diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-11-14 09:41:47 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-11-14 09:41:47 (GMT) |
commit | 8c84c3550ad13ec19b6340bd8e9633aee91156af (patch) | |
tree | c4b2e1d57e7e1598810288048104d8f8186d9550 /src | |
parent | 7a1dc775d5d8edcf9193ca4ad7154af5eab18f1c (diff) | |
download | uscxml-8c84c3550ad13ec19b6340bd8e9633aee91156af.zip uscxml-8c84c3550ad13ec19b6340bd8e9633aee91156af.tar.gz uscxml-8c84c3550ad13ec19b6340bd8e9633aee91156af.tar.bz2 |
Datamode Extensions for V8
Diffstat (limited to 'src')
-rw-r--r-- | src/uscxml/Factory.cpp | 4 | ||||
-rw-r--r-- | src/uscxml/plugins/DataModel.h | 3 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp | 2 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp | 63 | ||||
-rw-r--r-- | src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.h | 4 |
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 |