aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/base/scriptables/debuggable
diff options
context:
space:
mode:
Diffstat (limited to 'engines/wintermute/base/scriptables/debuggable')
-rw-r--r--engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp42
-rw-r--r--engines/wintermute/base/scriptables/debuggable/debuggable_script.h5
-rw-r--r--engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp1
-rw-r--r--engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h62
4 files changed, 103 insertions, 7 deletions
diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp
index 1aa318bdbf..73ecd3fc89 100644
--- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp
+++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp
@@ -22,18 +22,28 @@
#include "common/tokenizer.h"
#include "debuggable_script.h"
-#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/scriptables/script_value.h"
+#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h"
#include "engines/wintermute/debugger/breakpoint.h"
#include "engines/wintermute/debugger/script_monitor.h"
+#include "engines/wintermute/debugger/watch_instance.h"
namespace Wintermute {
-DebuggableScript::DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine) : ScScript(inGame, engine), _engine(engine), _stepDepth(kDefaultStepDepth) {}
-
-DebuggableScript::~DebuggableScript() {}
+DebuggableScript::DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine) : ScScript(inGame, engine), _engine(engine), _stepDepth(kDefaultStepDepth) {
+ _engine->_watches.subscribe(this);
+ for (uint i = 0; i < _engine->_watches.size(); i++) {
+ _watchInstances.push_back(new WatchInstance(_engine->_watches[i], this));
+ }
+}
+DebuggableScript::~DebuggableScript() {
+ for (uint i = 0; i < _watchInstances.size(); i++) {
+ delete _watchInstances[i];
+ }
+ _engine->_watches.unsubscribe(this);
+}
void DebuggableScript::preInstHook(uint32 inst) {}
void DebuggableScript::postInstHook(uint32 inst) {
@@ -46,6 +56,11 @@ void DebuggableScript::postInstHook(uint32 inst) {
_engine->_monitor->notifyStep(this);
}
}
+
+ for (uint i = 0; i < _watchInstances.size(); i++) {
+ this->_watchInstances[i]->evaluate();
+ }
+
}
void DebuggableScript::setStepDepth(int depth) {
@@ -110,5 +125,24 @@ Common::String DebuggableScript::dbgGetFilename() const {
return _filename;
}
+void DebuggableScript::updateWatches() {
+ // We drop obsolete watches
+ for (uint i = 0; i < _watchInstances.size(); i++) {
+ Watch *findMe = _watchInstances[i]->_watch;
+ if (Common::find(_engine->_watches.begin(), _engine->_watches.end(), findMe) == _engine->_watches.end()) {
+ // Not found on engine-wide list, must have been removed from watches. Must remove it from local list.
+ _watchInstances.remove_at(i);
+ }
+ }
+
+ // We add any new watches
+ for (uint i = 0; i < _engine->_watches.size(); i++) {
+ Watch *findMe = _engine->_watches[i];
+ if (Common::find(_engine->_watches.begin(), _engine->_watches.end(), findMe) == _engine->_watches.end()) {
+ // Not found on local list, must be a new one.
+ _watchInstances.push_back(new WatchInstance(_engine->_watches[i], this));
+ }
+ }
+}
} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h
index c5c0896f11..b32a5ca4af 100644
--- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.h
+++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h
@@ -22,17 +22,19 @@
#ifndef DEBUGGABLE_SCRIPT_H_
#define DEBUGGABLE_SCRIPT_H_
-
#include "engines/wintermute/base/scriptables/script.h"
namespace Wintermute {
class ScriptMonitor;
+class Watch;
+class WatchInstance;
class DebuggableScEngine;
class DebuggableScript : public ScScript {
static const int kDefaultStepDepth = -2;
int32 _stepDepth;
DebuggableScEngine *_engine;
+ BaseArray<WatchInstance *> _watchInstances;
virtual void preInstHook(uint32 inst) override;
virtual void postInstHook(uint32 inst) override;
void setStepDepth(int depth);
@@ -57,6 +59,7 @@ public:
* Continue execution until the activation record on top of the stack is popped
*/
void stepFinish();
+ void updateWatches();
};
} // End of namespace Wintermute
diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp
index f1f1bf776e..28a00cd4ae 100644
--- a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp
+++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp
@@ -22,6 +22,7 @@
#include "debuggable_script_engine.h"
#include "debuggable_script.h"
+#include "engines/wintermute/debugger/watch_instance.h"
namespace Wintermute {
diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h
index 8469ecdc25..a4d9d2bfe7 100644
--- a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h
+++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h
@@ -22,21 +22,78 @@
#ifndef DEBUGGABLE_SCRIPT_ENGINE_H_
#define DEBUGGABLE_SCRIPT_ENGINE_H_
-
-#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h"
#include "engines/wintermute/base/scriptables/script_engine.h"
#include "engines/wintermute/coll_templ.h"
#include "common/algorithm.h"
+#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h"
namespace Wintermute {
class Breakpoint;
+class Watch;
class DebuggableScript;
class DebuggableScEngine;
class ScriptMonitor;
+class PublisherWArray : private Common::Array<Watch *> {
+ Common::Array<DebuggableScript *> _subscribers;
+ void notifySubscribers() {
+ for (uint i = 0; i < _subscribers.size(); i++) {
+ _subscribers[i]->updateWatches();
+ }
+ }
+public:
+ void subscribe(DebuggableScript *script) {
+ if (Common::find(_subscribers.begin(), _subscribers.end(), script) == _subscribers.end()) {
+ // If not already contained
+ _subscribers.push_back(script);
+ }
+ }
+
+ void unsubscribe(DebuggableScript *script) {
+ int location = -1;
+ for (uint i = 0; i < _subscribers.size() && location == -1; i++) {
+ if (_subscribers[i] == script) {
+ location = i;
+ }
+ }
+ if (location >= 0) {
+ _subscribers.remove_at(location);
+ } else {
+ // TODO: If this happens... it's funny. Some script out there forgot to subscribe.
+ }
+ }
+
+ void push_back(Watch *newElement) {
+ Common::Array<Watch *>::push_back(newElement);
+ notifySubscribers();
+ }
+
+ size_type size() {
+ return Common::Array<Watch *>::size();
+ }
+
+ iterator begin() {
+ return Common::Array<Watch *>::begin();
+ }
+
+ iterator end() {
+ return Common::Array<Watch *>::end();
+ }
+
+ Watch *&operator[](size_type idx) {
+ return Common::Array<Watch *>::operator[](idx);
+ }
+ Watch *remove_at(size_type idx) {
+ Watch *res = Common::Array<Watch *>::remove_at(idx);
+ notifySubscribers();
+ return res;
+ }
+};
+
class DebuggableScEngine : public ScEngine {
Common::Array<Breakpoint *> _breakpoints;
+ PublisherWArray _watches;
ScriptMonitor *_monitor;
public:
DebuggableScEngine(BaseGame *inGame);
@@ -45,6 +102,7 @@ public:
friend class DebuggerController;
friend class DebuggableScript;
friend class ScScript;
+ friend class WatchableScriptArray;
};
} // End of namespace Wintermute