summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-11-14 09:41:47 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-11-14 09:41:47 (GMT)
commit8c84c3550ad13ec19b6340bd8e9633aee91156af (patch)
treec4b2e1d57e7e1598810288048104d8f8186d9550 /src
parent7a1dc775d5d8edcf9193ca4ad7154af5eab18f1c (diff)
downloaduscxml-8c84c3550ad13ec19b6340bd8e9633aee91156af.zip
uscxml-8c84c3550ad13ec19b6340bd8e9633aee91156af.tar.gz
uscxml-8c84c3550ad13ec19b6340bd8e9633aee91156af.tar.bz2
Datamode Extensions for V8
Diffstat (limited to 'src')
-rw-r--r--src/uscxml/Factory.cpp4
-rw-r--r--src/uscxml/plugins/DataModel.h3
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp2
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp63
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h4
5 files changed, 73 insertions, 3 deletions
diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp
index 0333b85..968aabd 100644
--- a/src/uscxml/Factory.cpp
+++ b/src/uscxml/Factory.cpp
@@ -652,6 +652,10 @@ boost::shared_ptr<ExecutableContentImpl> Factory::createExecutableContent(const
}
+void DataModelImpl::addExtension(DataModelExtension* ext) {
+ ERROR_EXECUTION_THROW("DataModel does not support extensions");
+}
+
size_t DataModelImpl::replaceExpressions(std::string& content) {
std::stringstream ss;
size_t replacements = 0;
diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h
index a210ea1..05f89d5 100644
--- a/src/uscxml/plugins/DataModel.h
+++ b/src/uscxml/plugins/DataModel.h
@@ -97,8 +97,7 @@ public:
_interpreter = interpreter;
}
- virtual void addExtension(DataModelExtension* ext) {}
-
+ virtual void addExtension(DataModelExtension* ext);
virtual std::string andExpressions(std::list<std::string>) {
return "";
}
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
index bb77944..3c0b84b 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp
@@ -112,7 +112,7 @@ void JSCDataModel::addExtension(DataModelExtension* ext) {
currScope = JSValueToObject(_ctx, newScope, NULL);
} else {
JSStringRelease(pathCompJS);
- throw "adsf";
+ throw "Cannot add datamodel extension in non-object";
}
} else {
// this is the function!
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index 153e2c0..5f18414 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -90,6 +90,69 @@ V8DataModel::~V8DataModel() {
delete _dom;
}
+void V8DataModel::addExtension(DataModelExtension* ext) {
+ if (_extensions.find(ext) != _extensions.end())
+ return;
+
+ ext->dm = this;
+ _extensions.insert(ext);
+
+ v8::Locker locker;
+ v8::HandleScope scope;
+ v8::Context::Scope contextScope(_contexts.front());
+ v8::Handle<v8::Object> currScope = _contexts.front()->Global();
+
+ std::list<std::string> locPath = InterpreterImpl::tokenize(ext->provides(), '.');
+ std::list<std::string>::iterator locIter = locPath.begin();
+ while(true) {
+ std::string pathComp = *locIter;
+ v8::Local<v8::String> pathCompJS = v8::String::New(locIter->c_str());
+
+ if (++locIter != locPath.end()) {
+ // just another intermediate step
+ if (!currScope->Has(pathCompJS)) {
+ currScope->Set(pathCompJS, v8::Object::New());
+ }
+
+ v8::Local<v8::Value> newScope = currScope->Get(pathCompJS);
+ if (newScope->IsObject()) {
+ currScope = newScope->ToObject();
+ } else {
+ throw "Cannot add datamodel extension in non-object";
+ }
+ } else {
+ // this is the function!
+ currScope->Set(pathCompJS, v8::FunctionTemplate::New(jsExtension, v8::External::New(reinterpret_cast<void*>(ext)))->GetFunction(), v8::ReadOnly);
+ break;
+ }
+ }
+}
+
+v8::Handle<v8::Value> V8DataModel::jsExtension(const v8::Arguments& args) {
+ DataModelExtension* extension = static_cast<DataModelExtension*>(v8::External::Unwrap(args.Data()));
+
+ v8::Local<v8::String> memberJS;
+ std::string memberName;
+
+ if (args.Length() > 0 && args[0]->IsString()) {
+ memberJS = args[0]->ToString();
+ memberName = *v8::String::AsciiValue(memberJS);
+ }
+
+ if (args.Length() > 1) {
+ // setter
+ Data data = ((V8DataModel*)(extension->dm))->getValueAsData(args[1]);
+ extension->setValueOf(memberName, data);
+ return v8::Undefined();
+ }
+
+ if (args.Length() == 1) {
+ // getter
+ return ((V8DataModel*)(extension->dm))->getDataAsValue(extension->getValueOf(memberName));
+ }
+ return v8::Undefined();
+}
+
boost::shared_ptr<DataModelImpl> V8DataModel::create(InterpreterImpl* interpreter) {
boost::shared_ptr<V8DataModel> dm = boost::shared_ptr<V8DataModel>(new V8DataModel());
dm->_interpreter = interpreter;
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
index b114550..9e2ec71 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h
@@ -96,6 +96,9 @@ public:
virtual bool evalAsBool(const std::string& expr);
virtual double evalAsNumber(const std::string& expr);
+ virtual void addExtension(DataModelExtension* ext);
+
+ static v8::Handle<v8::Value> jsExtension(const v8::Arguments& args);
static v8::Handle<v8::Value> jsIn(const v8::Arguments& args);
static v8::Handle<v8::Value> jsPrint(const v8::Arguments& args);
@@ -118,6 +121,7 @@ protected:
v8::Handle<v8::Value> getNodeAsValue(const Arabica::DOM::Node<std::string>& node);
void throwExceptionEvent(const v8::TryCatch& tryCatch);
+ std::set<DataModelExtension*> _extensions;
};
#ifdef BUILD_AS_PLUGINS