/* Copyright (C) 2014-2019 de4dot@gmail.com This file is part of dnSpy dnSpy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. dnSpy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with dnSpy. If not, see . */ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using dnSpy.Contracts.Debugger.Code; namespace dnSpy.Contracts.Debugger.Breakpoints.Code { /// /// Code breakpoints service /// public abstract class DbgCodeBreakpointsService { /// /// Modifies a breakpoint /// /// Breakpoint /// New settings public void Modify(DbgCodeBreakpoint breakpoint, DbgCodeBreakpointSettings settings) => Modify(new[] { new DbgCodeBreakpointAndSettings(breakpoint, settings) }); /// /// Modifies breakpoints /// /// New settings public abstract void Modify(DbgCodeBreakpointAndSettings[] settings); /// /// Raised when breakpoints are modified /// public abstract event EventHandler? BreakpointsModified; /// /// Gets all breakpoints /// public abstract DbgCodeBreakpoint[] Breakpoints { get; } /// /// Gets all visible breakpoints /// public IEnumerable VisibleBreakpoints => Breakpoints.Where(a => !a.IsHidden); /// /// Raised when is changed /// public abstract event EventHandler>? BreakpointsChanged; /// /// Adds a breakpoint. If the breakpoint already exists, null is returned. /// /// Breakpoint info /// public DbgCodeBreakpoint? Add(DbgCodeBreakpointInfo breakpoint) => Add(new[] { breakpoint }).FirstOrDefault(); /// /// Adds breakpoints. Duplicate breakpoints are ignored. /// /// Breakpoints /// public abstract DbgCodeBreakpoint[] Add(DbgCodeBreakpointInfo[] breakpoints); /// /// Removes a breakpoint /// /// Breakpoint to remove public void Remove(DbgCodeBreakpoint breakpoint) => Remove(new[] { breakpoint ?? throw new ArgumentNullException(nameof(breakpoint)) }); /// /// Removes breakpoints /// /// Breakpoints to remove public abstract void Remove(DbgCodeBreakpoint[] breakpoints); /// /// Returns an existing breakpoint at or null if none exists /// /// Location /// public abstract DbgCodeBreakpoint? TryGetBreakpoint(DbgCodeLocation location); /// /// Removes all visible breakpoints /// public abstract void Clear(); /// /// Raised when is changed /// public abstract event EventHandler? BoundBreakpointsMessageChanged; } /// /// changed event args /// public readonly struct DbgBoundBreakpointsMessageChangedEventArgs { /// /// Gets all breakpoints /// public ReadOnlyCollection Breakpoints { get; } /// /// Constructor /// /// Breakpoints public DbgBoundBreakpointsMessageChangedEventArgs(ReadOnlyCollection breakpoints) => Breakpoints = breakpoints ?? throw new ArgumentNullException(nameof(breakpoints)); } /// /// Breakpoint and old settings /// public readonly struct DbgCodeBreakpointAndOldSettings { /// /// Gets the breakpoint /// public DbgCodeBreakpoint Breakpoint { get; } /// /// Gets the old settings /// public DbgCodeBreakpointSettings OldSettings { get; } /// /// Constructor /// /// Breakpoint /// Old settings public DbgCodeBreakpointAndOldSettings(DbgCodeBreakpoint breakpoint, DbgCodeBreakpointSettings oldSettings) { Breakpoint = breakpoint ?? throw new ArgumentNullException(nameof(breakpoint)); OldSettings = oldSettings; } } /// /// Breakpoints modified event args /// public readonly struct DbgBreakpointsModifiedEventArgs { /// /// Gets the breakpoints /// public ReadOnlyCollection Breakpoints { get; } /// /// Constructor /// /// Breakpoints and old settings public DbgBreakpointsModifiedEventArgs(ReadOnlyCollection breakpoints) => Breakpoints = breakpoints ?? throw new ArgumentNullException(nameof(breakpoints)); } /// /// Breakpoint and settings /// public readonly struct DbgCodeBreakpointAndSettings { /// /// Gets the breakpoint /// public DbgCodeBreakpoint Breakpoint { get; } /// /// Gets the new settings /// public DbgCodeBreakpointSettings Settings { get; } /// /// Constructor /// /// Breakpoint /// New settings public DbgCodeBreakpointAndSettings(DbgCodeBreakpoint breakpoint, DbgCodeBreakpointSettings settings) { Breakpoint = breakpoint ?? throw new ArgumentNullException(nameof(breakpoint)); Settings = settings; } } /// /// Info needed to add a breakpoint /// public readonly struct DbgCodeBreakpointInfo { /// /// Breakpoint location /// public DbgCodeLocation Location { get; } /// /// Breakpoint settings /// public DbgCodeBreakpointSettings Settings { get; } /// /// Breakpoint options /// public DbgCodeBreakpointOptions Options { get; } /// /// Constructor /// /// Breakpoint location. If you don't own this location instance, you must call /// Breakpoint settings public DbgCodeBreakpointInfo(DbgCodeLocation location, DbgCodeBreakpointSettings settings) { Location = location ?? throw new ArgumentNullException(nameof(location)); Settings = settings; Options = DbgCodeBreakpointOptions.None; } /// /// Constructor /// /// Breakpoint location. If you don't own this location instance, you must call /// Breakpoint settings /// Breakpoint options public DbgCodeBreakpointInfo(DbgCodeLocation location, DbgCodeBreakpointSettings settings, DbgCodeBreakpointOptions options) { Location = location ?? throw new ArgumentNullException(nameof(location)); Settings = settings; Options = options; } } /// /// Export an instance to get created when gets created /// public interface IDbgCodeBreakpointsServiceListener { /// /// Called once by /// /// Breakpoints service void Initialize(DbgCodeBreakpointsService dbgCodeBreakpointsService); } }