From a3fb1daf5b4e58471cc714853636025b6cac9aed Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Thu, 21 Aug 2014 13:19:08 +0200 Subject: Reactiveted new CMake policies and some more documentation --- CMakeLists.txt | 8 +++- README.md | 9 +++- contrib/local/compress_and_upload_deps.sh | 1 + docs/BUILDING.md | 2 +- docs/OVERVIEW.md | 48 +++++++++++++++++++ embedding/java/src/org/uscxml/tests/TestData.java | 56 ++++++++++++++++++----- src/bindings/swig/csharp/CMakeLists.txt | 2 +- src/bindings/swig/uscxml_beautify.i | 22 +++++++++ src/bindings/swig/uscxml_ignores.i | 6 +++ src/uscxml/Factory.cpp | 4 ++ 10 files changed, 141 insertions(+), 17 deletions(-) create mode 100644 docs/OVERVIEW.md 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 diff --git a/README.md b/README.md index a5920f7..207b3b7 100644 --- a/README.md +++ b/README.md @@ -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 @@ +#### 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 #include "uscxml/Interpreter.h" and instantiate objects of uscxml::Interpreter. 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 interpreter.receive(Event). +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 _event object at runtime. If +content is given as a literal string, it will be represented as a space-normalized string in _event.data. The +more interesting case is to pass more complex data, in which case, you need to populate the data 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 _event.data. + + std::map compound; // Associative array, key/value pairs + std::list array; // Simple array of things + Blob binary; // Binary data + Arabica::DOM::Node 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 setEvent(Event) 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 embedding directory. In order to pass XML via an event, +the Data class in the language bindings support setXML(), 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 +%} + %extend uscxml::Data { std::vector getCompoundKeys() { std::vector 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; } } -- cgit v0.12