summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-07-26 19:05:33 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-07-26 19:05:33 (GMT)
commit720bbe5c1b8c0789b5c7ad9ffca33e52bf77f1da (patch)
tree8f692eb636ddb21649097e053f8504a2dab70a01 /src/uscxml/plugins
parent8ff01ac995c8b95fa2695b6ff7e3e985bd4579d6 (diff)
downloaduscxml-720bbe5c1b8c0789b5c7ad9ffca33e52bf77f1da.zip
uscxml-720bbe5c1b8c0789b5c7ad9ffca33e52bf77f1da.tar.gz
uscxml-720bbe5c1b8c0789b5c7ad9ffca33e52bf77f1da.tar.bz2
Started calendar invoker and bug fixes
Diffstat (limited to 'src/uscxml/plugins')
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp48
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h7
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp111
-rw-r--r--src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h2
-rw-r--r--src/uscxml/plugins/invoker/CMakeLists.txt20
-rw-r--r--src/uscxml/plugins/invoker/calendar/CalendarInvoker.cpp44
-rw-r--r--src/uscxml/plugins/invoker/calendar/CalendarInvoker.h40
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 */