using BizHawk.Emulation.Common; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace BizHawk.Client.EmuHawk { public class BreakpointList : List { public Action Callback { get; set; } public void Add(IDebuggable core, uint address, MemoryCallbackType type) { Add(new Breakpoint(core, Callback, address, type)); } public new void Clear() { foreach (var breakpoint in this) { breakpoint.ReadOnly = false; breakpoint.Active = false; } base.Clear(); } public new bool Remove(Breakpoint b) { var breakpoint = Find(x => x == b); if (breakpoint != null) { breakpoint.ReadOnly = false; breakpoint.Active = false; } return base.Remove(b); } public new void RemoveAt(int index) { if (index < Count) { var breakpoint = this[index]; breakpoint.ReadOnly = false; breakpoint.Active = false; base.RemoveAt(index); } } public new int RemoveAll(Predicate match) { var removeCount = 0; foreach (var breakpoint in this) { if (match(breakpoint)) { Remove(breakpoint); removeCount++; } } return removeCount; } } public class Breakpoint { private bool _active; private readonly IDebuggable _core; public Breakpoint(bool readOnly, IDebuggable core, Action callBack, uint address, MemoryCallbackType type, bool enabled = true) { _core = core; Type = type; Callback = callBack; Address = address; Name = "Pause"; Active = enabled; ReadOnly = readOnly; } public Breakpoint(IDebuggable core, Action callBack, uint address, MemoryCallbackType type, bool enabled = true) { _core = core; Type = type; Callback = callBack; Address = address; Name = "Pause"; Active = enabled; } public Breakpoint(string name, bool readOnly, IDebuggable core, Action callBack, uint address, MemoryCallbackType type, bool enabled = true) { _core = core; Type = type; Callback = callBack; Address = address; Name = name; Active = enabled; ReadOnly = readOnly; } public Action Callback { get; set; } public uint? Address { get; set; } public MemoryCallbackType Type { get; set; } public string Name { get; set; } internal bool ReadOnly { get; set; } // Adds an existing callback public Breakpoint(IDebuggable core, IMemoryCallback callback) { _core = core; _active = true; Callback = callback.Callback; Address = callback.Address; Type = callback.Type; Name = callback.Name; // We don't know where this callback came from so don't let the user mess with it // Most likely it came from lua and doing so could cause some bad things to happen ReadOnly = true; } public bool Active { get { return _active; } set { if (!ReadOnly) { if (!value) { RemoveCallback(); } if (!_active && value) // If inactive and changing to active { AddCallback(); } _active = value; } } } private void AddCallback() { _core.MemoryCallbacks.Add(new MemoryCallback(Type, Name, Callback, Address)); } private void RemoveCallback() { _core.MemoryCallbacks.Remove(Callback); } public void ResetCallback() { if (Active) { RemoveCallback(); AddCallback(); } } } }