#pragma once #include "stdafx.h" #include #include "../Utilities/SimpleLock.h" #include "DebuggerTypes.h" class Debugger; enum class CallbackType { CpuRead = 0, CpuWrite = 1, CpuExec = 2, PpuRead = 3, PpuWrite = 4 }; class ScriptingContext { private: //Must be static to be thread-safe when switching game //UI updates all script windows in a single thread, so this is safe static string _log; std::deque _logRows; SimpleLock _logLock; bool _inStartFrameEvent = false; bool _inExecOpEvent = false; Debugger* _debugger = nullptr; std::unordered_map _saveSlotData; int32_t _saveSlot = -1; int32_t _loadSlot = -1; bool _stateLoaded = false; protected: string _scriptName; bool _initDone = false; vector _callbacks[5][0x10000]; vector _eventCallbacks[(int)EventType::EventTypeSize]; virtual void InternalCallMemoryCallback(uint16_t addr, uint8_t &value, CallbackType type) = 0; virtual int InternalCallEventCallback(EventType type) = 0; public: ScriptingContext(Debugger* debugger); virtual ~ScriptingContext() {} virtual bool LoadScript(string scriptName, string scriptContent, Debugger* debugger) = 0; void Log(string message); const char* GetLog(); Debugger* GetDebugger(); string GetScriptName(); void RequestSaveState(int slot); bool RequestLoadState(int slot); void SaveState(); bool LoadState(); bool LoadState(string stateData); string GetSavestateData(int slot); void ClearSavestateData(int slot); bool ProcessSavestate(); void CallMemoryCallback(uint16_t addr, uint8_t &value, CallbackType type); int CallEventCallback(EventType type); bool CheckInitDone(); bool CheckInStartFrameEvent(); bool CheckInExecOpEvent(); bool CheckStateLoadedFlag(); void RegisterMemoryCallback(CallbackType type, int startAddr, int endAddr, int reference); virtual void UnregisterMemoryCallback(CallbackType type, int startAddr, int endAddr, int reference); void RegisterEventCallback(EventType type, int reference); virtual void UnregisterEventCallback(EventType type, int reference); };