diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-07-26 19:05:33 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2013-07-26 19:05:33 (GMT) |
commit | 720bbe5c1b8c0789b5c7ad9ffca33e52bf77f1da (patch) | |
tree | 8f692eb636ddb21649097e053f8504a2dab70a01 /src/uscxml/plugins | |
parent | 8ff01ac995c8b95fa2695b6ff7e3e985bd4579d6 (diff) | |
download | uscxml-720bbe5c1b8c0789b5c7ad9ffca33e52bf77f1da.zip uscxml-720bbe5c1b8c0789b5c7ad9ffca33e52bf77f1da.tar.gz uscxml-720bbe5c1b8c0789b5c7ad9ffca33e52bf77f1da.tar.bz2 |
Started calendar invoker and bug fixes
Diffstat (limited to 'src/uscxml/plugins')
7 files changed, 248 insertions, 24 deletions
diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 2143f5f..1326fb9 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -57,6 +57,7 @@ JSClassDefinition JSCDataModel::jsInClassDef = { 0, 0, "In", 0, 0, 0, 0, 0, 0, 0 JSClassDefinition JSCDataModel::jsPrintClassDef = { 0, 0, "print", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, jsPrint, 0, 0, 0 }; JSClassDefinition JSCDataModel::jsIOProcessorsClassDef = { 0, 0, "ioProcessors", 0, 0, 0, 0, 0, jsIOProcessorHasProp, jsIOProcessorGetProp, 0, 0, jsIOProcessorListProps, 0, 0, 0, 0 }; +JSClassDefinition JSCDataModel::jsInvokersClassDef = { 0, 0, "invokers", 0, 0, 0, 0, 0, jsInvokerHasProp, jsInvokerGetProp, 0, 0, jsInvokerListProps, 0, 0, 0, 0 }; boost::shared_ptr<DataModelImpl> JSCDataModel::create(InterpreterImpl* interpreter) { boost::shared_ptr<JSCDataModel> dm = boost::shared_ptr<JSCDataModel>(new JSCDataModel()); @@ -81,6 +82,12 @@ boost::shared_ptr<DataModelImpl> JSCDataModel::create(InterpreterImpl* interpret JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), printName, jsPrint, kJSPropertyAttributeNone, NULL); JSStringRelease(inName); + JSClassRef jsInvokerClassRef = JSClassCreate(&jsInvokersClassDef); + JSObjectRef jsInvoker = JSObjectMake(dm->_ctx, jsInvokerClassRef, dm.get()); + JSStringRef invokerName = JSStringCreateWithUTF8CString("_invokers"); + JSObjectSetProperty(dm->_ctx, JSContextGetGlobalObject(dm->_ctx), invokerName, jsInvoker, kJSPropertyAttributeNone, NULL); + JSStringRelease(invokerName); + JSClassRef jsIOProcClassRef = JSClassCreate(&jsIOProcessorsClassDef); JSObjectRef jsIOProc = JSObjectMake(dm->_ctx, jsIOProcClassRef, dm.get()); JSStringRef ioProcName = JSStringCreateWithUTF8CString("_ioprocessors"); @@ -109,7 +116,6 @@ boost::shared_ptr<DataModelImpl> JSCDataModel::create(InterpreterImpl* interpret JSObjectSetProperty(dm->_ctx, globalObject, JSStringCreateWithUTF8CString("document"), documentObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, NULL); } - dm->eval(Element<std::string>(), "_invokers = {};"); dm->eval(Element<std::string>(), "_x = {};"); return dm; @@ -576,4 +582,44 @@ void JSCDataModel::jsIOProcessorListProps(JSContextRef ctx, JSObjectRef object, } } + +bool JSCDataModel::jsInvokerHasProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) { + JSCDataModel* INSTANCE = (JSCDataModel*)JSObjectGetPrivate(object); + std::map<std::string, Invoker> invokers = INSTANCE->_interpreter->getInvokers(); + + size_t maxSize = JSStringGetMaximumUTF8CStringSize(propertyName); + char buffer[maxSize]; + JSStringGetUTF8CString(propertyName, buffer, maxSize); + std::string prop(buffer); + + return invokers.find(prop) != invokers.end(); +} + +JSValueRef JSCDataModel::jsInvokerGetProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) { + JSCDataModel* INSTANCE = (JSCDataModel*)JSObjectGetPrivate(object); + std::map<std::string, Invoker> invokers = INSTANCE->_interpreter->getInvokers(); + + size_t maxSize = JSStringGetMaximumUTF8CStringSize(propertyName); + char buffer[maxSize]; + JSStringGetUTF8CString(propertyName, buffer, maxSize); + std::string prop(buffer); + + if (invokers.find(prop) != invokers.end()) { + return INSTANCE->getDataAsValue(invokers.find(prop)->second.getDataModelVariables()); + } + return JSValueMakeUndefined(ctx); +} + +void JSCDataModel::jsInvokerListProps(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) { + JSCDataModel* INSTANCE = (JSCDataModel*)JSObjectGetPrivate(object); + std::map<std::string, Invoker> invokers = INSTANCE->_interpreter->getInvokers(); + + std::map<std::string, Invoker>::const_iterator invokerIter = invokers.begin(); + while(invokerIter != invokers.end()) { + JSStringRef invokeName = JSStringCreateWithUTF8CString(invokerIter->first.c_str()); + JSPropertyNameAccumulatorAddName(propertyNames, invokeName); + invokerIter++; + } +} + }
\ No newline at end of file diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h index 9f254e4..9e70a8f 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h @@ -71,7 +71,12 @@ protected: static bool jsIOProcessorHasProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); static JSValueRef jsIOProcessorGetProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); static void jsIOProcessorListProps(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); - + + static JSClassDefinition jsInvokersClassDef; + static bool jsInvokerHasProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); + static JSValueRef jsInvokerGetProp(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception); + static void jsInvokerListProps(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames); + JSValueRef getDocumentAsValue(const Arabica::DOM::Document<std::string>& doc); JSValueRef getDataAsValue(const Data& data); Data getValueAsData(const JSValueRef value); diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp index 2f43c73..462b661 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -8,6 +8,21 @@ #include <Pluma/Connector.hpp> #endif +#define SET_PL_CONTEXT \ +_dmPtr = this; + +#define PL_MODULE \ +_interpreter.getSessionId().c_str() \ + +#define UNSET_PL_ENGINE(dm) \ +PL_set_engine(NULL, NULL); + +#define SET_PL_ENGINE(dm) \ +assert(_swiEngines.find(dm) != _swiEngines.end()); \ +int rc = PL_set_engine(_swiEngines[dm], NULL); \ +assert(rc == PL_ENGINE_SET); \ +_dmPtr = dm; + namespace uscxml { using namespace Arabica::XPath; @@ -21,43 +36,90 @@ bool connect(pluma::Host& host) { } #endif +// SWI prolog does not support passing user data +static SWIDataModel* _dmPtr; +static std::map<SWIDataModel*, PL_engine_t> _swiEngines; + SWIDataModel::SWIDataModel() { } -// SWI prolog does not support passing user data -static InterpreterImpl* _swiInterpreterPtr; - +SWIDataModel::~SWIDataModel() { + if (_swiEngines.find(this) != _swiEngines.end()) { + PL_destroy_engine(_swiEngines[this]); + _swiEngines.erase(this); + } +} + boost::shared_ptr<DataModelImpl> SWIDataModel::create(InterpreterImpl* interpreter) { boost::shared_ptr<SWIDataModel> dm = boost::shared_ptr<SWIDataModel>(new SWIDataModel()); dm->_interpreter = interpreter; - // this is most unfortunate! - _swiInterpreterPtr = interpreter; const char* swibin = getenv("SWI_BINARY"); if (swibin == NULL) swibin = SWI_BINARY; const char* quiet = "--quiet"; + int argc = 2; static char * av[] = { (char*)swibin, (char*)quiet, - // "-s", - // "/Users/sradomski/Documents/TK/Code/pl-devel/demo/likes.pl", NULL }; - if(!PL_initialise(2,av)) { - LOG(ERROR) << "Error intializing prolog engine"; - PL_halt(1); - return boost::shared_ptr<DataModelImpl>(); - } - // load SWI XML parser - PlCall("use_module", PlCompound("library", PlTerm("sgml"))); + PL_engine_t engine; - // load json parser - PlCall("use_module", PlCompound("library", PlTerm("http/json"))); - PlCall("use_module", PlCompound("library", PlTerm("http/json_convert"))); + if (!PL_is_initialised(NULL, NULL)) { + if(!PL_initialise(argc,av)) { + LOG(ERROR) << "Error intializing prolog engine"; + PL_halt(1); + return boost::shared_ptr<DataModelImpl>(); + } else { + LOG(WARNING) << "Instantiating more than one SWI prolog datamodel will lead to weird effects as I cannot seperate the environments"; + } + + PL_set_engine(PL_ENGINE_CURRENT, &engine); + + // load SWI XML parser + try { + PlCall("use_module", PlCompound("library", PlTerm("sgml"))); + } catch (PlException plex) { + + LOG(ERROR) << "Cannot load prolog sgml module - make sure you have it installed in your prolog runtime: " << (char*)plex; + throw plex; + } + + // load json parser + try { + PlCall("use_module", PlCompound("library", PlTerm("http/json"))); + PlCall("use_module", PlCompound("library", PlTerm("http/json_convert"))); + } catch (PlException plex) { + LOG(ERROR) << "Cannot load prolog json module or json_convert - make sure you have it installed in your prolog runtime: " << (char*)plex; + throw plex; + } + } else { + engine = PL_create_engine(NULL); + } + + assert(engine); + _swiEngines[dm.get()] = engine; + _dmPtr = dm.get(); + + int rc = PL_set_engine(engine, NULL); + assert(rc == PL_ENGINE_SET); + + _plModule = boost::replace_all_copy(interpreter->getSessionId(), "-", ""); + boost::replace_all(_plModule, "0", "g"); + boost::replace_all(_plModule, "1", "h"); + boost::replace_all(_plModule, "2", "i"); + boost::replace_all(_plModule, "3", "j"); + boost::replace_all(_plModule, "4", "k"); + boost::replace_all(_plModule, "5", "l"); + boost::replace_all(_plModule, "6", "m"); + boost::replace_all(_plModule, "7", "n"); + boost::replace_all(_plModule, "8", "o"); + boost::replace_all(_plModule, "9", "p"); + // use atoms for double quoted PlCall("set_prolog_flag(double_quotes,atom)."); @@ -89,7 +151,7 @@ boost::shared_ptr<DataModelImpl> SWIDataModel::create(InterpreterImpl* interpret foreign_t SWIDataModel::inPredicate(term_t a0, int arity, void* context) { char *s; if ( PL_get_atom_chars(a0, &s) ) { - NodeSet<std::string> config = _swiInterpreterPtr->getConfiguration(); + NodeSet<std::string> config = _dmPtr->_interpreter->getConfiguration(); for (int i = 0; i < config.size(); i++) { if (HAS_ATTR(config[i], "id") && strcmp(ATTR(config[i], "id").c_str(), s) == 0) { return TRUE; @@ -113,9 +175,6 @@ void SWIDataModel::setName(const std::string& name) { _name = name; } -SWIDataModel::~SWIDataModel() { -} - void SWIDataModel::pushContext() { // std::cout << "SWIDataModel::pushContext" << std::endl; } @@ -129,6 +188,7 @@ void SWIDataModel::initialize() { } void SWIDataModel::setEvent(const Event& event) { + SET_PL_CONTEXT; // remove old event try { PlCall("retractall(event(_))"); @@ -208,17 +268,20 @@ void SWIDataModel::setEvent(const Event& event) { } Data SWIDataModel::getStringAsData(const std::string& content) { + SET_PL_CONTEXT // std::cout << "SWIDataModel::getStringAsData" << std::endl; Data data; return data; } bool SWIDataModel::validate(const std::string& location, const std::string& schema) { + SET_PL_CONTEXT // std::cout << "SWIDataModel::validate" << std::endl; return true; } uint32_t SWIDataModel::getLength(const std::string& expr) { + SET_PL_CONTEXT PlCompound compound(expr.c_str()); PlTermv termv(compound.arity()); for (int i = 0; i < compound.arity(); i++) { @@ -235,6 +298,7 @@ void SWIDataModel::setForeach(const std::string& item, const std::string& array, const std::string& index, uint32_t iteration) { + SET_PL_CONTEXT PlCompound compound(array.c_str()); PlCompound orig(array.c_str()); PlTermv termv(compound.arity()); @@ -262,6 +326,7 @@ void SWIDataModel::setForeach(const std::string& item, } void SWIDataModel::eval(const Element<std::string>& scriptElem, const std::string& expr) { + SET_PL_CONTEXT if (scriptElem && HAS_ATTR(scriptElem, "type") && boost::iequals(ATTR(scriptElem, "type"), "query")) { evalAsBool(expr); } else { @@ -271,6 +336,7 @@ void SWIDataModel::eval(const Element<std::string>& scriptElem, const std::strin } bool SWIDataModel::evalAsBool(const std::string& expr) { + SET_PL_CONTEXT try { PlCompound compound(expr.c_str()); PlTermv termv(compound.arity()); @@ -285,6 +351,7 @@ bool SWIDataModel::evalAsBool(const std::string& expr) { } std::string SWIDataModel::evalAsString(const std::string& expr) { + SET_PL_CONTEXT PlCompound orig(expr.c_str()); // keep the original to find variables PlCompound compound(expr.c_str()); if (strlen(compound.name())) { @@ -316,6 +383,7 @@ std::string SWIDataModel::evalAsString(const std::string& expr) { // this is similar to http://etalis.googlecode.com/svn/eEtalis/src/term.c std::map<std::string, PlTerm> SWIDataModel::resolveAtoms(PlTerm& term, PlTerm& orig) { + SET_PL_CONTEXT std::map<std::string, PlTerm> atoms; switch (orig.type()) { case PL_VARIABLE: { @@ -343,6 +411,7 @@ std::map<std::string, PlTerm> SWIDataModel::resolveAtoms(PlTerm& term, PlTerm& o void SWIDataModel::assign(const Element<std::string>& assignElem, const Document<std::string>& doc, const std::string& content) { + SET_PL_CONTEXT std::string expr = content; std::string predicate; if (HAS_ATTR(assignElem, "expr")) { diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h index f391139..b4532cf 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h @@ -66,8 +66,8 @@ protected: std::map<std::string, PlTerm> resolveAtoms(PlTerm& term, PlTerm& orig); Event _event; - PlEngine* _plEngine; + std::string _plModule; std::string _name; std::string _sessionId; }; diff --git a/src/uscxml/plugins/invoker/CMakeLists.txt b/src/uscxml/plugins/invoker/CMakeLists.txt index e836275..67d356a 100644 --- a/src/uscxml/plugins/invoker/CMakeLists.txt +++ b/src/uscxml/plugins/invoker/CMakeLists.txt @@ -127,6 +127,26 @@ if (FFMPEG_FOUND) endif() +# calendar invoker + +if (LIBICAL_FOUND) + file(GLOB_RECURSE CALENDAR_INVOKER + calendar/*.cpp + calendar/*.h + ) + source_group("Invoker\\caledar" FILES ${CALENDAR_INVOKER}) + if (BUILD_AS_PLUGINS) + add_library( + invoker_calendar SHARED + ${CALENDAR_INVOKER}) + target_link_libraries(invoker_calendar uscxml) + set_target_properties(invoker_calendar PROPERTIES FOLDER "Plugin Invoker") + else() + list (APPEND USCXML_FILES ${CALENDAR_INVOKER}) + endif() +endif() + + # UMUNDO invoker if (UMUNDO_FOUND) diff --git a/src/uscxml/plugins/invoker/calendar/CalendarInvoker.cpp b/src/uscxml/plugins/invoker/calendar/CalendarInvoker.cpp new file mode 100644 index 0000000..7ea3fc3 --- /dev/null +++ b/src/uscxml/plugins/invoker/calendar/CalendarInvoker.cpp @@ -0,0 +1,44 @@ +#include "CalendarInvoker.h" +#include <glog/logging.h> + +#ifdef BUILD_AS_PLUGINS +#include <Pluma/Connector.hpp> +#endif + +namespace uscxml { + +#ifdef BUILD_AS_PLUGINS +PLUMA_CONNECTOR +bool connect(pluma::Host& host) { + host.add( new CalendarInvokerProvider() ); + return true; +} +#endif + +CalendarInvoker::CalendarInvoker() { +} + +CalendarInvoker::~CalendarInvoker() { +}; + +boost::shared_ptr<InvokerImpl> CalendarInvoker::create(InterpreterImpl* interpreter) { + boost::shared_ptr<CalendarInvoker> invoker = boost::shared_ptr<CalendarInvoker>(new CalendarInvoker()); + invoker->_interpreter = interpreter; + return invoker; +} + +Data CalendarInvoker::getDataModelVariables() { + Data data; + return data; +} + +void CalendarInvoker::send(const SendRequest& req) { +} + +void CalendarInvoker::cancel(const std::string sendId) { +} + +void CalendarInvoker::invoke(const InvokeRequest& req) { +} + +}
\ No newline at end of file diff --git a/src/uscxml/plugins/invoker/calendar/CalendarInvoker.h b/src/uscxml/plugins/invoker/calendar/CalendarInvoker.h new file mode 100644 index 0000000..45dc8d0 --- /dev/null +++ b/src/uscxml/plugins/invoker/calendar/CalendarInvoker.h @@ -0,0 +1,40 @@ +#ifndef CALENDARINVOKER_H_W09J90F0 +#define CALENDARINVOKER_H_W09J90F0 + +#include <uscxml/Interpreter.h> + +#ifdef BUILD_AS_PLUGINS +#include "uscxml/plugins/Plugins.h" +#endif + +namespace uscxml { + +class CalendarInvoker : public InvokerImpl { +public: + CalendarInvoker(); + virtual ~CalendarInvoker(); + virtual boost::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter); + + virtual std::set<std::string> getNames() { + std::set<std::string> names; + names.insert("calendar"); + names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#calendar"); + return names; + } + + virtual Data getDataModelVariables(); + virtual void send(const SendRequest& req); + virtual void cancel(const std::string sendId); + virtual void invoke(const InvokeRequest& req); + +protected: +}; + +#ifdef BUILD_AS_PLUGINS +PLUMA_INHERIT_PROVIDER(CalendarInvoker, InvokerImpl); +#endif + +} + + +#endif /* end of include guard: CALENDARINVOKER_H_W09J90F0 */ |