aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/debugger
diff options
context:
space:
mode:
authorTobia Tesan2016-02-29 15:39:42 +0100
committerTobia Tesan2016-03-01 20:40:46 +0100
commita120aa855990f045d38d3b603306490305a48a39 (patch)
treec29f829e36ea762de60f683b23dbefd725717d16 /engines/wintermute/debugger
parentd5d25b0e89faebe4b1c5961d7b1ab872339e4a03 (diff)
downloadscummvm-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.cpp60
-rw-r--r--engines/wintermute/debugger/debugger_controller.h13
-rw-r--r--engines/wintermute/debugger/script_monitor.h3
-rw-r--r--engines/wintermute/debugger/watch.cpp42
-rw-r--r--engines/wintermute/debugger/watch.h51
-rw-r--r--engines/wintermute/debugger/watch_instance.cpp53
-rw-r--r--engines/wintermute/debugger/watch_instance.h44
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_ */