diff options
| author | Tobia Tesan | 2016-02-29 15:39:42 +0100 |
|---|---|---|
| committer | Tobia Tesan | 2016-03-01 20:40:46 +0100 |
| commit | a120aa855990f045d38d3b603306490305a48a39 (patch) | |
| tree | c29f829e36ea762de60f683b23dbefd725717d16 /engines/wintermute/debugger | |
| parent | d5d25b0e89faebe4b1c5961d7b1ab872339e4a03 (diff) | |
| download | scummvm-rg350-a120aa855990f045d38d3b603306490305a48a39.tar.gz scummvm-rg350-a120aa855990f045d38d3b603306490305a48a39.tar.bz2 scummvm-rg350-a120aa855990f045d38d3b603306490305a48a39.zip | |
WINTERMUTE: Add Watch functionality
Diffstat (limited to 'engines/wintermute/debugger')
| -rw-r--r-- | engines/wintermute/debugger/debugger_controller.cpp | 60 | ||||
| -rw-r--r-- | engines/wintermute/debugger/debugger_controller.h | 13 | ||||
| -rw-r--r-- | engines/wintermute/debugger/script_monitor.h | 3 | ||||
| -rw-r--r-- | engines/wintermute/debugger/watch.cpp | 42 | ||||
| -rw-r--r-- | engines/wintermute/debugger/watch.h | 51 | ||||
| -rw-r--r-- | engines/wintermute/debugger/watch_instance.cpp | 53 | ||||
| -rw-r--r-- | engines/wintermute/debugger/watch_instance.h | 44 |
7 files changed, 266 insertions, 0 deletions
diff --git a/engines/wintermute/debugger/debugger_controller.cpp b/engines/wintermute/debugger/debugger_controller.cpp index 6fe49f2af2..2e021530f8 100644 --- a/engines/wintermute/debugger/debugger_controller.cpp +++ b/engines/wintermute/debugger/debugger_controller.cpp @@ -32,6 +32,7 @@ #include "engines/wintermute/base/scriptables/script_stack.h" #include "engines/wintermute/debugger/breakpoint.h" #include "engines/wintermute/debugger/debugger_controller.h" +#include "engines/wintermute/debugger/watch.h" #include "engines/wintermute/debugger/listing_providers/blank_listing_provider.h" #include "engines/wintermute/debugger/listing_providers/cached_source_listing_provider.h" #include "engines/wintermute/debugger/listing_providers/source_listing.h" @@ -99,6 +100,47 @@ Error DebuggerController::enableBreakpoint(uint id) { } } +Error DebuggerController::removeWatchpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_watches.size() > id) { + SCENGINE->_watches.remove_at(id); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + + +Error DebuggerController::disableWatchpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_watches.size() > id) { + SCENGINE->_watches[id]->disable(); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + +Error DebuggerController::enableWatchpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_watches.size() > id) { + SCENGINE->_watches[id]->enable(); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } + +} + +Error DebuggerController::addWatch(const char *filename, const char *symbol) { + assert(SCENGINE); + if (!bytecodeExists(filename)) { + return Error(ERROR, NO_SUCH_BYTECODE, filename); + } + SCENGINE->_watches.push_back(new Watch(filename, symbol, this)); + return Error(SUCCESS, OK, "Watchpoint added"); +} + void DebuggerController::onBreakpoint(const Breakpoint *breakpoint, DebuggableScript *script) { _lastScript = script; _lastLine = script->_currentLine; @@ -111,6 +153,13 @@ void DebuggerController::notifyStep(DebuggableScript *script) override { DEBUGGER->notifyStep(script->dbgGetFilename().c_str(), script->_currentLine); } +void DebuggerController::onWatch(const Watch *watch, DebuggableScript *script) { + _lastScript = script; // If script has changed do we still care? + _lastLine = script->_currentLine; + Common::String symbol = watch->getSymbol(); + DEBUGGER->notifyWatch(script->dbgGetFilename().c_str(), symbol.c_str(), script->resolveName(symbol)->getString()); +} + Error DebuggerController::step() { if (!_lastScript) { return Error(ERROR, NOT_ALLOWED); @@ -225,6 +274,17 @@ Common::Array<BreakpointInfo> DebuggerController::getBreakpoints() const { return breakpoints; } +Common::Array<WatchInfo> DebuggerController::getWatchlist() const { + Common::Array<WatchInfo> watchlist; + for (uint i = 0; i < SCENGINE->_watches.size(); i++) { + WatchInfo watchInfo; + watchInfo._filename = SCENGINE->_watches[i]->getFilename(); + watchInfo._symbol = SCENGINE->_watches[i]->getSymbol(); + watchlist.push_back(watchInfo); + } + return watchlist; +} + uint32 DebuggerController::getLastLine() const { return _lastLine; } diff --git a/engines/wintermute/debugger/debugger_controller.h b/engines/wintermute/debugger/debugger_controller.h index 87b4945f27..8c720281db 100644 --- a/engines/wintermute/debugger/debugger_controller.h +++ b/engines/wintermute/debugger/debugger_controller.h @@ -43,6 +43,13 @@ struct BreakpointInfo { bool _enabled; }; +struct WatchInfo { + Common::String _filename; + Common::String _symbol; + int _hits; + bool _enabled; +}; + struct TopEntry { bool current; Common::String filename; @@ -70,7 +77,12 @@ public: Error removeBreakpoint(uint id); Error disableBreakpoint(uint id); Error enableBreakpoint(uint id); + Error addWatch(const char *filename, const char *symbol); + Error removeWatchpoint(uint id); + Error disableWatchpoint(uint id); + Error enableWatchpoint(uint id); Common::Array<BreakpointInfo> getBreakpoints() const; + Common::Array<WatchInfo> getWatchlist() const; /** * @brief step one instruction */ @@ -99,6 +111,7 @@ public: * Inherited from ScriptMonitor */ void onBreakpoint(const Breakpoint *breakpoint, DebuggableScript *script); + void onWatch(const Watch *watch, DebuggableScript *script); void notifyStep(DebuggableScript *script); }; } diff --git a/engines/wintermute/debugger/script_monitor.h b/engines/wintermute/debugger/script_monitor.h index 5f3327692b..e9559e2ade 100644 --- a/engines/wintermute/debugger/script_monitor.h +++ b/engines/wintermute/debugger/script_monitor.h @@ -27,12 +27,15 @@ namespace Wintermute { class DebuggableScript; class Breakpoint; +class Watch; class ScriptMonitor { public: + virtual ~ScriptMonitor() {}; virtual void notifyStep(DebuggableScript* script) = 0; virtual void onBreakpoint(const Breakpoint* breakpoint, DebuggableScript* script) = 0; + virtual void onWatch(const Watch* watch, DebuggableScript* script) = 0; }; } // End of namespace Wintermute diff --git a/engines/wintermute/debugger/watch.cpp b/engines/wintermute/debugger/watch.cpp new file mode 100644 index 0000000000..410756fdc8 --- /dev/null +++ b/engines/wintermute/debugger/watch.cpp @@ -0,0 +1,42 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program 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 2 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "watch.h" +#include "watch_instance.h" +#include "script_monitor.h" + +namespace Wintermute { + +Watch::Watch(const Common::String &filename, const Common::String &symbol, ScriptMonitor* monitor) : _enabled(false), _filename(filename), _symbol(symbol), _monitor(monitor) {} + +Watch::~Watch() { /* Nothing to take care of in here */ } + +void Watch::trigger(WatchInstance* instance) { + _monitor->onWatch(this, instance->_script); +} + +Common::String Watch::getFilename() const { return _filename; } +Common::String Watch::getSymbol() const { return _symbol; } +bool Watch::isEnabled() const { return _enabled; } +void Watch::enable() { _enabled = true; } +void Watch::disable() { _enabled = false; } +} diff --git a/engines/wintermute/debugger/watch.h b/engines/wintermute/debugger/watch.h new file mode 100644 index 0000000000..cbffe43b41 --- /dev/null +++ b/engines/wintermute/debugger/watch.h @@ -0,0 +1,51 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program 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 2 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef WATCH_H_ +#define WATCH_H_ + +#include "common/str.h" + +namespace Wintermute { + +class ScValue; +class ScScript; +class WatchInstance; +class ScriptMonitor; + +class Watch { + const Common::String _filename; + const Common::String _symbol; + int _enabled; + ScriptMonitor *_monitor; +public: + Watch(const Common::String &filename, const Common::String &symbol, ScriptMonitor*); + Common::String getFilename() const; + Common::String getSymbol() const; + bool isEnabled() const; + void enable(); + void disable(); + void trigger(WatchInstance*); + virtual ~Watch(); +}; +} +#endif /* WATCH_H_ */ diff --git a/engines/wintermute/debugger/watch_instance.cpp b/engines/wintermute/debugger/watch_instance.cpp new file mode 100644 index 0000000000..2d31221ad4 --- /dev/null +++ b/engines/wintermute/debugger/watch_instance.cpp @@ -0,0 +1,53 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program 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 2 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "watch_instance.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" +#include "engines/wintermute/debugger/watch.h" + +namespace Wintermute { + +WatchInstance::WatchInstance(Watch* watch, DebuggableScript* script) : _watch(watch), _script(script), _lastValue(nullptr) {} +WatchInstance::~WatchInstance() { delete _lastValue; } + +void WatchInstance::evaluate() { + if (_watch->isEnabled()) { + if (!_watch->getFilename().compareTo(_script->_filename)) { + + if(_lastValue == nullptr) { + _lastValue = new ScValue(_script->_gameRef); + // ^^ This here is NULL by default + } + ScValue* currentValue = _script->resolveName(_watch->getSymbol()); + if(ScValue::compare( + currentValue, + _lastValue + )) { + _lastValue->copy(currentValue); + _watch->trigger(this); + } + delete currentValue; + } + } +} +} // End of namespace Wintermute diff --git a/engines/wintermute/debugger/watch_instance.h b/engines/wintermute/debugger/watch_instance.h new file mode 100644 index 0000000000..84fb62968d --- /dev/null +++ b/engines/wintermute/debugger/watch_instance.h @@ -0,0 +1,44 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program 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 2 + * of the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef WATCH_INSTANCE_H_ +#define WATCH_INSTANCE_H_ + +namespace Wintermute { +class Watch; +class ScValue; +class DebuggableScript; + +class WatchInstance { + Watch* _watch; + ScValue *_lastValue; + DebuggableScript* _script; +public: + WatchInstance (Watch* watch, DebuggableScript* script); + ~WatchInstance(); + void evaluate(); +friend class DebuggableScript; +friend class Watch; +}; +} // End of namespace Wintermute + +#endif /* WATCH_INSTANCE_H_ */ |
