diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | README.md | 9 | ||||
-rwxr-xr-x | contrib/local/compress_and_upload_deps.sh | 1 | ||||
-rw-r--r-- | docs/BUILDING.md | 2 | ||||
-rw-r--r-- | docs/OVERVIEW.md | 48 | ||||
-rw-r--r-- | embedding/java/src/org/uscxml/tests/TestData.java | 56 | ||||
-rw-r--r-- | src/bindings/swig/csharp/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/bindings/swig/uscxml_beautify.i | 22 | ||||
-rw-r--r-- | src/bindings/swig/uscxml_ignores.i | 6 | ||||
-rw-r--r-- | src/uscxml/Factory.cpp | 4 |
10 files changed, 141 insertions, 17 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 11fc485..f702a67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,13 +2,17 @@ cmake_minimum_required(VERSION 2.8.4) cmake_policy(PUSH) if(POLICY CMP0042) - cmake_policy(SET CMP0042 OLD) + # new behavior defaults to ON for MACOSX_RPATH + cmake_policy(SET CMP0042 NEW) endif() if(POLICY CMP0045) + # Error on non-existent target in get_target_property, + # set to old as we actually use it to check for specific targets cmake_policy(SET CMP0045 OLD) endif() if(POLICY CMP0046) - cmake_policy(SET CMP0046 OLD) + # Error on non-existent dependency in add_dependencies + cmake_policy(SET CMP0046 NEW) endif() # specify USCXML version @@ -10,7 +10,7 @@ - [Test Reports](#test-reports) - [License](#license) - [Download](#download) -- [Usage](#usage) +- [Getting Started](#getting-started) - [Advanced Topics](#advanced-topics) - [Embedding uSCXML](#embedding-uscxml) - [Extending uSCXML](#extending-uscxml) @@ -19,6 +19,11 @@ <!-- END doctoc generated TOC please keep comment here to allow auto update --> +#### Related Documents + +- [Building form Source](docs/BUILDING.md) +- [Developer Overview](docs/OVERVIEW.md) + ## General uSCXML is a SCXML interpreter written in C/C++. It is [standards compliant](#test-reports) and [easily extended](#extending-uscxml) @@ -94,7 +99,7 @@ upon](https://github.com/tklab-tud/uscxml/blob/master/docs/BUILDING.md#build-dep We do not yet feature installers. Please download the source and have a look at the [build instructions](https://github.com/tklab-tud/uscxml/blob/master/docs/BUILDING.md). -## Usage +## Getting Started In order to use the interpreter, you need to <tt>#include "uscxml/Interpreter.h"</tt> and instantiate objects of <tt>uscxml::Interpreter</tt>. diff --git a/contrib/local/compress_and_upload_deps.sh b/contrib/local/compress_and_upload_deps.sh index 76413de..ed5d3d0 100755 --- a/contrib/local/compress_and_upload_deps.sh +++ b/contrib/local/compress_and_upload_deps.sh @@ -32,6 +32,7 @@ ssh ${USCXML_PREBUILT_HOST} mkdir -p ${USCXML_PREBUILT_PATH}/${VERSION} PLATFORMS=`find . -maxdepth 1 -type d -regex ./[^\.].*` #PLATFORMS="linux-x86_64" +PLATFORMS="linux-armv6l" #PLATFORMS="darwin-i386" #PLATFORMS="windows-x86" for FILE in ${PLATFORMS}; do diff --git a/docs/BUILDING.md b/docs/BUILDING.md index d31b28e..abc5839 100644 --- a/docs/BUILDING.md +++ b/docs/BUILDING.md @@ -336,7 +336,7 @@ Now you can compile uSCXML like on any other platform: If you want an ECMAScript datamodel or LUA, you will need to install additional packages: # additional datamodels: ECMAScript, LUA, Prolog - $ sudo apt-get install libjavascriptcoregtk-3.0-dev liblua5.2-dev swi-prolog-nox + $ sudo apt-get install libjavascriptcoregtk-3.0-dev liblua5.2-dev swi-prolog-nox # additional invokers $ sudo apt-get install libical-dev libpurple-dev libopenal-dev libsndfile1-dev libopenscenegraph-dev diff --git a/docs/OVERVIEW.md b/docs/OVERVIEW.md new file mode 100644 index 0000000..e930e80 --- /dev/null +++ b/docs/OVERVIEW.md @@ -0,0 +1,48 @@ +# uSCXML Developer Overview + +The core concept with uSCXML is a state chart and its syntax with regard to valid elements and attributes is given +in the [SCXML specification](http://www.w3.org/TR/scxml/). uSCXML is standards compliant with the exception of +transitions in history elements which were added rather recently. + +## Events + +To bring a state-chart to life it needs to receive events. After you instantiated and started SCXML interpreter it +will assume a stable configuration and wait for events. You can send events via <tt>interpreter.receive(Event)</tt>. +An event consists (foremost) of the following attributes: + + std::string name; // the name of the event + std::string origin; // where the event originated + std::string origintype; // the type of the event's source + std::string content; // literal string content to be space-normalized + Data data; // complex, JSON-like event data (conflicts with literal string content) + +The first three attributes are available as simple attributes of the datamodel's <tt>_event</tt> object at runtime. If +content is given as a literal string, it will be represented as a space-normalized string in <tt>_event.data</tt>. The +more interesting case is to pass more complex data, in which case, you need to populate the <tt>data</tt> attribute. + +### Data + +The data attribute, as an instance of the Data class contains a nested tree of arbitrary content and can be used to +pass more complex data structures than space-normalized string literals into the interpreter as <tt>_event.data</tt>. + + std::map<std::string, Data> compound; // Associative array, key/value pairs + std::list<Data> array; // Simple array of things + Blob binary; // Binary data + Arabica::DOM::Node<std::string> node; // A DOM node + std::string atom; // String literal or identifier/value, depending on type + Type type; // [VERBATIM | INTERPRETED], + +Not all datamodels support all types of data, e.g. neither the Prolog nor the Lua datamodel support binary data. +When in doubt, you will have to have a look at the <tt>setEvent(Event)</tt> method of the respective datamodel +implementation. The most complete datamodel's in terms of supported types are those with ECMAScript, supporting +Core Level 2 for XML data and TypedArrays to handle binary data. + +When you populate a data object, you can only ever set a single attribute. You can, for example, not set a key in the +compound and an index in the array and expect something meaningful at runtime. For nesting use compound and array, for +scalar data use atom, binary or node. + +### DOM Nodes in the Language Bindings + +We do not wrap DOM nodes into the target language but pass its serialized XML string representation to be reparsed in +the target languages. There are some examples in the <tt>embedding</tt> directory. In order to pass XML via an event, +the Data class in the language bindings support <tt>setXML()</tt>, which will accept a valid XML string.
\ No newline at end of file diff --git a/embedding/java/src/org/uscxml/tests/TestData.java b/embedding/java/src/org/uscxml/tests/TestData.java index 0a95328..d470d00 100644 --- a/embedding/java/src/org/uscxml/tests/TestData.java +++ b/embedding/java/src/org/uscxml/tests/TestData.java @@ -1,11 +1,21 @@ package org.uscxml.tests; +import java.io.StringWriter; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + import org.uscxml.Blob; import org.uscxml.Data; +import org.w3c.dom.Document; public class TestData { - public static void main(String[] args) { + public static void main(String[] args) throws Exception { System.load("/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/libuscxmlNativeJava64.jnilib"); { Data data = Data.fromJSON("[1,2,3,4,5]"); @@ -15,36 +25,60 @@ public class TestData { Data data = Data.fromJSON("{ \"foo\": \"bar\", \"faz\": 12 }"); System.out.println(data); } - + + { + Data data = new Data(); + + DocumentBuilderFactory factory = DocumentBuilderFactory + .newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + + Document document = builder.newDocument(); + document.appendChild(document.createElement("foo")); + + Transformer transformer = TransformerFactory.newInstance() + .newTransformer(); + StreamResult result = new StreamResult(new StringWriter()); + DOMSource source = new DOMSource(document); + transformer.transform(source, result); + + String xml = result.getWriter().toString(); + + data.setXML(xml); + System.out.println(data.getXML()); + } + { byte origData[] = new byte[1024]; for (int i = 0; i < origData.length; i++) { - origData[i] = (byte)i; + origData[i] = (byte) i; } - + { Blob blob = new Blob(origData, "application/octet-stream"); - if (origData.length != blob.getSize()) throw new RuntimeException("Blob does not match"); + if (origData.length != blob.getSize()) + throw new RuntimeException("Blob does not match"); for (int i = 0; i < origData.length; i++) { if (origData[i] != blob.getData()[i]) throw new RuntimeException("Blob mismatch at " + i); } } - + Data data = new Data(origData, "application/octet-stream"); Blob blob = data.getBinary(); System.out.println(blob.getSize()); - + byte newData[] = blob.getData(); - - if (newData.length != origData.length) throw new RuntimeException("Arrays length does not match"); + + if (newData.length != origData.length) + throw new RuntimeException("Arrays length does not match"); for (int i = 0; i < origData.length; i++) { if (newData[i] != origData[i]) throw new RuntimeException("Mismatch at " + i); } - + } - + } } diff --git a/src/bindings/swig/csharp/CMakeLists.txt b/src/bindings/swig/csharp/CMakeLists.txt index ee37bf7..384507b 100644 --- a/src/bindings/swig/csharp/CMakeLists.txt +++ b/src/bindings/swig/csharp/CMakeLists.txt @@ -78,7 +78,7 @@ if (DMCS_EXECUTABLE OR CSC_EXECUTABLE) COMMENT "Creating umundoCSharp.dll for Mono ...") endif() - add_dependencies(csharp umundoNativeCSharp) + add_dependencies(csharp uscxmlNativeCSharp) if (BUILD_TESTS) add_dependencies(ALL_TESTS csharp) endif() diff --git a/src/bindings/swig/uscxml_beautify.i b/src/bindings/swig/uscxml_beautify.i index bf54958..751be78 100644 --- a/src/bindings/swig/uscxml_beautify.i +++ b/src/bindings/swig/uscxml_beautify.i @@ -114,6 +114,10 @@ }; +%{ + #include <glog/logging.h> +%} + %extend uscxml::Data { std::vector<std::string> getCompoundKeys() { std::vector<std::string> keys; @@ -124,4 +128,22 @@ } return keys; } + + std::string getXML() { + if (!self->node) + return ""; + + std::stringstream ss; + ss << self->node; + return ss.str(); + } + + void setXML(const std::string& xml) { + NameSpacingParser parser = NameSpacingParser::fromXML(xml); + if (!parser.errorsReported()) { + self->node = parser.getDocument(); + } else { + LOG(ERROR) << "Cannot parse message as XML: " << parser.errors(); + } + } }; diff --git a/src/bindings/swig/uscxml_ignores.i b/src/bindings/swig/uscxml_ignores.i index f7d3dad..c8fc372 100644 --- a/src/bindings/swig/uscxml_ignores.i +++ b/src/bindings/swig/uscxml_ignores.i @@ -189,6 +189,12 @@ %ignore uscxml::SendRequest::fromXML; %ignore uscxml::InvokeRequest::fromXML; +// HTTPServer + +%ignore uscxml::HTTPServer::wsSend; +%ignore uscxml::HTTPServer::wsBroadcast; +%ignore uscxml::HTTPServer::reply; + // Data diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp index ce09a27..9ebc0d8 100644 --- a/src/uscxml/Factory.cpp +++ b/src/uscxml/Factory.cpp @@ -445,14 +445,17 @@ void Factory::listComponents() { { std::cout << "Available Datamodels:" << std::endl; LIST_COMPONENTS(DataModelImpl, _dataModels); + std::cout << std::endl; } { std::cout << "Available Invokers:" << std::endl; LIST_COMPONENTS(InvokerImpl, _invokers); + std::cout << std::endl; } { std::cout << "Available I/O Processors:" << std::endl; LIST_COMPONENTS(IOProcessorImpl, _ioProcessors); + std::cout << std::endl; } { std::cout << "Available Elements:" << std::endl; @@ -461,6 +464,7 @@ void Factory::listComponents() { std::cout << "\t" << iter->second->getNamespace() << " / " << iter->second->getLocalName() << std::endl; iter++; } + std::cout << std::endl; } } |