diff options
author | Stefan Radomski <github@mintwerk.de> | 2016-05-12 13:12:33 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2016-05-12 13:12:33 (GMT) |
commit | b62e7979600feee23dc7cdb61042a8fc7673122b (patch) | |
tree | f7351372f37979dd2d048e0b68a16a4cd3b2aadb /apps | |
parent | 1b11b310be61e51b3ac5ebb83f7c8a33aef3d6e8 (diff) | |
download | uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.zip uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.gz uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.bz2 |
Major Refactoring v2.0
Diffstat (limited to 'apps')
59 files changed, 82 insertions, 11900 deletions
diff --git a/apps/restart-on-term.sh b/apps/restart-on-term.sh deleted file mode 100644 index 37bb4fa..0000000 --- a/apps/restart-on-term.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -# see http://superuser.com/questions/223449/auto-restart-process-on-crash -PROGRAM=$1 - -RC=1 -while [ $RC -ne 0 ]; do - ./${PROGRAM} - RC=$? -done diff --git a/apps/samples/http2im/http2im.scxml b/apps/samples/http2im/http2im.scxml deleted file mode 100644 index 369c6a6..0000000 --- a/apps/samples/http2im/http2im.scxml +++ /dev/null @@ -1,48 +0,0 @@ -<scxml datamodel="ecmascript" name="http2im"> - - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - <state id="idle"> - <onentry> - <!-- <send event="dump" delay="100ms" /> --> - </onentry> - - <invoke type="instant-messaging" id="im"> - <param name="username" expr="'uscxml@diogenes.local'" /> - <param name="password" expr="'uscxml'" /> - <param name="protocol" expr="'prpl-jabber'" /> - <finalize> - <script> - print("-----------------\n"); - dump(_event);</script> - </finalize> - </invoke> - - <transition event="http.get"> - <script> - print("-----------------\n"); - dump(_event);</script> - <respond status="200" to="_event.origin" /> - <send target="#_im" event="im.send"> - <param name="receiver" expr="'benedikt@diogenes.local'" /> - <content expr="_event.data.query.msg" /> - </send> - </transition> - - <transition event="im.buddy.status.changed"> - <!-- <script>print("\n\n"); dump(_invokers['im']);</script> --> - </transition> - - <transition event="im.signed.on"> - <!-- <send target="#_im" event="im.buddy.add"> - <param name="name" expr="'sradomski@diogenes.local'" /> - <param name="msg" expr="'Please add me as a contact!'" /> - </send> --> - <!-- <script>print("\n\n"); dump(_invokers['im']);</script> --> - <send target="#_im" event="im.send"> - <param name="receiver" expr="'sradomski@diogenes.local'" /> - <content><![CDATA[Have a look <a href="http://www.heise.de">here</a>]]></content> - </send> - </transition> - - </state> -</scxml>
\ No newline at end of file diff --git a/apps/samples/map/SpatialMapTicker.java b/apps/samples/map/SpatialMapTicker.java deleted file mode 100644 index 9947ffb..0000000 --- a/apps/samples/map/SpatialMapTicker.java +++ /dev/null @@ -1,160 +0,0 @@ -/** - * Compile as: - * $ javac -cp .:/usr/local/share/umundo/java/umundo.jar SpatialMapTicker.java - * - * Run as: - * $ java -cp .:/usr/local/share/umundo/java/umundo.jar SpatialMapTicker - */ -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.LinkedList; -import java.util.Random; - -import org.umundo.core.Greeter; -import org.umundo.core.Message; -import org.umundo.core.Node; -import org.umundo.core.Publisher; - -public class SpatialMapTicker { - - Node node; - Publisher pub; - Greeter greeter; - ArrayList<Sensor> sensors = new ArrayList<Sensor>(); - static ArrayList<SensorMessage> messages = new ArrayList<SensorMessage>(); - static Random random = new Random(System.currentTimeMillis()); - - public class SensorMessage { - public String message; - public int severity; - public SensorMessage(String message, int severity) { - this.message = message; - this.severity = severity; - } - public SensorMessage(String message) { - this.message = message; - this.severity = 3; - } - } - - public class Sensor { - @Override - public String toString() { - return "Sensor [id=" + id + ", lat=" + lat + ", lon=" + lon - + ", html=" + getHTML() + "]"; - } - public String id = ""; - public Double lat = new Double(0); - public Double lon = new Double(0); - LinkedList<SensorMessage> messages = new LinkedList<SensorMessage>(); - - public void addMessage(SensorMessage message) { - if (messages.size() > 15) - messages.removeLast(); - messages.addFirst(message); - } - - public String getHTML() { - StringBuilder sb = new StringBuilder(); - for (SensorMessage message : messages) { - sb.append(message.severity); - sb.append(": "); - sb.append(message.message); - sb.append("<br />"); - } - return sb.toString(); - } - } - - public class SensorGreeter extends Greeter { - public void welcome(Publisher publisher, String nodeId, String subId) { - // send all sensors to new subscribers - for (Sensor sensor : sensors) { - Message msg = new Message(); //Message.toSubscriber(subId); - msg.putMeta("id", sensor.id); - msg.putMeta("lat", sensor.lat.toString()); - msg.putMeta("lon", sensor.lon.toString()); - msg.putMeta("html", sensor.getHTML()); - pub.send(msg); - } - } - - @Override - public void farewell(Publisher arg0, String nodeId, String subId) { - } - - } - - public SpatialMapTicker() { - node = new Node(); - pub = new Publisher("map/tick"); - greeter = new SensorGreeter(); - pub.setGreeter(greeter); - node.addPublisher(pub); - - double latCenter = 59.32; - double lonCenter = 18.08; - - int nrSensors = 15; //(int) (Math.random() * 20); - for (int i = 0; i < nrSensors; i++) { - Sensor sensor = new Sensor(); - double latOffset = (Math.random() - 0.5) * 0.3; - double lonOffset = (Math.random() - 0.5) * 0.3; - - sensor.id = "Sensor #" + i; - sensor.lat = latCenter + latOffset; - sensor.lon = lonCenter + lonOffset; - sensors.add(sensor); - } - } - - public static void main(String[] args) { - SpatialMapTicker ticker = new SpatialMapTicker(); - ticker.run(); - } - - private void run() { - messages.add(new SensorMessage("Oil pressure threshold exceeded")); - messages.add(new SensorMessage("Equipment is on fire")); - messages.add(new SensorMessage("Error #32 in diagnostics unit")); - messages.add(new SensorMessage("Unauthorized startup")); - messages.add(new SensorMessage("Tire pressure too low")); - messages.add(new SensorMessage("Error #145 in diagnostics unit")); - messages.add(new SensorMessage("Unit was moved out of construction site area")); - messages.add(new SensorMessage("Hydraulic pressure exceeding safety limits")); - messages.add(new SensorMessage("Drivers seat belts are not fastened!")); - messages.add(new SensorMessage("Battery recharge cycles exceeded")); - messages.add(new SensorMessage("Unit operated outside recommended paramters")); - - while (true) { - try { - Thread.sleep((long) (Math.random() * 300) + 100); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - Sensor sensor = sensors.get(random.nextInt(sensors.size())); - SensorMessage fault = messages.get(random.nextInt(messages.size())); - - Date now = new Date(); - SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss z"); - String nowString = sdf.format(now); - sensor.addMessage(fault); - -// System.out.println("Publishing " + sensor); - - Message msg = new Message(); - msg.putMeta("id", sensor.id); - msg.putMeta("lat", sensor.lat.toString()); - msg.putMeta("lon", sensor.lon.toString()); - msg.putMeta("html", sensor.getHTML()); - msg.putMeta("time", nowString); - msg.putMeta("timeStamp", Long.toString(now.getTime())); - msg.putMeta("message", sensor.messages.getFirst().message); - msg.putMeta("severity", Integer.toString(random.nextInt(10))); - pub.send(msg); - } - } - -} diff --git a/apps/samples/map/click.wav b/apps/samples/map/click.wav Binary files differdeleted file mode 100644 index e11b0b7..0000000 --- a/apps/samples/map/click.wav +++ /dev/null diff --git a/apps/samples/map/spoken-map-ticker.scxml b/apps/samples/map/spoken-map-ticker.scxml deleted file mode 100644 index 3955715..0000000 --- a/apps/samples/map/spoken-map-ticker.scxml +++ /dev/null @@ -1,78 +0,0 @@ -<scxml datamodel="ecmascript" name="mapticker" - xmlns:html="http://www.w3.org/1999/xhtml" - xmlns:vxml="http://www.w3.org/2001/vxml" - xmlns="http://www.w3.org/2005/07/scxml"> - - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - - <state id="start"> - <!-- - Invoke an external HTML browser - --> - <invoke type="xhtml" id="xhtml1"> - <content src="spoken-map-ticker.xhtml" /> - <finalize> - <!-- <script>dump(_event);</script> --> - </finalize> - </invoke> - - <!-- - Invoke a VoiceXML browser - --> - <!-- invoke type="vxml" id="vxml" / --> - - <!-- - Invoke a uMundo component for pub/sub ticker subscription - --> - <invoke type="umundo" id="umundo"> - <param name="channel" expr="'map/tick'" /> - <finalize> - <!-- <script>dump(_event);</script> --> - </finalize> - </invoke> - - <invoke type="openal" id="audio"></invoke> - - <state id="idle"> - <!-- - Map in XHTML invoker was moved -> update OpenAL listener position - --> - <transition event="map.center" target="idle"> - <send event="move.listener" target="#_audio"> - <param name="x" expr="_event.data.lon" /> - <param name="y" expr="1" /> - <param name="z" expr="_event.data.lat" /> - </send> - </transition> - - <!-- - Ticker message was received - -> Send to XHTML invoker to display - -> Play clicking noise from respective direction - -> Speak content if severity exceeds a given threshold - --> - <transition target="idle" event="umundo.rcvd"> - <send target="#_xhtml1"> - <content>${_event.data}</content> - </send> - <send target="#_audio" event="play" delay="0ms"> - <param name="src" expr="'click.wav'" /> - <param name="x" expr="_event.data.lon" /> - <param name="y" expr="0" /> - <param name="z" expr="_event.data.lat" /> - </send> - - <if cond="_event.data.message && _event.data.severity > 8"> - <send target="#_vxml"> - <content> - <vxml:prompt> - ${_event.data.message} - </vxml:prompt> - </content> - </send> - </if> - - </transition> - </state> - </state> -</scxml>
\ No newline at end of file diff --git a/apps/samples/map/spoken-map-ticker.xhtml b/apps/samples/map/spoken-map-ticker.xhtml deleted file mode 100644 index ace8724..0000000 --- a/apps/samples/map/spoken-map-ticker.xhtml +++ /dev/null @@ -1,240 +0,0 @@ -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <!-- space in between script is required as <script/> is not valid HTML to most browsers --> - <script type="text/javascript" src="http://code.jquery.com/jquery-2.0.3.js"> </script> - <script type="text/javascript" src="http://www.openlayers.org/api/OpenLayers.js"> </script> - <script type="text/javascript" src="http://epikur.local/~sradomski/CometSession.js"> </script> - <script type="text/javascript" src="https://raw.github.com/jchavannes/jquery-timer/master/jquery.timer.js"> </script> - - <style type="text/css"> - html, body, #map { - width: 100%; - height: 100%; - margin: 0; - } - .olPopup { - border-radius: 8px; - } - div.olControlOverviewMapElement { - background-color: #666; - } - div.olMap { - width: 180px; - height: 120px; - margin: 0; - } - div.timeRuler { - font-family:Courier,Arial,Helvetica,sans-serif; - font-size: 1.2em; - font-weight: bold; - background-color: #eee; - } - div#message { - overflow: auto; - height: 100%; - font-family:Courier,Arial,Helvetica,sans-serif; - font-size: 0.6em; - } - - div#message p { - padding: 0px; - margin: 4px 2px; - } - - </style> - - <!-- script type="text/javascript" src="http://localhost/~sradomski/CometSession.js"></script --> - <script type="text/javascript"> -//<![CDATA[ - $(document).ready(function() { - var scxml = new CometSession({ - server: document.URL, - onEvent: function(response, message) { - if (message) { - console.log(message); - - if (!markers[message.id]) { - addMarker(message); - } else { - for (i = 0; i < map.popups.length; i++) { - if (map.popups[i].feature.id === message.id) { - map.popups[i].setContentHTML("<h3>" + message.id + "</h3>" + message.html); - } - } - markers[message.id].marker.opacity = 1.0; - markers[message.id].marker.setOpacity(1.0); - - markers[message.id].marker.timer.play(); - markers[message.id].feature.popupContentHTML = "<h3>" + message.id + "</h3>" + message.html; - } - - if (message.message && message.message.length > 0) { - var messageDiv = $("#message")[0]; - if (message.timeStamp > lastUpdateTime + 3000) { - var timeRuler = document.createElement("div"); - timeRuler.setAttribute("class", "timeRuler"); - timeRuler.innerHTML = message.time; // + messageDiv.innerHTML; - messageDiv.appendChild(timeRuler); - lastUpdateTime = message.timeStamp; - } - - console.log(message.timeStamp); - console.log(lastUpdateTime); - - var messagePara = document.createElement("p"); - if (message.severity > 7) { - messagePara.setAttribute("style", "color:red; font-weight:bold;"); - } - messagePara.innerHTML += message.message; // + messageDiv.innerHTML; - - messageDiv.appendChild(messagePara); - messagePara.addEventListener("mousedown", function() { - var marker = markers[message.id].marker; - marker.events.triggerEvent("mousedown"); - }); - messagePara.addEventListener("mouseover", function() { - messagePara.style.backgroundColor = "#eee"; - }); - messagePara.addEventListener("mouseout", function() { - messagePara.style.backgroundColor = "#fff"; - }); - - if (!stopScrolling) { - messageDiv.scrollTop = messageDiv.scrollHeight; - } - } - } - } - }); - - // var map = new OpenLayers.Map("demoMap"); - // map.addLayer(new OpenLayers.Layer.OSM()); - // map.zoomToMaxExtent(); - - var markers = {}; - var lastUpdateTime = 0; - var stopScrolling = false; - - var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984 - var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection - - function onMoveEvent() { - var position = map.getCenter().transform(toProjection, fromProjection); - if (Math.random() > 0.7) { // do not publish every move event - scxml.send('map.center', { - 'zoom': map.getZoom(), - 'lon': position.lon, - 'lat': position.lat }); - } - } - - function onMoveEndEvent() { - var position = map.getCenter().transform(toProjection, fromProjection); - scxml.send('map.center', { - 'zoom': map.getZoom(), - 'lon': position.lon, - 'lat': position.lat }); - } - - function addMarker(message) { - var feature = new OpenLayers.Feature( - markerLayer, - new OpenLayers.LonLat(message.lon, message.lat).transform(fromProjection, toProjection)); - feature.closeBox = true; - feature.popupClass = OpenLayers.Class(OpenLayers.Popup.Anchored, { - 'autoSize': true, -// 'maxSize': new OpenLayers.Size(300,200) - }); - feature.data.popupContentHTML = "<h3>" + message.id + "</h3>" + message.html; - feature.data.overflow = "auto"; - feature.data.id = message.id; - var marker = feature.createMarker(); - - marker.timer = $.timer(function() { - if (marker.opacity > 0.5) { - marker.opacity -= 0.02; - marker.setOpacity(marker.opacity); - } else { - marker.timer.stop(); - } - }, 100); - - marker.opacity = 1.0; - marker.setOpacity(marker.opacity); - marker.timer.play(); - - markerClick = function(evt) { - if (this.popup == null) { - this.popup = this.createPopup(this.closeBox); - map.addPopup(this.popup); - this.popup.show(); - } else { - this.popup.toggle(); - } - currentPopup = this.popup; - OpenLayers.Event.stop(evt); - }; - - marker.events.register("mousedown", feature, markerClick); - markers[message.id] = { - 'marker': marker, - 'feature': feature - }; - markerLayer.addMarker(marker); - } - // see also: http://php-baustelle.de/openlayers/step-by-step/ - var map = new OpenLayers.Map('map', { - eventListeners: { - "move": onMoveEvent, - "moveend": onMoveEndEvent, - } - }); - - var mapnik = new OpenLayers.Layer.OSM(); - var markerLayer = new OpenLayers.Layer.Markers("Markers"); -// var attribution = new OpenLayers.Layer.Vector("Attribution", {attribution:"for Smart Vortex"}); - - map.addLayer(mapnik); -// map.addLayer(attribution); - map.addLayer(markerLayer); // has to be the last layer to receive events! - - map.addControl(new OpenLayers.Control.LayerSwitcher()); - // see also http://dev.openlayers.org/releases/OpenLayers-2.12/examples/mousewheel-interval.html - map.addControl(new OpenLayers.Control.Navigation( - {dragPanOptions: {enableKinetic: true}} - )); - - var overview = new OpenLayers.Control.OverviewMap({ - maximized: true, - minRatio: 200, - maxRatio: 300, - }); - map.addControl(overview); - - // stockholm - var position = new OpenLayers.LonLat(18.08,59.32).transform(fromProjection, toProjection); -// var position = new OpenLayers.LonLat(0,0).transform(fromProjection, toProjection); - var zoom = 11; - map.setCenter(position, zoom); - - // var message = { - // 'id': "12", - // 'lat': 59.454441065280534, - // 'lon': 18.062356332194543, - // 'html': '<p>asdf</p>' - // }; - -// addMarker(message); - }); -//]]> - </script> - </head> - <body> - <table width="100%" height="100%"> - <tr> - <td width="20%" height="100%"><div id="message" onmouseover="stopScrolling = true" onmouseout="stopScrolling = false"></div></td> - <td width="80%" height="100%"><div id="map"></div></td> - </tr> - </table> - </body> -</html>
\ No newline at end of file diff --git a/apps/samples/miles/emptyface.jpg b/apps/samples/miles/emptyface.jpg Binary files differdeleted file mode 100755 index a1b2f32..0000000 --- a/apps/samples/miles/emptyface.jpg +++ /dev/null diff --git a/apps/samples/miles/miles.html b/apps/samples/miles/miles.html deleted file mode 100644 index c6891a2..0000000 --- a/apps/samples/miles/miles.html +++ /dev/null @@ -1,51 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> - <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/tundra/tundra.css"> - - <style type="text/css"> - </style> - - <script type="text/javascript"> - </script> - - <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.9.1/dojo/dojo.js"></script> - <script src="miles.js"></script> - - <script type="text/javascript"> - require(["dojo/domReady!"], function(dom) { - var milesSession1 = new Miles("miles1", { - "scxmlURL": "85.22.93.138:8085", - "reflectorIp": "88.131.107.12", - "email": "user@smartvortex.eu", - "problemName": "webconfero", - "remoteEmail": "yetanother@smartvortex.eu" - }); - var milesSession2 = new Miles("miles2", {"scxmlURL": "localhost:8080", "reflectorIp": "88.131.107.12", "email": "user@smartvortex.eu", "problemName": "webconfero", "remoteEmail": "yetanother@smartvortex.eu"}); - var milesSession3 = new Miles("miles3", {"scxmlURL": "localhost:8080", "reflectorIp": "88.131.107.12", "email": "user@smartvortex.eu", "problemName": "webconfero", "remoteEmail": "stillanother@smartvortex.eu"}); - var milesSession4 = new Miles("miles4", {"scxmlURL": "localhost:8080", "reflectorIp": "88.131.107.12", "email": "user@smartvortex.eu", "problemName": "webconfero", "remoteEmail": "last@smartvortex.eu"}); - }); - </script> - </head> - <body class="tundra"> - <table> - <tr> - <td> - <div id="miles1"></div> - </td> - <td> - <div id="miles2"></div> - </td> - </tr> - <tr> - <td> - <div id="miles3"></div> - </td> - <td> - <div id="miles4"></div> - </td> - </tr> - </table> - </body> -</html> diff --git a/apps/samples/miles/miles.js b/apps/samples/miles/miles.js deleted file mode 100644 index 01bb134..0000000 --- a/apps/samples/miles/miles.js +++ /dev/null @@ -1,630 +0,0 @@ -function Miles(element, params) { - // private attributes - var self = this; - - // private instanceId - if (!Miles.instances) - Miles.instances = 0; - this.instanceId = Miles.instances++; - - // public attributes defaults - this.imageIteration = 0; - this.resRoot = ""; - this.reflectorIp = "88.131.107.12"; - this.email = "user@smartvortex.eu"; - this.problemName = "webconfero"; - this.remoteEmail = "other@smartvortex.eu"; - this.scxmlURL = "localhost:8080" - - this.width = 320; - this.height = 240; - - this.showVideo = true; - this.enableAudio = true; - this.activateCamera = true; - this.openMicrophone = true; - this.videoFramerate = 25; - this.videoHeight = this.height; - this.videoWidth = this.width; - - // copy over values from constructor arguments - if (params) { - for (var param in params) { - if (self.hasOwnProperty(param)) - self[param] = params[param]; - } - } - - // private attributes - var connected = false; - - var participants = []; // empty array - var videoCompressions = [ - { value: 'jpeg', label: "JPEG" }, - { value: 'h263', label: "H.263" }, - { value: 'h264', label: "H.264" }, - ]; - var videoCompression = ""; - - var audioEncodings = [ - { value: 'pcm', label: "PCM" }, - { value: 'ulaw', label: "uLaw" }, - { value: 'ogg', label: "Ogg Theora" }, - ]; - var audioEncoding = ""; - - var repollInterval = { - image: 20, - chat: 500, - participants: 1000 - }; - - var surpressPublication = false; // do not publish changes performed from subscriptions - var stopChatScrolling = false; - - // called when dojo loaded all requirements below - this.connect = function() { - var query = ""; - query += "?reflector=" + encodeURIComponent(self.reflectorIp); - query += "&userid=" + encodeURIComponent(self.email); - query += "&session=" + encodeURIComponent(self.problemName); - - //self.messageElem.innerHTML += "Connecting to http://" + self.scxmlURL + "/miles/start" + query + "<br />"; - self.xhr.get({ - // The URL to request - url: "http://" + self.scxmlURL + "/miles/start" + query, - // handleAs:"text", - error: function(err) { - console.log(err); - }, - load: function(result) { - connected = true; - // toggle connect button to disconnect - self.connectDropDown.dropDown.onCancel(true); - self.controlElem.replaceChild(self.controlDropDown.domNode, self.connectDropDown.domNode); - - showChat(); - - // trigger continuous updates - refreshImage(); - getChatText(); - getParticipants(); - } - }); - } - - this.disconnect = function() { - var query = ""; - query += "?reflector=" + encodeURIComponent(self.reflectorIp); - query += "&userid=" + encodeURIComponent(self.email); - query += "&session=" + encodeURIComponent(self.problemName); - - self.xhr.get({ - // The URL to request - url: "http://" + self.scxmlURL + "/miles/stop" + query, - // handleAs:"text", - error: function(err) { - console.log(err); - }, - load: function(result) { - connected = false; - hideChat(); - self.controlDropDown.dropDown.onCancel(true); - self.controlElem.replaceChild(self.connectDropDown.domNode, self.controlDropDown.domNode); - } - }); - } - - var hideChat = function() { - // hide chat elements until connected - for(var key in self.chatElems) { - if (self.chatElems.hasOwnProperty(key) && "style" in self.chatElems[key]) - self.chatElems[key].style.display = "none"; - } - } - - var showChat = function() { - for(var key in self.chatElems) { - if (self.chatElems.hasOwnProperty(key) && "style" in self.chatElems[key]) - self.chatElems[key].style.display = ""; - } - } - - var getParticipants = function() { - if (!connected) - return; - - var query = ""; - self.xhr.get({ - // The URL to request - url: "http://" + self.scxmlURL + "/miles/participants" + query, - handleAs:"json", - error: function(err) { - console.log(err); - setTimeout(getParticipants, repollInterval.participants); - }, - load: function(result) { - if (result.participants) { - participants = result.participants; - } - setTimeout(getParticipants, repollInterval.participants); - } - }); - } - - // fetch a base64 encoded image and set it as the src attribute - var refreshImage = function() { - if (!connected) - return; - - var query = ""; - query += "?userid=" + encodeURIComponent(self.remoteEmail); - self.xhr.get({ - // The URL to request - url: "http://" + self.scxmlURL + "/miles/thumbnail" + query, - handleAs:"text", - headers:{ - "X-Content-Encoding": "base64" - }, - error: function(err) { - console.log(err); - setTimeout(refreshImage, repollInterval.image); - }, - load: function(result) { - self.pictureElem.src = "data:image/jpeg;base64," + result; - //self.messageElem.innerHTML = self.imageIteration++; - setTimeout(refreshImage, repollInterval.image); - } - }); - }; - - var getChatText = function() { - if (!connected) - return; - - self.xhr.get({ - // The URL to request - url: "http://" + self.scxmlURL + "/miles/gettext", - handleAs:"json", - error: function(err) { - console.log(err); - setTimeout(getChatText, repollInterval.chat); - }, - load: function(result) { - if (result.message) { - self.chatOutputElem.innerHTML += result.message + '<br />'; - if (!stopChatScrolling) - self.chatOutputElem.scrollTop = self.chatOutputElem.scrollHeight; - } - setTimeout(getChatText, repollInterval.chat); - } - }); - }; - - - require(["dojo/dom-construct", - "dojo/_base/xhr", - "dojo/dom", - "dojo/on", - "dojo/topic", - "dojo/_base/unload", - "dijit/form/DropDownButton", - "dijit/TooltipDialog", - "dijit/form/TextBox", - "dijit/form/Button", - "dijit/form/CheckBox", - "dijit/form/Select", - "dijit/form/NumberSpinner", - "dojo/ready"], - function(domConst, - xhr, - dom, - on, - topic, - baseUnload, - DropDownButton, - TooltipDialog, - TextBox, - Button, - CheckBox, - Select, - NumberSpinner, - ready) { - ready(function() { - self.xhr = xhr; - - // if we were passed an id, resolve to dom node - if (typeof(element) === 'string') { - element = dom.byId(element); - } - element.style.width = self.width + "px"; - - baseUnload.addOnWindowUnload(function(){ - self.disconnect(); - }); - - // dynamically assemble the DOM we need - element.appendChild(domConst.toDom('\ - <table>\ - <tr>\ - <td valign="top" colspan="2" >\ - <div style="position: relative; padding: 0px">\ - <img class="picture" src="' + self.resRoot + 'emptyface.jpg"></img>\ - <div style="position: absolute; left: 10px; top: 10px">\ - <table></tr>\ - <td class="control" style="vertical-align: middle"></td>\ - </tr></table>\ - </div>\ - </div>\ - </td>\ - </tr>\ - <tr><td valign="top" colspan="2" >\ - <div class="chatOutput" style="max-height:120px; overflow: auto">\ - </td></tr>\ - <tr class="chat">\ - <td valign="top" style="vertical-align: middle">\ - <div class="chatInput">\ - </td>\ - <td valign="top"><div class="chatSendButton"></td>\ - </tr>\ - <tr>\ - <td valign="top" colspan="2" >\ - <div class="messages">\ - </td>\ - </tr>\ - </table>\ - ')); - - // from the above DOM, fetch some nodes to put dojo widgets in - self.pictureElem = dojo.query("img.picture", element)[0]; - self.pictureElem.width = self.width; - self.pictureElem.height = self.height; - self.controlElem = dojo.query("td.control", element)[0]; - self.messageElem = dojo.query("div.messages", element)[0]; - self.chatOutputElem = dojo.query("div.chatOutput", element)[0]; - self.chatOutputElem.style.fontSize = "0.8em"; - self.chatElems = dojo.query(".chat", element); - - console.log(self.controlElem); - - hideChat(); - - on(self.chatOutputElem, "mouseover", function(evt) { - stopChatScrolling = true; - }); - on(self.chatOutputElem, "mouseout", function(evt) { - stopChatScrolling = false; - }); - - self.chatInputElem = dojo.query("div.chatInput", element)[0]; - - self.chatSendButton = new Button({ - label: "Send", - onClick: function(){ - self.xhr.post({ - // The URL to request - url: "http://" + self.scxmlURL + "/miles/text", - contentType: 'application/json', - postData: dojo.toJson({ - message: self.chatInput.get('value'), - userid: self.email - }), - error: function(err) { - console.log(err); - }, - load: function(result) { - self.chatInput.set('value', ''); - } - }); - - } - - }, dojo.query("div.chatSendButton", element)[0]); - - // the chat interface - self.chatInput = new TextBox({ - name: "chatInput", - style: "width: 100%", - onKeyDown: function(e) { - var code = e.keyCode || e.which; - if( code === 13 ) { - e.preventDefault(); - self.chatInput.get('value'); // send button reads empty string otherwise?! - self.chatSendButton.onClick(); - return false; - } - }, - }, self.chatInputElem); - - - // the connect dropdown button - self.connectDropDownContent = domConst.toDom('\ - <div>\ - <table>\ - <tr><td>Problem Name:</td><td><div class="problemName" /></td></tr>\ - <tr><td>Your Email:</td><td><div class="email" /></td></tr>\ - <tr><td>Other Email:</td><td><div class="remoteEmail" /></td></tr>\ - <tr><td>Reflector Host:</td><td><div class="reflectorIp" /></td></tr>\ - <tr><td>Video Server:</td><td><div class="scxmlURL" /></td></tr>\ - <tr><td></td><td align="right"><div class="connectButton" /></td></tr>\ - </div>\ - '); - self.connectToolTip = new TooltipDialog({ content:self.connectDropDownContent, style:"max-height:320px"}); - self.connectDropDown = new DropDownButton({ label: "Connect", dropDown: self.connectToolTip }); - - // Connect parameters - self.problemNameBox = new TextBox({ - name: "problemName", - value: self.problemName, - style: "width: 100%", - onChange: function(){ - self.problemName = self.problemNameBox.get('value'); - } - - }); - dojo.query("div.problemName", self.connectToolTip.domNode)[0].appendChild(self.problemNameBox.domNode); - - self.emailBox = new TextBox({ - name: "email", - value: self.email, - style: "width: 100%", - onChange: function(){ - self.email = self.emailBox.get('value'); - } - }); - dojo.query("div.email", self.connectToolTip.domNode)[0].appendChild(self.emailBox.domNode); - - self.remoteEmailBox = new TextBox({ - name: "remoteEmail", - value: self.remoteEmail, - style: "width: 100%", - onChange: function(){ - self.remoteEmail = self.remoteEmailBox.get('value'); - } - }); - dojo.query("div.remoteEmail", self.connectToolTip.domNode)[0].appendChild(self.remoteEmailBox.domNode); - - self.reflectorIpBox = new TextBox({ - name: "self.reflectorIp", - value: self.reflectorIp, - style: "width: 100%", - onChange: function(){ - self.reflectorIp = self.reflectorIpBox.get('value'); - } - }); - dojo.query("div.reflectorIp", self.connectToolTip.domNode)[0].appendChild(self.reflectorIpBox.domNode); - - self.scxmlURLBox = new TextBox({ - name: "scxmlURL", - value: self.scxmlURL, - style: "width: 100%", - onChange: function(){ - self.scxmlURL = self.scxmlURLBox.get('value'); - } - }); - dojo.query("div.scxmlURL", self.connectToolTip.domNode)[0].appendChild(self.scxmlURLBox.domNode); - - self.connectButton = new Button({ - label: "Connect", - onClick: function(){ - self.connect(); - } - }); - dojo.query("div.connectButton", self.connectToolTip.domNode)[0].appendChild(self.connectButton.domNode); - - // Control parameters - self.controlDropDownContent = domConst.toDom('\ - <div>\ - <fieldset name="global">\ - <legend>Global Options</legend>\ - <table>\ - <tr><td>Activate Camera:</td><td><div class="activateCamera" /></td></tr>\ - <tr><td style="padding-left: 1em">Compression:</td><td><div class="videoCompression" /></td></tr>\ - <tr><td style="padding-left: 1em">Framerate:</td><td><div class="videoFramerate" /></td></tr>\ - <tr><td style="padding-left: 1em">Width:</td><td><div class="videoWidth" /></td></tr>\ - <tr><td style="padding-left: 1em">Height:</td><td><div class="videoHeight" /></td></tr>\ - <tr><td>Open Microphone:</td><td><div class="openMicrophone" /></td></tr>\ - <tr><td style="padding-left: 1em">Encoding:</td><td><div class="audioEncoding" /></td></tr>\ - </table>\ - </fieldset>\ - <fieldset name="session">\ - <legend>Session Options</legend>\ - <table>\ - <tr><td>Enable Audio:</td><td><div class="enableAudio" /></td></tr>\ - <tr><td>Show Video:</td><td><div class="showVideo" /></td></tr>\ - <tr><td></td><td align="right"><div class="disconnectButton" /></td></tr>\ - </table>\ - </fieldset>\ - </div>\ - '); - self.controlToolTip = new TooltipDialog({ content:self.controlDropDownContent, style:"max-height:320px"}); - self.controlDropDown = new DropDownButton({ label: "Session", dropDown: self.controlToolTip }); - - // Control parameters - - // global camera - topic.subscribe("miles/activateCamera", function(data) { - surpressPublication = true; - self.activateCameraCheckbox.set('value', data.activateCamera); - self.videoCompressionSelect.set('value', data.videoCompression); - self.videoFramerateSpinner.set('value', data.videoFramerate); - self.videoWidthSpinner.set('value', data.videoWidth); - self.videoHeightSpinner.set('value', data.videoHeight); - surpressPublication = false; - }); - - var publishCameraParameters = function() { - topic.publish("miles/activateCamera", { - "activateCamera": self.activateCamera, - "videoCompression": self.videoCompression, - "videoFramerate": self.videoFramerate, - "videoWidth": self.videoWidth, - "videoHeight": self.videoHeight - }); - // tell the server - if (activateCamera) { - var query = ""; - query += "?width=" + encodeURIComponent(self.videoWidth); - query += "&height=" + encodeURIComponent(self.videoHeight); - query += "&framerate=" + encodeURIComponent(self.videoFramerate); - query += "&compression=" + encodeURIComponent(self.videoCompression); - self.xhr.get({ - url: "http://" + self.scxmlURL + "/miles/sendvideo" + query, - error: function(err) { - console.log(err); - } - }); - } else { - self.xhr.get({ - url: "http://" + self.scxmlURL + "/miles/sendvideooff", - error: function(err) { - console.log(err); - } - }); - } - }; - - self.activateCameraCheckbox = new CheckBox({ - name: "activateCamera", - checked: self.activateCamera, - onChange: function() { - self.activateCamera = self.activateCameraCheckbox.get('value'); - if (!surpressPublication) - publishCameraParameters(); - } - }); - dojo.query("div.activateCamera", self.controlToolTip.domNode)[0].appendChild(self.activateCameraCheckbox.domNode); - - self.videoCompressionSelect = new Select({ - name: "videoCompression", - options: self.videoCompressions, - onChange: function() { - self.videoCompression = self.videoCompressionSelect.get('value'); - if (!surpressPublication) - publishCameraParameters(); - } - }); - dojo.query("div.videoCompression", self.controlToolTip.domNode)[0].appendChild(self.videoCompressionSelect.domNode); - - self.videoFramerateSpinner = new NumberSpinner({ - name: "videoFramerate", - value: self.videoFramerate, - style: "width: 50px", - onChange: function() { - self.videoFramerate = self.videoFramerateSpinner.get('value'); - if (!surpressPublication) - publishCameraParameters(); - } - }); - dojo.query("div.videoFramerate", self.controlToolTip.domNode)[0].appendChild(self.videoFramerateSpinner.domNode); - - self.videoWidthSpinner = new NumberSpinner({ - name: "videoWidth", - value: self.videoWidth, - style: "width: 50px", - onChange: function() { - self.videoWidth = self.videoWidthSpinner.get('value'); - if (!surpressPublication) - publishCameraParameters(); - } - }); - dojo.query("div.videoWidth", self.controlToolTip.domNode)[0].appendChild(self.videoWidthSpinner.domNode); - - self.videoHeightSpinner = new NumberSpinner({ - name: "videoHeight", - value: self.videoHeight, - style: "width: 50px", - onChange: function() { - self.videoHeight = self.videoHeightSpinner.get('value'); - if (!surpressPublication) - publishCameraParameters(); - } - }); - dojo.query("div.videoHeight", self.controlToolTip.domNode)[0].appendChild(self.videoHeightSpinner.domNode); - - // global microphone - topic.subscribe("miles/openMicrophone", function(data) { - surpressPublication = true; - self.openMicrophoneCheckbox.set('value', data.openMicrophone); - self.audioEncodingSelect.set('value', data.audioEncoding); - surpressPublication = false; - }); - - var publishMicrophoneParameters = function() { - topic.publish("miles/openMicrophone", { - "openMicrophone": openMicrophone, - "audioEncoding": audioEncoding - }); - // tell the server - if (openMicrophone) { - var query = ""; - query += "?encoding=" + encodeURIComponent(self.audioEncoding); - self.xhr.get({ - url: "http://" + self.scxmlURL + "/miles/sendaudio" + query, - error: function(err) { - console.log(err); - } - }); - } else { - self.xhr.get({ - url: "http://" + self.scxmlURL + "/miles/sendaudiooff", - error: function(err) { - console.log(err); - } - }); - } - } - - self.openMicrophoneCheckbox = new CheckBox({ - name: "openMicrophone", - value: self.openMicrophone, - checked: self.openMicrophone, - onChange: function() { - self.openMicrophone = self.openMicrophoneCheckbox.get('value'); - if (!surpressPublication) - publishMicrophoneParameters(); - } - }); - dojo.query("div.openMicrophone", self.controlToolTip.domNode)[0].appendChild(self.openMicrophoneCheckbox.domNode); - - self.audioEncodingSelect = new Select({ - name: "audioEncoding", - options: self.audioEncodings, - onChange: function() { - self.audioEncoding = self.audioEncodingSelect.get('value'); - if (!surpressPublication) - publishMicrophoneParameters(); - } - }); - dojo.query("div.audioEncoding", self.controlToolTip.domNode)[0].appendChild(self.audioEncodingSelect.domNode); - - - // session scoped parameters - self.enableAudioCheckbox = new CheckBox({ - name: "enableAudio", - value: self.enableAudio, - checked: self.enableAudio, - }); - dojo.query("div.enableAudio", self.controlToolTip.domNode)[0].appendChild(self.enableAudioCheckbox.domNode); - - self.showVideo = new CheckBox({ - name: "showVideo", - value: self.showVideo, - checked: self.showVideo, - }); - dojo.query("div.showVideo", self.controlToolTip.domNode)[0].appendChild(self.showVideo.domNode); - - self.disconnectButton = new Button({ - label: "Disconnect", - onClick: function(){ - self.disconnect(); - } - }); - dojo.query("div.disconnectButton", self.controlToolTip.domNode)[0].appendChild(self.disconnectButton.domNode); - - // intially append the connect dropdown - self.controlElem.appendChild(self.connectDropDown.domNode); - - }) - }); -} diff --git a/apps/samples/miles/miles.scxml b/apps/samples/miles/miles.scxml deleted file mode 100644 index 8281e9f..0000000 --- a/apps/samples/miles/miles.scxml +++ /dev/null @@ -1,170 +0,0 @@ -<scxml name="miles" datamodel="ecmascript"> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - <state id="main"> - <invoke type="miles" id="miles"> - <finalize> - <!-- <log label="out" expr="_event.name" /> --> - <script>//dump(_event);</script> - <if cond="_event.data.origin"> - <!-- <log label="Reply-length" expr="_event.data.base64.length" /> --> - <if cond="_event.name === 'thumbnail.reply'"> - <!-- <log expr="_event.data.image.base64().length" /> --> - <respond status="200" to="_event.data.origin"> - <header name="Cache-Control" value="no-cache" /> <!-- force IE to actually reload --> - <header name="Access-Control-Allow-Origin" value="*" /> - <header name="Content-Type" value="text/plain" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="_event.data.image.base64()" /> - </respond> - <else /> - <respond status="200" to="_event.data.origin"> - <header name="Cache-Control" value="no-cache" /> <!-- force IE to actually reload --> - <header name="Access-Control-Allow-Origin" value="*" /> - <!-- respond element will add content-type header --> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="_event.data" /> - </respond> - </if> - <else /> - <log label="Error" expr="'Event returned from invoker did not specify its origin for a reply'" /> - </if> - </finalize> - </invoke> - - <state id="idle"> - <!-- XHR CORS preflight respond --> - <transition event="http.options" target="idle"> - <respond status="200" to="_event.origin"> - <header name="Access-Control-Allow-Origin" value="*" /> <!-- request origins we allow --> - <header name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" /> <!-- http methods we allow --> - <header name="Access-Control-Allow-Headers" - value="X-Requested-With, X-Content-Encoding, Content-Type" /> <!-- headers we allow --> - </respond> - </transition> - - <transition event="http.get" target="idle"> - <!-- <log label="in" expr="_event.data.path" /> --> - <script>//dump(_event);</script> - <if cond="false"> - - <!-- START ############### --> - <elseif cond="_event.data.pathComponent[1] === 'start'" /> - <send target="#_miles" event="start"> - <param name="origin" expr="_event.origin" /> - <param name="reflector" expr="_event.data.query.reflector" /> - <param name="userid" expr="_event.data.query.userid" /> - <param name="session" expr="_event.data.query.session" /> - </send> - - <!-- STOP ############### --> - <elseif cond="_event.data.pathComponent[1] === 'stop'" /> - <send target="#_miles" event="stop"> - <param name="origin" expr="_event.origin" /> - <param name="reflector" expr="_event.data.query.reflector" /> - <param name="userid" expr="_event.data.query.userid" /> - <param name="session" expr="_event.data.query.session" /> - </send> - - <!-- PARTICIPANTS ############### --> - <elseif cond="_event.data.pathComponent[1] === 'participants'" /> - <send target="#_miles" event="participants"> - <param name="origin" expr="_event.origin" /> - </send> - - <!-- THUMBNAIL ############### --> - <elseif cond="_event.data.pathComponent[1] === 'thumbnail'" /> - <send target="#_miles" event="thumbnail"> - <param name="origin" expr="_event.origin" /> - <param name="userid" expr="_event.data.query.userid" /> - </send> - - <!-- VIDEO ON ############### --> - <elseif cond="_event.data.pathComponent[1] === 'videoon'" /> - <send target="#_miles" event="videoon"> - <param name="origin" expr="_event.origin" /> - <param name="userid" expr="_event.data.query.userid" /> - </send> - - <!-- VIDEO OFF ############### --> - <elseif cond="_event.data.pathComponent[1] === 'videooff'" /> - <send target="#_miles" event="videooff"> - <param name="origin" expr="_event.origin" /> - <param name="userid" expr="_event.data.query.userid" /> - </send> - - <!-- AUDIO ON ############### --> - <elseif cond="_event.data.pathComponent[1] === 'audioon'" /> - <send target="#_miles" event="audioon"> - <param name="origin" expr="_event.origin" /> - <param name="userid" expr="_event.data.query.userid" /> - </send> - - <!-- AUDIO OFF ############### --> - <elseif cond="_event.data.pathComponent[1] === 'videooff'" /> - <send target="#_miles" event="audiooff"> - <param name="origin" expr="_event.origin" /> - <param name="userid" expr="_event.data.query.userid" /> - </send> - - <!-- SEND VIDEO ############### --> - <elseif cond="_event.data.pathComponent[1] === 'sendvideo'" /> - <send target="#_miles" event="sendvideo"> - <param name="origin" expr="_event.origin" /> - <param name="width" expr="_event.data.query.width" /> - <param name="height" expr="_event.data.query.height" /> - <param name="framerate" expr="_event.data.query.framerate" /> - <param name="compression" expr="_event.data.query.compression" /> - </send> - - <!-- SEND VIDEO OFF ############### --> - <elseif cond="_event.data.pathComponent[1] === 'sendvideooff'" /> - <send target="#_miles" event="sendvideooff"> - <param name="origin" expr="_event.origin" /> - </send> - - <!-- SEND AUDIO ############### --> - <elseif cond="_event.data.pathComponent[1] === 'sendaudio'" /> - <send target="#_miles" event="sendaudio"> - <param name="origin" expr="_event.origin" /> - <param name="encoding" expr="_event.data.query.encoding" /> - </send> - - <!-- SEND AUDIO OFF ############### --> - <elseif cond="_event.data.pathComponent[1] === 'sendaudiooff'" /> - <send target="#_miles" event="sendaudiooff"> - <param name="origin" expr="_event.origin" /> - </send> - - <!-- GET TEXT ############### --> - <elseif cond="_event.data.pathComponent[1] === 'gettext'" /> - <send target="#_miles" event="gettext"> - <param name="origin" expr="_event.origin" /> - </send> - - <else /> - <respond status="404" to="_event.origin" /> - </if> - </transition> - - <transition event="http.post" target="idle"> - <!-- <log label="in" expr="_event.data.path" /> --> - <script>//dump(_event);</script> - <if cond="false"> - - <!-- POST TEXT ############### --> - <elseif cond="_event.data.pathComponent[1] === 'text'" /> - <send target="#_miles" event="posttext"> - <param name="origin" expr="_event.origin" /> - <param name="userid" expr="_event.data.content.userid" /> - <param name="message" expr="_event.data.content.message" /> - </send> - - <else /> - <respond status="404" to="_event.origin" /> - </if> - - </transition> - - </state> - </state> -</scxml> diff --git a/apps/samples/miles/test1.jpeg b/apps/samples/miles/test1.jpeg Binary files differdeleted file mode 100644 index 18c9517..0000000 --- a/apps/samples/miles/test1.jpeg +++ /dev/null diff --git a/apps/samples/miles/test2.jpeg b/apps/samples/miles/test2.jpeg Binary files differdeleted file mode 100644 index 7fb9cc0..0000000 --- a/apps/samples/miles/test2.jpeg +++ /dev/null diff --git a/apps/samples/miles/test3.jpeg b/apps/samples/miles/test3.jpeg Binary files differdeleted file mode 100644 index 6ed85b0..0000000 --- a/apps/samples/miles/test3.jpeg +++ /dev/null diff --git a/apps/samples/miles/test4.jpeg b/apps/samples/miles/test4.jpeg Binary files differdeleted file mode 100644 index 8a623f0..0000000 --- a/apps/samples/miles/test4.jpeg +++ /dev/null diff --git a/apps/samples/put-that-there/put-that-there.scxml b/apps/samples/put-that-there/put-that-there.scxml deleted file mode 100644 index 00865c4..0000000 --- a/apps/samples/put-that-there/put-that-there.scxml +++ /dev/null @@ -1,88 +0,0 @@ -<scxml datamodel="ecmascript" initial="start" binding="late" name="ptt" - xmlns="http://www.w3.org/2005/07/scxml" - xmlns:scenegraph="http://uscxml.tk.informatik.tu-darmstadt.de/scenegraph.xsd"> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - - <datamodel> - <data id="foo">This is foo!</data> - </datamodel> - - <state id="start"> - <invoke type="scenegraph"> - <content> - <scenegraph:display x="0" y="0" width="80%" height="80%"> - <scenegraph:viewport x="0" y="0" width="100%" height="100%" bgcolor="grey" id="scene1"> - <scenegraph:translation x="0" y="0" z="0"> - <scenegraph:sphere radius="1" materialcolor="1.0,1.0,0,0.3" /> - </scenegraph:translation> - <scenegraph:translation x="5" y="0" z="0"> - <scenegraph:box x="1" y="2" z="3" color="red" /> - </scenegraph:translation> - <scenegraph:translation x="0" y="5" z="0"> - <scenegraph:capsule radius="1" height="2" materialcolor="blue"/> - </scenegraph:translation> - <scenegraph:translation x="0" y="0" z="5"> - <scenegraph:cone radius="1" height="2" color="lightblue" /> - </scenegraph:translation> - <scenegraph:translation x="0" y="-5" z="0"> - <scenegraph:cylinder radius="1" height="2" color="orange" /> - </scenegraph:translation> - </scenegraph:viewport> - </scenegraph:display> - </content> - </invoke> - <state id="main"> - - <transition event="http" target="main" type="internal" - cond="_event.data.pathComponent[1] === 'basichttp' && - _event.data.pathComponent[2] === 'query'" > - <!-- a request for /ptt/basichttp/query --> - <script>dump(_event);</script> - <if cond="_event.data.header['X-XPath']"> - <script> - // a xpath query, evaluate, check for result and set reply on event - var nodes = document.evaluate(_event.data.header['X-XPath']); - if (nodes.asNodeSet().size > 0) { - _event.reply = nodes.asNodeSet()[0]; - } else { - _event.reply = "No nodes!"; - } - </script> - <elseif cond="_event.data.header['X-ECMAPath']" /> - <script> - // an ecmascript expression evaluate and set reply on event - _event.reply = eval(_event.data.header['X-ECMAPath']); - </script> - </if> - <send type="basichttp" targetexpr="_event.data.header['X-Reply-To']"> - <content expr="_event.reply" /> - </send> - </transition> - - <transition event="http" target="main" type="internal" - cond="_event.data.pathComponent[1] === 'query'" > - <!-- a request for /ptt/query --> - <script>dump(_event);</script> - <if cond="_event.data.header['X-XPath']"> - <script> - // a xpath query, evaluate, check for result and set reply on event - var nodes = document.evaluate(_event.data.header['X-XPath']); - if (nodes.asNodeSet().size > 0) { - _event.reply = nodes.asNodeSet()[0]; - } else { - _event.reply = "No nodes!"; - } - </script> - <elseif cond="_event.data.header['X-ECMAPath']" /> - <script> - // an ecmascript expression evaluate and set reply on event - _event.reply = eval(_event.data.header['X-ECMAPath']); - </script> - </if> - <respond to="_event.origin"> - <content expr="_event.reply" /> - </respond> - </transition> - </state> - </state> -</scxml> diff --git a/apps/samples/server-push/server-push.scxml b/apps/samples/server-push/server-push.scxml deleted file mode 100644 index c0f0a21..0000000 --- a/apps/samples/server-push/server-push.scxml +++ /dev/null @@ -1,82 +0,0 @@ -<!-- - Example for server-push with long-polling XMLHttpRequests. - Start in mmi-browser and connect http-browser via: - http://localhost:8080/push ---> - -<scxml name="push" datamodel="ecmascript"> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string. .js" /> - - <state id="main"> - <!-- We will only answer http requests when the heartbeat is emitted --> - <invoke type="heartbeat" id="heartbeat"> - <param name="interval" expr="'1s'" /> - </invoke> - <state id="idle"> - <!-- XHR CORS preflight response --> - <transition event="http.options" target="idle"> - <script>dump(_event);</script> - <respond status="200" to="_event.origin"> - <header name="Access-Control-Allow-Origin" value="*" /> - <header name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" /> - <header name="Access-Control-Allow-Headers" value="X-Requested-With, Content-Type" /> - </respond> - </transition> - - <transition event="http.post" target="idle"> - <if cond="_event.name. ('postponed')"> - <!-- This is an event we postponed before the heartbeat, respond --> - <respond to="_event.origin"> - <content>This is awesome!</content> - </respond> - <else /> - <!-- Postpone until the heartbeat is emitted and send all events again --> - <postpone until="_event.name == 'heartbeat.1s'" chaining="true" /> - </if> - </transition> - - <transition event="http.get"> - <respond to="_event.origin"> - <content> -<![CDATA[ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html> - <head> - <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> - <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js"></script> - - <script type="text/javascript"> - require(["dojo/domReady!", "dojo"], function(dom, dojo) { - var xhr = dojo.require("dojo/_base/xhr"); - var longpoll = function() { - xhr.post({ - // The URL to request - url: "http://localhost:8080/push/anywhere", - handleAs:"text", - headers:{ - "X-Requested-With": null, - "Content-Type": "application/json", - }, - load: function(result) { - dojo.byId("foo").innerHTML += result + "<br />"; - longpoll(); - } - }); - } - longpoll(); - }); - </script> - </head> - <body class="tundra"> - <div id="foo"></div> - </body> -</html> -]]> - </content> - </respond> - </transition> - - </state> - </state> -</scxml>
\ No newline at end of file diff --git a/apps/samples/vrml/README.md b/apps/samples/vrml/README.md deleted file mode 100644 index 2a019da..0000000 --- a/apps/samples/vrml/README.md +++ /dev/null @@ -1,150 +0,0 @@ -# VRML Server - -The VRML Server allows clients to retrieve sceneshots of 3D models on the filesystem in a variety of formats. - -## General Mode of Operation - -The VRML server will monitor its vrml directory recursively for <tt>vrml</tt> and <tt>wrl</tt> -files. Whenever such a file is found, it is converted into a native, binary representation and -saved in the tmp directory. Clients can now access sceneshots of this model by specifying the -desired pose and format. - -## Accessing Sceneshots - -In the simplest case, a sceneshot is retrieved by simply requested its respective URL on the VRML server: - -<tt>http://host/vrml/HARD_MP_VAL_000.png</tt> - -All paths start with vrml and then reflect the vrml directory structure as it is being monitored. When a directory -<tt>foo</tt> was added (either by creation or linking) in the vrml directory, its 3D models will be available at: - -<tt>http://host/vrml/foo/FANCY_MODEL_000.png</tt> - -When you do not pass any parameters, you will get a sceneshot of the model with its largest, axis aligned surface area -facing the camera. That is, the model will be rotated by multiples of 90deg to show the side of the bounding box which -has the largest surface area. The implied assumption is that this side is suited to identify the model and its eventual -problems the quickest. - -If you do not like the standard sceneshot, you can pass a couple of parameters to adapt most aspects of the scene: - -<table> - <tr><th>Name</th><th>Range</th><th>Description</th></tr> - <tr><td><tt>pitch</tt></td><td>[0 .. 2π] rad</td><td>Rotation along the x-axis</td></tr> - <tr><td><tt>roll</tt></td><td>[0 .. 2π] rad</td><td>Rotation along the z-axis</td></tr> - <tr><td><tt>yaw</tt></td><td>[0 .. 2π] rad</td><td>Rotation along the y-axis</td></tr> - <tr><td><tt>zoom</tt></td><td>[0 .. ∞] bounding-sphere units</td><td>Distance of camera to model center</td></tr> - <tr><td><tt>x</tt></td><td>[-∞ .. ∞] OpenGL units</td><td>Translation on x-axis</td></tr> - <tr><td><tt>y</tt></td><td>[-∞ .. ∞] OpenGL units</td><td>Translation on y-axis</td></tr> - <tr><td><tt>z</tt></td><td>[-∞ .. ∞] OpenGL units</td><td>Translation on z-axis (consider using zoom instead)</td></tr> - <tr><td><tt>width</tt></td><td>[0 .. BIG] pixels</td><td>The width of the image (limited by your GPU)</td></tr> - <tr><td><tt>height</tt></td><td>[0 .. BIG] pixels</td><td>The height of the image</td></tr> - <tr><td><tt>autorotate</tt></td><td>[<tt>on</tt> | <tt>off</tt>]</td><td>Whether or not to autorotate first</td></tr> -</table> - -<tt>http://host/vrml/HARD_MP_VAL_000.png?pitch=0.3&width=2560&height=1600</tt> - -There are some caveats: -<ul> - <li>With euler angles such as pitch/roll/yaw, a gimbal lock can occur. - <li>Choosing zoom, x, y or z to big will move the model off the clipping distance. - <li>width and height have no upper limit, this might be a potential DoS. - <li>When observing series of models with autorotating on, not every model is guaranteed to start with the same pose. - <li>The OpenGL units really ought to be expressed in multiples of bounding-sphere units. -</ul> - -## REST API - -The main purpose of the REST API is to provide clients with a list of available model files. - -<table> - <tr><th>Path</th><th>Type</th><th>Return Value</th><th>Example</th></tr> - <tr> - <td><tt>/vrml</tt></td> - <td><tt>GET</tt></td> - <td> - A JSON structure identifying all known models in the hierarchy as found on the filesystem.<br/> - - The entries are organized in a tree, reflecting the original locations relative to the vrml - directory. The suffix of <tt>png</tt> is just one example, supported extensions are ultimately - defined by the available <a href="http://www.link.de/here">OSG writer plugins</a>, but limited for - now to <tt>gif</tt>, <tt>jpg</tt>, <tt>png</tt>, <tt>tif</tt> and <tt>bmp</tt>. - </td> - <td> -<pre> -{ - "models": { - "HARD_MP_VAL_000": { - "path": "/HARD_MP_VAL_000.png", - "url": "http://host/vrml/HARD_MP_VAL_000.png" - }, - "HARD_MP_VAL_001": { - "path": "/HARD_MP_VAL_001.png", - "url": "http://host/vrml/HARD_MP_VAL_001.png" - }, - "data": { - "SOFT_MP_VAL_000": { - "path": "/data/SOFT_MP_VAL_000.png", - "url": "http://host/vrml/data/SOFT_MP_VAL_000.png" - }, - ... -</pre> - </td> - </tr> - - <tr> - <td><tt>/vrml/models</tt>, <tt>/vrml/wrls</tt></td> - <td><tt>GET</tt></td> - <td> - A JSON structure with information about the available binary model files in the tmp directory or the wrl - files in the vrml directory respectively.<br/> - - The entries correspond to the tree at <tt>/vrml</tt> but all paths are flattened using the path delimiter - ('<tt>:</tt>' per default). - </td> - <td> -<pre> -{ - "HARD_MP_VAL_000": { - "atime": 1363002503, - "ctime": 1362521747, - "dir": "/tmp", - "extension": "osgb", - "group": "/", - "mtime": "1362521747", - "name": "HARD_MP_VAL_000.osgb", - "path": "/tmp/HARD_MP_VAL_000.osgb", - "relDir": "/", - "relPath": "/HARD_MP_VAL_000.osgb", - "size": "580201", - "strippedName": "HARD_MP_VAL_000" - }, -... -</pre> - </td> - </tr> - - <tr> - <td><tt>/vrml/processed</tt></td> - <td><tt>GET</tt></td> - <td> - A JSON structure with information about the sceneshots that were requested recently and are still on disc.<br/> - - The individual entries within a model key encode the request parameters seperated by underscores, that is:<br/> - The euler angles <tt>pitch</tt>, <tt>roll</tt>, <tt>yaw</tt>, <tt>zoom</tt>, translation in <tt>x</tt>, translation - in <tt>y</tt>, translation in <tt>z</tt>, <tt>width</tt>, <tt>height</tt>, and whether or not to <tt>autorotate</tt>. - </td> - <td> - <pre> -{ - "HARD_MP_VAL_000": { - "0.94_0_0_1_0_0_0_640_480_on.png": { - "atime": 1363002687, - "ctime": 1363002687, - "dir": "/tmp", -... - </pre> - </td> - </tr> - - -</table> diff --git a/apps/samples/vrml/annotations.js b/apps/samples/vrml/annotations.js deleted file mode 100644 index b91ccfa..0000000 --- a/apps/samples/vrml/annotations.js +++ /dev/null @@ -1,70 +0,0 @@ -function Annotations(element, params) { - - // private attributes - var self = this; - var dojo = require("dojo"); - var domConst = dojo.require('dojo/dom-construct'); - var xhr = dojo.require("dojo/_base/xhr"); - - if (typeof(element) === 'string') { - element = dojo.byId(element); - } - - // private instanceId - if (!Annotations.instances) - Annotations.instances = 0; - var instanceId = Annotations.instances++; - - // public attributes - this.annotations = []; - this.vrmlViewer = params.viewer; - - // establish our dom - element.appendChild(domConst.toDom('\ - <div style="text-align: right"><div class="annotation" /></div><button type="button" class="annotate"></button></div>\ - <div class="messages"></div>\ - ')); - - this.annotationTextElem = dojo.query("div.annotation", element)[0]; - this.annotateButtonElem = dojo.query("button.annotate", element)[0]; - this.messagesElem = dojo.query("div.messages", element)[0]; - - // privileged public methods - this.annotate = function(text) { - var pose = dojo.clone(self.vrmlViewer.pose); - var imageURL = self.vrmlViewer.imageURL; - var annoLink = document.createElement("a"); - var annoText = document.createTextNode(text + "\n"); - annoLink.setAttribute("href", "#"); - annoLink.appendChild(annoText); - annoLink.onclick = function() { - self.vrmlViewer.setPose(imageURL, pose); - } - this.messagesElem.appendChild(annoLink); - } - - require(["dijit/form/TextBox"], function(TextBox) { - self.annotationBox = new TextBox({ - name: "Annotation", - style: "width: 70%", - onKeyDown: function(e) { - var code = e.keyCode || e.which; - if( code === 13 ) { - e.preventDefault(); - self.annotate(this.get("value")); - return false; - } - }, - }, self.annotationTextElem); - }); - - require(["dijit/form/Button"], function(Button) { - self.resetButton = new Button({ - label: "Annotate", - onClick: function(){ - self.annotate(self.annotationBox.get("value")); - } - }, self.annotateButtonElem); - }); - -} diff --git a/apps/samples/vrml/ffmpeg-server.invoked.scxml b/apps/samples/vrml/ffmpeg-server.invoked.scxml deleted file mode 100644 index 0c6449f..0000000 --- a/apps/samples/vrml/ffmpeg-server.invoked.scxml +++ /dev/null @@ -1,245 +0,0 @@ -<scxml datamodel="ecmascript"> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - - <script> -//<![CDATA[ - function clone(item) { - if (!item) { return item; } // null, undefined values check - - var types = [ Number, String, Boolean ], - result; - - // normalizing primitives if someone did new String('aaa'), or new Number('444'); - types.forEach(function(type) { - if (item instanceof type) { - result = type( item ); - } - }); - - if (typeof result == "undefined") { - if (Object.prototype.toString.call( item ) === "[object Array]") { - result = []; - item.forEach(function(child, index, array) { - result[index] = clone( child ); - }); - } else if (typeof item == "object") { - // testing that this is DOM - if (item.nodeType && typeof item.cloneNode == "function") { - var result = item.cloneNode( true ); - } else if (!item.prototype) { // check that this is a literal - if (item instanceof Date) { - result = new Date(item); - } else { - // it is an object literal - result = {}; - for (var i in item) { - result[i] = clone( item[i] ); - } - } - } else { - // depending what you would like here, - // just keep the reference, or create new object - if (false && item.constructor) { - // would not advice to do that, reason? Read below - result = new item.constructor(); - } else { - result = item; - } - } - } else { - result = item; - } - } - - return result; - } -//]]> - </script> - - <datamodel> - <data id="modelDir" /> - <data id="requests">{}</data> - </datamodel> - - <state id="start"> - <onentry> - <log expr="modelDir" /> - </onentry> - <invoke type="osgconvert" id="osgvonvert.frame"> - <param name="threads" expr="1" /> - <finalize> - <script> - requests[_event.data.context].job.renderedFrames++; - </script> - <!-- osgconverter will copy its send request for the reply so these are still available --> - <send target="#_ffmpeg" event="render.frame"> - <param name="frame" expr="_event.data.content.bmp" /> - <param name="context" expr="_event.data.context" /> - </send> - <if cond="requests[_event.data.context].job.renderedFrames >= requests[_event.data.context].job.totalFrames"> - <send target="#_ffmpeg" event="render.end"> - <param name="context" expr="_event.data.context" /> - </send> - </if> - </finalize> - </invoke> - - <invoke type="ffmpeg" id="ffmpeg"> - <finalize> - <script> -// dump(_event); - </script> - <send target="#_parent" event="render.done"> - <param name="context" expr="_event.data.context" /> - <param name="movie" expr="_event.data.movie" /> - <param name="mimetype" expr="_event.data.mimetype" /> - <param name="filename" expr="_event.data.filename" /> - </send> - <script> - // free up job in requests - requests[_event.data.context] = undefined; - </script> - - </finalize> - </invoke> - - <state id ="idle"> - <!-- <onentry> - <script> - print("Invokers:"); - dump(_invokers['ffmpeg']); - </script> - </onentry> --> - <transition event="http.post" target="idle" cond=" - _event.data.pathComponent.length == 2 && - _event.data.pathComponent[1] === 'movie'"> - <!-- - Something to encode just arrived. - Interpolate pose information and send each frame to the osg converter. - The finalize of the osgconverter will send the images to ffmpeg whose - finalize will trigger the response. - --> - <script> -//<![CDATA[ - dump(_event); - var pathDelim = ':'; // we need to flatten directories - this will seperate them in filenames - - // store event - var job = {}; - job.event = _event; - job.framesPerSec = 25; - job.lengthInSec = _event.data.content.data.movieLength; - job.format = _event.data.content.data.format; - job.height = _event.data.content.data.height; - job.width = _event.data.content.data.width; - job.keyFrames = _event.data.content.data.frames; - job.frames = []; - job.totalFrames = job.lengthInSec * job.framesPerSec - job.renderedFrames = 0; - - // sanitize - if (job.height % 2) - job.height++; - if (job.width % 2) - job.width++; - - // calculate overall relative length - var totalRelLength = 0; - for (var index in job.keyFrames) { - totalRelLength += job.keyFrames[index].relFrameLength; - } - var framesToRelLength = job.totalFrames / totalRelLength; - - // create frames - for (var kfIndex = 0; job.keyFrames[kfIndex]; kfIndex++) { - var nextPose = false; - if (job.keyFrames[kfIndex + 1]) { - nextPose = job.keyFrames[kfIndex + 1].pose; - } - var keyFrame = job.keyFrames[kfIndex]; - - keyFrame.file = keyFrame.imagePath.substr(1); - - keyFrame.modelFile = keyFrame.file + ".osgb"; - keyFrame.modelFile = keyFrame.modelFile.replace(/\//g, pathDelim); - keyFrame.modelFile = modelDir + '/' + keyFrame.modelFile; - - var currentPose = keyFrame.pose; - var thisFrames = Math.round(keyFrame.relFrameLength * framesToRelLength); - var startTransitionAt = Math.round((100 - keyFrame.relTransitionLength) * 0.01 * thisFrames); - var transitionFrames = thisFrames - startTransitionAt; - - //print("---------------------\n"); - //print("lengthInSec: " + job.lengthInSec + "\n"); - //print("totalFrames: " + job.totalFrames + "\n"); - //print("thisFrames for " + kfIndex + ": " + thisFrames + "\n"); - //print("startTransitionAt for " + kfIndex + ": " + startTransitionAt + "\n"); - //print("transitionFrames for " + kfIndex + ": " + transitionFrames + "\n"); - - for (var frameIndex = 0; frameIndex < thisFrames && job.frames.length <= job.totalFrames; frameIndex++) { - var frame = clone(keyFrame); - - if (frameIndex > startTransitionAt && nextPose) { - - var transitionProgress = (frameIndex - startTransitionAt) / transitionFrames; - frame.pose.pitch += (nextPose.pitch - frame.pose.pitch) * transitionProgress; - frame.pose.roll += (nextPose.roll - frame.pose.roll) * transitionProgress; - frame.pose.yaw += (nextPose.yaw - frame.pose.yaw) * transitionProgress; - frame.pose.x += (nextPose.x - frame.pose.x) * transitionProgress; - frame.pose.y += (nextPose.y - frame.pose.y) * transitionProgress; - frame.pose.z += (nextPose.z - frame.pose.z) * transitionProgress; - frame.pose.zoom += (nextPose.zoom - frame.pose.zoom) * transitionProgress; - - //print("#########################\n"); - //print("Transition at: " + frameIndex + " \ Progress: " + transitionProgress + "\n"); - //print("Interpolated pose:\n") - //dump(frame.pose); - } - - job.frames.push(frame); - } - } - job.totalFrames = job.frames.length; - requests[_event.origin] = {}; - requests[_event.origin].job = job; -//]]> - </script> - <send target="#_ffmpeg" event="render.start" idlocation="requests[_event.origin].sendId"> - <param name="context" expr="_event.origin" /> - <param name="format" expr="requests[_event.origin].job.format" /> - <param name="width" expr="requests[_event.origin].job.width" /> - <param name="height" expr="requests[_event.origin].job.height" /> - </send> - <foreach array="requests[_event.origin].job.frames" item="frame" index="index"> - <send target="#_osgvonvert.frame"> - <param name="format" expr="'bmp'" /> - <!-- param name="dest" expr="'/Users/sradomski/Desktop/ctrl/' + index + '.bmp'" / --> - <param name="source" expr="frame.modelFile" /> - <param name="pitch" expr="frame.pose.pitch" /> - <param name="roll" expr="frame.pose.roll" /> - <param name="yaw" expr="frame.pose.yaw" /> - <param name="zoom" expr="frame.pose.zoom" /> - <param name="x" expr="frame.pose.x" /> - <param name="y" expr="frame.pose.y" /> - <param name="z" expr="frame.pose.z" /> - <param name="width" expr="requests[_event.origin].job.width" /> - <param name="height" expr="requests[_event.origin].job.height" /> - <param name="autorotate" expr="frame.pose.autorotate" /> - <param name="context" expr="_event.origin" /> - </send> - </foreach> - </transition> - - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 3 && - _event.data.pathComponent[1] === 'movie' && - _event.data.pathComponent[2] === 'codecs'"> - <log expr="_invokers['ffmpeg']" /> - <send target="#_parent" event="send.codecs"> - <param name="context" expr="_event.origin" /> - <param name="codecs" expr="_invokers['ffmpeg']" /> - </send> - </transition> - </state> - </state> -</scxml>
\ No newline at end of file diff --git a/apps/samples/vrml/img/Tutorial.png b/apps/samples/vrml/img/Tutorial.png Binary files differdeleted file mode 100644 index 7f5a041..0000000 --- a/apps/samples/vrml/img/Tutorial.png +++ /dev/null diff --git a/apps/samples/vrml/img/Tutorial.pxm b/apps/samples/vrml/img/Tutorial.pxm Binary files differdeleted file mode 100644 index 682a00c..0000000 --- a/apps/samples/vrml/img/Tutorial.pxm +++ /dev/null diff --git a/apps/samples/vrml/img/close.png b/apps/samples/vrml/img/close.png Binary files differdeleted file mode 100644 index 7233cbe..0000000 --- a/apps/samples/vrml/img/close.png +++ /dev/null diff --git a/apps/samples/vrml/img/drag.png b/apps/samples/vrml/img/drag.png Binary files differdeleted file mode 100644 index b398a3f..0000000 --- a/apps/samples/vrml/img/drag.png +++ /dev/null diff --git a/apps/samples/vrml/img/drag2.png b/apps/samples/vrml/img/drag2.png Binary files differdeleted file mode 100644 index 4dfb651..0000000 --- a/apps/samples/vrml/img/drag2.png +++ /dev/null diff --git a/apps/samples/vrml/img/drag3.png b/apps/samples/vrml/img/drag3.png Binary files differdeleted file mode 100644 index 467ba6e..0000000 --- a/apps/samples/vrml/img/drag3.png +++ /dev/null diff --git a/apps/samples/vrml/img/pitchRoll-handle.png b/apps/samples/vrml/img/pitchRoll-handle.png Binary files differdeleted file mode 100644 index fcff0dd..0000000 --- a/apps/samples/vrml/img/pitchRoll-handle.png +++ /dev/null diff --git a/apps/samples/vrml/img/pitchRoll.png b/apps/samples/vrml/img/pitchRoll.png Binary files differdeleted file mode 100644 index 4f73745..0000000 --- a/apps/samples/vrml/img/pitchRoll.png +++ /dev/null diff --git a/apps/samples/vrml/img/pitchRoll.pxm b/apps/samples/vrml/img/pitchRoll.pxm Binary files differdeleted file mode 100644 index 1dbc3e2..0000000 --- a/apps/samples/vrml/img/pitchRoll.pxm +++ /dev/null diff --git a/apps/samples/vrml/img/pitchRoll3.png b/apps/samples/vrml/img/pitchRoll3.png Binary files differdeleted file mode 100644 index ede9247..0000000 --- a/apps/samples/vrml/img/pitchRoll3.png +++ /dev/null diff --git a/apps/samples/vrml/img/xy-handle.png b/apps/samples/vrml/img/xy-handle.png Binary files differdeleted file mode 100644 index 0edb8cc..0000000 --- a/apps/samples/vrml/img/xy-handle.png +++ /dev/null diff --git a/apps/samples/vrml/img/xy.png b/apps/samples/vrml/img/xy.png Binary files differdeleted file mode 100644 index fe081ee..0000000 --- a/apps/samples/vrml/img/xy.png +++ /dev/null diff --git a/apps/samples/vrml/img/xy.pxm b/apps/samples/vrml/img/xy.pxm Binary files differdeleted file mode 100644 index 5e077ef..0000000 --- a/apps/samples/vrml/img/xy.pxm +++ /dev/null diff --git a/apps/samples/vrml/img/xy2.png b/apps/samples/vrml/img/xy2.png Binary files differdeleted file mode 100644 index 2cc3f15..0000000 --- a/apps/samples/vrml/img/xy2.png +++ /dev/null diff --git a/apps/samples/vrml/img/yawZoom-handle.png b/apps/samples/vrml/img/yawZoom-handle.png Binary files differdeleted file mode 100644 index f6a54ee..0000000 --- a/apps/samples/vrml/img/yawZoom-handle.png +++ /dev/null diff --git a/apps/samples/vrml/img/yawZoom.png b/apps/samples/vrml/img/yawZoom.png Binary files differdeleted file mode 100644 index a256b3b..0000000 --- a/apps/samples/vrml/img/yawZoom.png +++ /dev/null diff --git a/apps/samples/vrml/img/yawZoom.pxm b/apps/samples/vrml/img/yawZoom.pxm Binary files differdeleted file mode 100644 index ec00b18..0000000 --- a/apps/samples/vrml/img/yawZoom.pxm +++ /dev/null diff --git a/apps/samples/vrml/stress-vrml-server.pl b/apps/samples/vrml/stress-vrml-server.pl deleted file mode 100755 index 4145f29..0000000 --- a/apps/samples/vrml/stress-vrml-server.pl +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/perl -w - -use Math::Round; - -my $pi = 3.14159; - -# make one thousand requests with random parameters -for (my $i = 0; $i < 1000; $i++) { - my $pitch = rand(2*$pi); - my $roll = rand(2*$pi); - my $yaw = rand(2*$pi); - my $width = rand(400) + 200; - my $height = rand(400) + 200; - my $url = "http://epikur.local:8080/vrml/HARD_MP_VAL_002.png". - "?pitch=".sprintf("%.3f",$pitch). - "&roll=".sprintf("%.3f",$roll). - "&yaw=".sprintf("%.3f",$yaw). - "&width=".sprintf("%.0f",$width). - "&height=".sprintf("%.0f",$height); - print $url."\n"; - `wget '$url'`; -} - -# for (my $pitch = 0; $pitch < 2*$pi; $pitch += 0.01) { -# for (my $roll = 0; $roll < 2*$pi; $roll += 0.01) { -# for (my $yaw = 0; $yaw < 2*$pi; $yaw += 0.01) { -# my $url = "http://epikur.local:8081/vrml/HARD_MP_VAL_002.png". -# "?pitch=".sprintf("%.3f",$pitch). -# "&roll=".sprintf("%.3f",$roll). -# "&yaw=".sprintf("%.3f",$yaw); -# print $url."\n"; -# `wget '$url'`; -# } -# } -# }
\ No newline at end of file diff --git a/apps/samples/vrml/viewer-webgl-setpose.js b/apps/samples/vrml/viewer-webgl-setpose.js deleted file mode 100644 index e2d3c6c..0000000 --- a/apps/samples/vrml/viewer-webgl-setpose.js +++ /dev/null @@ -1,1353 +0,0 @@ -// Define the namespace -// var eu_smartvorex_femkit_ui_modelviewer = eu_smartvorex_femkit_ui_modelviewer || {}; - -// eu_smartvorex_femkit_ui_modelviewer.VRMLViewer = function (element, params) { -VRMLViewer = function (element, params) { - element.innerHTML = "<div name='vrmlviewer'/>"; - - this.updatePose = function(pose) { - console.log("Updating pose."); - console.log("Pose = " + JSON.stringify(pose, null, 4)); - if (!pose.width) pose.width = self.pose.width; - if (!pose.height) pose.height = self.pose.height; - // this.setScene(this.imagePath, this.imageFormat, pose, this.serverURL); - }; - - // private attributes - var self = this; - var batchChanges = false; - var webGLManipulatorsSetup = false; - var currWebGLModel = ""; - - // private instanceId - // if (!eu_smartvorex_femkit_ui_modelviewer.VRMLViewer.instances) - // eu_smartvorex_femkit_ui_modelviewer.VRMLViewer.instances = 0; - // this.instanceId = eu_smartvorex_femkit_ui_modelviewer.VRMLViewer.instances++; - - if (!VRMLViewer.instances) - VRMLViewer.instances = 0; - this.instanceId = VRMLViewer.instances++; - - // public attribute defaults - this.width = 450; - this.height = 350; - - { - var pose = { - pitch: 0, - roll: 0, - yaw: 0, - zoom: 1, - x: 0, - y: 0, - z: 0, - autorotate: false, - }; - this.pose = pose; - } - - this.enableMovies = false; - this.enableDND = true; - this.enableWebGL = true; - this.enableSceneshots = false; - this.enableDraggables = false; - this.treeNavigationStyle = true; - this.listNavigationStyle = true; - this.listDirectory = ""; - - this.serverURL = "localhost:8080"; - this.imagePath = ""; - this.imageFormat = ".png"; - this.resRoot = ""; - - osg.setNotifyLevel(osg.ERROR); - - // copy over values from constructor arguments - if (params) { - for (var param in params) { - if (self.hasOwnProperty(param)) { - self[param] = params[param]; - } else { - console.log("Unknown paramter " + param); - } - } - } - - if (!self.pose.width) - self.pose.width = self.width; - if (!self.pose.height) - self.pose.height = self.height; - - var hasWebGL = function() { - try { - if (!window.WebGLRenderingContext) { - return false; - } - var canvas = document.createElement("canvas"); - var names = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"]; - for (var i = 0; i < 4; i++) { - var gl = canvas.getContext(names[i]); - if (gl) { - return true; - } - } - } catch(e) { - return false; - } - return false; - }; - - if (self.enableWebGL && !hasWebGL()) { - console.log("Your browser does no support WebGL, falling back to sceneshots"); - self.enableWebGL = false; - self.enableSceneshots = true; - } - - /** - * normalize given parameters - */ - var normalizeParams = function() { - // make sure server url begins with protocol and does *not* ends in / - if (!self.serverURL.substring(0, 7) == "http://" && - !self.serverURL.substring(0, 8) == "https://") - self.serverURL = "http://" + self.serverURL; - if (!self.serverURL.lastIndexOf("/") === self.serverURL.length) - self.serverURL += self.serverURL.substring(0, self.serverURL - 1); - - // make sure we have a listDirectory with navigation style list ending in / - if (self.modelNavigationStyle === "list" && !self.listDirectory && self.imagePath) - self.listDirectory = self.imagePath.substring(0, self.imagePath.lastIndexOf("/")); - if (!self.listDirectory.indexOf("/", self.listDirectory.length - 1) !== -1) - self.listDirectory += "/"; - - // use latest image if none given - if (!self.imagePath) - self.imagePath = self.listDirectory + "latest"; - - if (!self.imageFormat.substring(0, 1) !== ".") - self.imageFormat = "." + self.imageFormat; - }; - normalizeParams(); - - /** - * Fetch a remote WebGL model and return a future for it - */ - var getWebGLModel = function(url) { - console.log("Loading " + url); - if (self.webGLStandby) { self.webGLStandby.show(); } - var defer = osgDB.Promise.defer(); - var node = new osg.MatrixTransform(); - // node.setMatrix(osg.Matrix.makeRotate(-Math.PI/2, 1,0,0, [])); - var loadModel = function(url) { - osg.log("loading " + url); - var req = new XMLHttpRequest(); - req.open('GET', url, true); - req.onreadystatechange = function(aEvt) { - if (req.readyState == 4) { - if(req.status == 200) { - osgDB.Promise.when(osgDB.parseSceneGraph(JSON.parse(req.responseText))).then(function(child) { - - console.log("Loaded " + url); - - var rotate = []; - osg.Matrix.makeIdentity(rotate); - // osg.Matrix.preMult(rotate, osg.Matrix.makeRotate(Math.PI/2.0, 1,0,0,[])); - // osg.Matrix.preMult(rotate, osg.Matrix.makeRotate(Math.PI, 0,1,0,[])); - - node.setMatrix(rotate); - node.addChild(child); - defer.resolve(node); - osg.log("success " + url); - - }); - if (self.webGLStandby) { self.webGLStandby.hide(); } - } else { - osg.log("error " + url); - if (self.webGLStandby) { self.webGLStandby.hide(); } - } - } - }; - req.send(null); - }; - loadModel(url); - return defer.promise; - }; - - /** - * Concatenate pose as query string - */ - var urlSuffixForPose = function(pose) { - var queryString = - '?width=' + pose.width + - '&height=' + pose.height + - '&pitch=' + pose.pitch + - '&roll=' + pose.roll + - '&yaw=' + pose.yaw + - '&x=' + pose.x + - '&y=' + pose.y + - '&z=' + pose.z + - '&zoom=' + pose.zoom + - '&autorotate=' + (pose.autorotate ? '1' : '0'); - return queryString; - }; - - /** - * Get relative position of two elements - */ - var moverRelativeTo = function(mover, container) { - // see http://stackoverflow.com/questions/288699/get-the-position-of-a-div-span-tag - var absolutePosition = function(el) { - for (var lx=0, ly=0; el != null; lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent); - return {x: lx,y: ly}; - }; - - var containerPos = absolutePosition(container); - return { - x: mover.x - containerPos.x, - y: mover.y - containerPos.y - }; - }; - - var eulerToMatrix = function(pitch, roll, yaw) { - // see http://www.flipcode.com/documents/matrfaq.html#Q36 - var m = osg.Matrix.makeIdentity([]); - - var A = Math.cos(pitch); - var B = Math.sin(pitch); - var C = Math.cos(roll); - var D = Math.sin(roll); - var E = Math.cos(yaw); - var F = Math.sin(yaw); - var AD = A * D; - var BD = B * D; - - osg.Matrix.setRow(m, 0, (C * E), (-C * F), (-D), 0); - osg.Matrix.setRow(m, 1, (-BD * E + A * F), (BD * F + A * E), (-B * C), 0); - osg.Matrix.setRow(m, 2, (AD * E + B * F), (-AD * F + B * E), (A * C), 0); - osg.Matrix.setRow(m, 3, 0, 0, 0, 1); - - return m; - } - - var matrixToEuler = function(m) { - // see: http://www.flipcode.com/documents/matrfaq.html#Q37 - var angleX = 0; - var angleZ = 0; - var D = -1 * Math.asin(osg.Matrix.get(m,0,2)); /* Calculate Y-axis angle */ - var angleY = D; - var C = Math.cos(angleY); - - /* Gimbal lock? */ - if (Math.abs(C) > 0.005) { - var tr_x = osg.Matrix.get(m,2,2) / C; /* No, so get X-axis angle */ - var tr_y = -1 * osg.Matrix.get(m,1,2) / C; - angleX = Math.atan2( tr_y, tr_x ); - tr_x = osg.Matrix.get(m,0,0) / C; /* Get Z-axis angle */ - tr_y = -1 * osg.Matrix.get(m,0,1) / C; - angleZ = Math.atan2( tr_y, tr_x ); - } else { - /* Gimball lock has occurred */ - angleX = 0; /* Set X-axis angle to zero */ - var tr_x = osg.Matrix.get(m,1,1); /* And calculate Z-axis angle */ - var tr_y = osg.Matrix.get(m,1,0); - angleZ = Math.atan2( tr_y, tr_x ); - } - - /* Clamp all angles to range */ - return { - pitch: angleX % (2 * 3.14159), - roll: angleY % (2 * 3.14159), - yaw: angleZ % (2 * 3.14159) - }; - } - - // get list of supported ffmpeg codecs from server - this.populateMovieCodecs = function(server, selectElem) { - self.xhr.get({ - // The URL to request - url: server, - handleAs:"json", - headers:{"X-Requested-With":null}, - load: function(result) { - for (var codec in result.video) { - if (codec !== "mpeg1video" && - codec !== "mpeg2video" && - codec !== "mpeg4" && - codec !== "h264" && - codec !== "ayuv" && - codec !== "flashsv" && - codec !== "flashsv2" && - codec !== "flv" && - codec !== "rv40" && - codec !== "theora" && - codec !== "v210" && - codec !== "v308" && - codec !== "v408" && - codec !== "v410" && - codec !== "wmv3" && - codec !== "y41p" && - codec !== "yuv4") - continue; - // console.log(codec); - selectElem.options.push({ label: result.video[codec].longName, value: codec }); - if (codec === "mpeg4") - selectElem.options[selectElem.options.length - 1].selected = true; - } - } - }); - }; - - // update list of vrml files from server - this.refreshServer = function(server, params) { - if (!self.listNavigationStyle && !self.treeNavigationStyle) - return; - - self.serverURL = server; - if (!params) - params = {}; - if (self.fileStandby) { self.fileStandby.show(); } - - self.xhr.get({ - // The URL to request - url: server, - handleAs:"json", - headers:{"X-Requested-With":null}, - error: function(result) { - - if (self.browseButton) { self.browseButton.setAttribute('label', 'Browse'); } - if (self.fileStandby) { self.fileStandby.hide(); } - - if (!params.skipTree) { - if (self.fileTreeStore) { - var allItems = self.fileTreeStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileTreeStore.remove(allItems[i].id); - } - } - } - if (!params.skipList) { - if (self.fileListStore) { - var allItems = self.fileListStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileListStore.remove(allItems[i].id); - } - } - } - }, - load: function(result) { -// self.localStorage.put("vrmlServer", self.serverURL, null); - if (self.browseButton) { self.browseButton.setAttribute('label', 'Refresh'); } - if (self.fileStandby) { self.fileStandby.hide(); } - - if (self.treeNavigationStyle && !params.skipTree) { - // empty store - var allItems = self.fileTreeStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileTreeStore.remove(allItems[i].id); - } - - // parse result as tree - (function fillstore(tree, parentId) { - // todo: respect navigation style - for (key in tree) { - if ('url' in tree[key]) { - self.fileTreeStore.add({id:parentId+key, name:key, url:tree[key].path, parent:parentId}); - } else { - self.fileTreeStore.add({id:parentId+key, name:key, parent:parentId}); - fillstore(tree[key], parentId+key); - } - } - } (result.models, "root", "")); - } - if (self.listNavigationStyle && !params.skipList) { - - // empty store - var allItems = self.fileListStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileListStore.remove(allItems[i].id); - } - - // parse result as list - if (!self.listDirectory) - console.log("Requested modelNavigationStyle === list but provided no listDirectory"); - var dirs = self.listDirectory.split("/"); - var models = result.models; - for (var dir in dirs) { - if (!dirs[dir].length) - continue; - if (dirs[dir] in models) { - models = models[dirs[dir]]; - } else { - console.log("No " + dirs[dir] + " in " + models); - } - } - for (var key in models) { - var url = self.serverURL + models[key].path; - self.fileListStore.add({id:key, value:models[key].path, label:key, name:key, url:url}); - } - self.fileListSelect.startup(); - } - // self.updateScene(); - } - }); - }; - - this.getPose = function() { - if (self.webGLViewer && self.webGLViewer.getSceneData()) { - var rotate = []; - osg.Matrix.makeIdentity(rotate); - - osg.Matrix.preMult(rotate, osg.Matrix.makeRotate(Math.PI/2.0, 1,0,0,[])); - osg.Matrix.preMult(rotate, osg.Matrix.makeRotate(Math.PI, 0,1,0,[])); - osg.Matrix.postMult(self.webGLViewer.getSceneData().getMatrix(), rotate); - - var pose = matrixToEuler(rotate); - return pose; - } else { - return { - pitch: self.pose.pitch, - roll: self.pose.roll, - yaw: self.pose.yaw, - } - } - } - - this.setPose = function(pose) { - this.setScene(self.imagePath, self.imageFormat, pose, self.serverURL); - } - - this.setScene = function(imagePath, imageFormat, pose, serverURL) { - - if (serverURL && serverURL != self.serverURL) { - self.refreshServer(serverURL); - } - - self.imagePath = imagePath; - self.imageFormat = imageFormat; - - for (var key in pose) { - self.pose[key] = pose[key]; - } - - self.pose.pitch = (2 * 3.14159 + self.pose.pitch) % (2 * 3.14159); - self.pose.roll = (2 * 3.14159 + self.pose.roll) % (2 * 3.14159); - self.pose.yaw = (2 * 3.14159 + self.pose.yaw) % (2 * 3.14159); - - var pitch = (self.pose.pitch / (2 * 3.14159) + 0.5) * 100; - var roll = (self.pose.roll / (2 * 3.14159) + 0.5) * 100; - var yaw = (self.pose.yaw / (2 * 3.14159) + 0.5) * 100; - var x = ((self.pose.x / 100) + 0.5) * 100; - var y = ((self.pose.y / 100) + 0.5) * 100; - var zoom = (((self.pose.zoom - 1) / 3) + 0.5) * 100; - - // console.log("pitch: " + pitch); - - if (self.pitchRollHandlerElem) self.pitchRollHandlerElem.parentNode.style.right = pitch + "%"; - if (self.pitchRollHandlerElem) self.pitchRollHandlerElem.parentNode.style.top = roll + "%"; - if (self.yawZoomHandlerElem) self.yawZoomHandlerElem.parentNode.style.right = yaw + "%"; - if (self.yawZoomHandlerElem) self.yawZoomHandlerElem.parentNode.style.top = zoom + "%"; - if (self.xyHandlerElem) self.xyHandlerElem.parentNode.style.right = x + "%"; - if (self.xyHandlerElem) self.xyHandlerElem.parentNode.style.top = y + "%"; - - self.updateScene(); - }; - - // update the scene - this.updateScene = function() { - if (self.serverURL && self.imagePath && !self.batchChanges) { - // console.log(self.serverURL + self.imagePath + self.imageFormat + urlSuffixForPose(self.pose)); - - if (self.enableWebGL) { - var setWebGLPose = function() { - - // reset camera controls - self.webGLViewer.getManipulator().reset(); - self.webGLViewer.getManipulator().computeHomePosition(); - - var bs = self.webGLViewer.getSceneData().getBound(); - var zoom = 1; //self.pose.zoom || 10; - var eye = [0, 0, bs.radius() * (1.9 * zoom)]; - // var center = bs.center(); - // var up = [1,1,0]; - - self.webGLViewer.getManipulator().setEyePosition(eye); - - // var poseMatrix = eulerToMatrix(self.pose.pitch, self.pose.yaw, -1 * self.pose.roll); - var poseMatrix = eulerToMatrix(self.pose.pitch * -1, self.pose.roll * -1, self.pose.yaw); - - var rotate = []; - osg.Matrix.makeIdentity(rotate); - // osg.Matrix.preMult(rotate, osg.Matrix.makeRotate(Math.PI/2.0, 1,0,0,[])); - // osg.Matrix.preMult(rotate, osg.Matrix.makeRotate(Math.PI, 0,1,0,[])); - osg.Matrix.postMult(poseMatrix, rotate); - - // osg.Matrix.preMult(rotate, poseMatrix); - self.webGLViewer.getSceneData().setMatrix(rotate); - - } - - if (self.imagePath != currWebGLModel) { - currWebGLModel = self.imagePath; - osgDB.Promise.when(getWebGLModel(self.serverURL + self.imagePath + '.osgjs')).then(function(model) { - self.webGLViewer.setSceneData(model); - if (!webGLManipulatorsSetup) { - self.webGLViewer.setupManipulator(new osgGA.OrbitManipulator(), false); - self.webGLViewer.getManipulator().computeHomePosition(); - } - webGLManipulatorsSetup = true; - setWebGLPose(); - }); - } - if (self.webGLViewer && currWebGLModel == self.imagePath && self.webGLViewer.getSceneData()) { - setWebGLPose(); - } - } - if (self.enableSceneshots) { - self.imgElem.src = self.serverURL + self.imagePath + self.imageFormat + urlSuffixForPose(self.pose); - if (self.enableMovies && self.movieAddButton) { - // we are showing an image, activate movie controls - self.movieAddButton.domNode.style.display = ""; - self.movieDropDown.domNode.style.display = ""; - } - } - } - }; - - require(["dojo/dom-construct", - "dojo/_base/xhr", - "dojo/dom", - "dojo/on", - "dojo/_base/array", - "dojox/storage", - "dojo/store/Memory", - "dojo/store/Observable", - "dijit/tree/ObjectStoreModel", - "dojo/data/ObjectStore", - "dijit/Tree", - "dijit/form/TextBox", - "dijit/form/Button", - "dojox/widget/Standby", - "dijit/form/DropDownButton", - "dijit/TooltipDialog", - "dojo/dnd/Moveable", - "dojo/ready", - "dojo/dnd/Source", - "dijit/form/HorizontalSlider", - "dijit/form/Select", - "dijit/form/NumberSpinner"], - function(domConst, - xhr, - dom, - on, - array, - storage, - Memory, - Observable, - ObjectStoreModel, - ObjectStore, - Tree, - TextBox, - Button, - Standby, - DropDownButton, - TooltipDialog, - Moveable, - ready, - Source, - HorizontalSlider, - Selector, - NumberSpinner) { - - ready(function() { - - if (typeof(element) === 'string') { - element = dom.byId(element); - } - element.style.height = self.pose.height; - element.style.width = self.pose.width; - - self.element = element; - self.xhr = xhr; - - // establish our dom - element.appendChild(domConst.toDom('\ - <table>\ - <tr>\ - <td valign="top">\ - <div style="position: relative; padding: 0px; width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px">\ - <div class="screenShot" style="position: absolute; width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px">\ - <img class="screenShot" style="width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px"></img>\ - </div>\ - <div class="webGL" style="position: absolute; width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px">\ - <canvas class="webGL" style="width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px"></canvas>\ - </div>\ - <div style="z-index: -1; position: absolute; right: 45%; top: 45%">\ - <div class="progress"></div>\ - </div>\ - <div style="position: absolute; left: 10px; top: 10px">\ - <table></tr>\ - <td class="treeNavigation filesDropDown" style="vertical-align: middle"></td>\ - <td class="movieControls">\ - <div class="movieDropDown" style="display: inline"></div>\ - <button type="button" class="movieAddButton"></button>\ - </td>\ - <td align="right"><button type="button" class="resetButton"></button></td>\ - <td class="dndHandler" style="vertical-align: middle; padding-top: 4px;"></td>\ - </tr></table>\ - </div>\ - <div style="position: absolute; right: 10px; top: 15%; height: 50%">\ - <div class="zoomSlide"></div>\ - </div>\ - <div class="draggable" style="position: absolute; right: 50%; top: 50%">\ - <div class="pitchRollHandler" style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px;">\ - <table>\ - <tr>\ - <td><img class="pitchRollHandlerImg" src="' + self.resRoot + 'img/pitchRoll-handle.png" height="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="pitchLabel"></div><div class="rollLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - <div class="draggable"style="position: absolute; right: 50%; top: 50%">\ - <div class="yawZoomHandler">\ - <div style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px; position: absolute; left: -34px;">\ - <table>\ - <tr>\ - <td><img class="yawZoomHandlerImg" src="' + self.resRoot + 'img/yawZoom-handle.png" height="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="yawLabel"></div><div class="zoomLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - </div>\ - <div class="draggable"style="position: absolute; right: 50%; top: 50%">\ - <div class="xyHandler" style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px;">\ - <table>\ - <tr>\ - <td><img class="xyHandlerImg" src="' + self.resRoot + 'img/xy-handle.png" width="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="xLabel"></div><div class="yLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - <div class="listNavigation" style="position: absolute; left: 10px; bottom: 10px">\ - <table></tr>\ - <td style="vertical-align: middle"><button class="prevButton" type="button" /></td>\ - <td style="vertical-align: middle"><div class="fileList" /></td>\ - <td style="vertical-align: middle"><button class="nextButton" type="button" /></td>\ - </tr></table>\ - </div>\ - </div>\ - </td>\ - <td valign="top" height="100%">\ - </td>\ - </tr>\ - <tr>\ - <td colspan="2"><div class="messages"></div></td>\ - </tr>\ - </table>\ - ')); - - // fetch special dom nodes for content - self.messageBox = dojo.query("div.messages", element)[0]; - self.imgElem = dojo.query("img.screenShot", element)[0]; - - /** - * === WebGL ==================== - */ - var activateWebGL = function(enable) { - if (enable) { - self.canvasElem = dojo.query("canvas.webGL", element)[0]; - self.canvasElem.style.width = self.width; - self.canvasElem.style.height = self.height; - self.canvasElem.width = self.width; - self.canvasElem.height = self.height; - - if (self.webGLViewer === undefined) { - self.webGLViewer = new osgViewer.Viewer(self.canvasElem, {antialias : true, alpha: true }); - self.webGLViewer.init(); - self.webGLViewer.getCamera().setClearColor([0.0, 0.0, 0.0, 0.0]); - self.webGLViewer.setupManipulator(); - self.webGLViewer.run(); - - self.webGLStandby = new Standby({target: self.element }); - self.element.appendChild(self.webGLStandby.domNode); - } - - // show elements - array.forEach(dojo.query(".webGL", element), function(entry, i) { - entry.style.display = "inline"; - }); - } else { - if (self.webGLViewer) { - self.webGLViewer.stop(); - } - // hide elements - array.forEach(dojo.query(".webGL", element), function(entry, i) { - entry.style.display = "none"; - }); - } - }; - activateWebGL(self.enableWebGL); - - var activateScreenshot = function(enable) { - if (enable) { - array.forEach(dojo.query(".screenShot", element), function(entry, i) { - entry.style.display = "inline"; - }); - } else { - array.forEach(dojo.query(".screenShot", element), function(entry, i) { - entry.style.display = "none"; - }); - } - }; - activateScreenshot(self.enableSceneshots); - - - /** - * === POSE MANIPULATION AND RESET ==================== - */ - self.resetButtonElem = dojo.query("button.resetButton", element)[0]; - self.resetButton = new Button({ - label: "Reset", - onClick: function() { - if (self.webGLViewer) { - self.webGLViewer.setupManipulator(); - self.webGLViewer.getManipulator().computeHomePosition(); - } - self.pose.x = 0; - self.pose.y = 0; - self.pose.pitch = 0; - self.pose.roll = 0; - self.pose.yaw = 0; - self.pose.zoom = 1; - - if (self.xyHandler) self.xyHandler.node.style.left = 0; - if (self.xyHandler) self.xyHandler.node.style.top = 0; - if (self.pitchRollHandler) self.pitchRollHandler.node.style.left = 0; - if (self.pitchRollHandler) self.pitchRollHandler.node.style.top = 0; - if (self.yawZoomHandler) self.yawZoomHandler.node.style.left = 0; - if (self.yawZoomHandler) self.yawZoomHandler.node.style.top = 0; - - self.updateScene(); - } - }, self.resetButtonElem); - - var activateDraggables = function(enable) { - if (enable) { - if (self.pitchRollHandler == undefined) { - self.progressElem = dojo.query("div.progress", element)[0]; - - self.pitchRollHandlerElem = dojo.query(".pitchRollHandler", element)[0]; - self.yawZoomHandlerElem = dojo.query(".yawZoomHandler", element)[0]; - self.xyHandlerElem = dojo.query(".xyHandler", element)[0]; - - self.pitchRollHandler = new Moveable(self.pitchRollHandlerElem); - self.pitchRollHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.pitchRollHandlerImg", mover.node)[0]; - var pitchLabel = dojo.query("div.pitchLabel", mover.node)[0]; - var rollLabel = dojo.query("div.rollLabel", mover.node)[0]; - pitchLabel.innerHTML = ''; - rollLabel.innerHTML = ''; - self.updateScene(); - }; - self.pitchRollHandler.onMoving = function(mover) { - var handlerImg = dojo.query(".pitchRollHandlerImg", mover.node)[0]; - var pitchLabel = dojo.query(".pitchLabel", mover.node)[0]; - var rollLabel = dojo.query(".rollLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 30; - offset.y += 20; - - self.xyHandlerElem.style.zIndex = 1; - self.yawZoomHandlerElem.style.zIndex = 1; - self.pitchRollHandlerElem.style.zIndex = 2; - - self.pose.roll = offset.x / self.pose.width - 0.5; - self.pose.pitch = offset.y / self.pose.height - 0.5; - self.pose.pitch *= -1; - self.pose.roll *= 2 * 3.14159; - self.pose.pitch *= 2 * 3.14159; - self.pose.roll = Math.ceil((self.pose.roll) * 10) / 10; - self.pose.pitch = Math.ceil((self.pose.pitch) * 10) / 10; - pitchLabel.innerHTML = 'Pitch:' + self.pose.pitch; - rollLabel.innerHTML = 'Roll:' + self.pose.roll; - }; - - self.yawZoomHandler = new Moveable(self.yawZoomHandlerElem); - self.yawZoomHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.yawZoomHandlerImg", mover.node)[0]; - var yawLabel = dojo.query("div.yawLabel", mover.node)[0]; - var zoomLabel = dojo.query("div.zoomLabel", mover.node)[0]; - yawLabel.innerHTML = ''; - zoomLabel.innerHTML = ''; - self.updateScene(); - }; - self.yawZoomHandler.onMoving = function(mover) { - var handlerImg = dojo.query("img.yawZoomHandlerImg", mover.node)[0]; - var yawLabel = dojo.query("div.yawLabel", mover.node)[0]; - var zoomLabel = dojo.query("div.zoomLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 7; - offset.y += 9; - - self.xyHandlerElem.style.zIndex = 1; - self.yawZoomHandlerElem.style.zIndex = 2; - self.pitchRollHandlerElem.style.zIndex = 1; - - // self.pose.pitch = self.pose.pitch % (2 * 3.14159); - // self.pose.roll = self.pose.roll % (2 * 3.14159); - self.pose.yaw = (self.pose.width - offset.x) / self.pose.width - 0.5; - self.pose.zoom = offset.y / self.pose.height - 0.5; - self.pose.yaw *= 2 * 3.14159; - self.pose.zoom = self.pose.zoom * 3 + 1; - self.pose.zoom = Math.ceil((self.pose.zoom) * 10) / 10; - self.pose.yaw = Math.ceil((self.pose.yaw) * 10) / 10; - yawLabel.innerHTML = 'Yaw:' + self.pose.yaw; - zoomLabel.innerHTML = 'Zoom:' + self.pose.zoom; - }; - - self.xyHandler = new Moveable(self.xyHandlerElem); - self.xyHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.xyHandlerImg", mover.node)[0]; - var xLabel = dojo.query("div.xLabel", mover.node)[0]; - var yLabel = dojo.query("div.yLabel", mover.node)[0]; - - xLabel.innerHTML = ''; - yLabel.innerHTML = ''; - - self.updateScene(); - }; - self.xyHandler.onMoving = function(mover) { - var handlerImg = dojo.query("img.xyHandlerImg", mover.node)[0]; - var xLabel = dojo.query("div.xLabel", mover.node)[0]; - var yLabel = dojo.query("div.yLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 3; - offset.y += 13; - - self.xyHandlerElem.style.zIndex = 2; - self.yawZoomHandlerElem.style.zIndex = 1; - self.pitchRollHandlerElem.style.zIndex = 1; - - self.pose.x = offset.x / self.pose.width - 0.5; - self.pose.y = offset.y / self.pose.height - 0.5; - self.pose.x *= 100; - self.pose.y *= 100; - self.pose.y = Math.ceil((self.pose.y) * 10) / 10; - self.pose.x = Math.ceil((self.pose.x) * 10) / 10; - xLabel.innerHTML = 'X:' + self.pose.x; - yLabel.innerHTML = 'Y:' + self.pose.y; - }; - } - - // show all draggables - array.forEach(dojo.query(".draggable", element), function(entry, i) { - entry.style.display = "inline"; - }); - - } else { - // show all draggables - array.forEach(dojo.query(".draggable", element), function(entry, i) { - entry.style.display = "none"; - }); - } - }; - activateDraggables(self.enableDraggables); - - /** - * === DRAG HANDLER ==================== - */ - var activateDND = function(enable) { - if (enable) { - self.createAvatar = function(item, mode) { - if (mode == 'avatar') { - // create your avatar if you want - var avatar = dojo.create( 'div', { innerHTML: item.data }); - var avatarPose = dojo.clone(self.pose); - avatarPose.width=60; - avatarPose.height=60; - var avatarImgUrl = urlSuffixForPose(avatarPose); - avatar.innerHTML = '<img src=' + self.serverURL + self.imagePath + self.imageFormat + avatarImgUrl + ' /> '; - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.serverURL + self.imagePath + self.imageFormat + avatarImgUrl; - item.imagePath = self.imagePath; - item.imageFormat = self.imageFormat; - item.serverURL = self.serverURL; - item.pose = avatarPose; - return {node: avatar, data: item, type: item.type}; - } - var handler = dojo.create( 'div', { innerHTML: '<img src="' + self.resRoot + 'img/drag.png" width="20px" />' }); - return {node: handler, data: item, type: item.type}; - }; - - self.dndHandler = new Source(dojo.query("td.dndHandler", element)[0], {copyOnly: true, creator: self.createAvatar}); - self.dndHandler.insertNodes(false, [ { } ]); - - array.forEach(dojo.query(".dndHandler", element), function(entry, i) { - entry.style.display = "inline"; - }); - - } else { - array.forEach(dojo.query(".dndHandler", element), function(entry, i) { - entry.style.display = "none"; - }); - - } - }; - - activateDND(self.enableDND); - - /** - * === FILE NAVIGATION ==================== - */ - - var activateListNavigation = function(enable) { - if (enable) { - array.forEach(dojo.query(".listNavigation", element), function(entry, i) { - entry.style.display = "inline"; - }); - - if (!self.fileListStore) { - // setup fileStore - self.fileListStore = new Observable(new Memory({ - data: [], - })); - - self.prevButtonElem = dojo.query("button.prevButton", element)[0]; - self.nextButtonElem = dojo.query("button.nextButton", element)[0]; - self.fileListElem = dojo.query("div.fileList", element)[0]; - - self.fileListSelect = new Selector({ - store: new ObjectStore({ objectStore: self.fileListStore }), - onChange: function(name) { - var item = self.fileListStore.query({ id: name })[0]; - self.imagePath = self.listDirectory + item.name; - self.updateScene(); - } - }, self.fileListElem); - - self.prevButton = new Button({ - label: "<", - onClick: function() { - var allItems = self.fileListStore.query(); - var foundAt = 0; - for (var i = 0; i < allItems.total; i++) { - console.log(self.serverURL + self.imagePath + " === " + allItems[i].url); - if (self.serverURL + self.imagePath === allItems[i].url) { - foundAt = i; - break; - } - } - - if (foundAt > 0) { - self.imagePath = self.listDirectory + allItems[foundAt - 1].name; - self.fileListSelect.attr( 'value', allItems[foundAt - 1].id ); - if (self.serverURL + self.imagePath !== allItems[foundAt - 1].url) - console.log(self.serverURL + self.imagePath + " !== " + allItems[foundAt - 1].url); - self.updateScene(); - } - } - }, self.prevButtonElem); - - self.nextButton = new Button({ - label: ">", - onClick: function() { - var allItems = self.fileListStore.query(); - var foundAt = 0; - for (var i = 0; i < allItems.total; i++) { - // console.log(self.serverURL + self.imagePath + " === " + allItems[i].url); - if (self.serverURL + self.imagePath === allItems[i].url) { - foundAt = i; - break; - } - } - if (foundAt + 1 < allItems.total) { - self.imagePath = self.listDirectory + allItems[foundAt + 1].name + ".png"; - self.fileListSelect.attr( 'value', allItems[foundAt + 1].id ); - if (self.serverURL + self.imagePath !== allItems[foundAt + 1].url) - console.log(self.serverURL + self.imagePath + " !== " + allItems[foundAt + 1].url); - self.updateScene(); - } - } - }, self.nextButtonElem); - } - } else { - array.forEach(dojo.query(".listNavigation", element), function(entry, i) { - entry.style.display = "none"; - }); - } - }; - activateListNavigation(self.listNavigationStyle); - - var activateTreeNavigation = function(enable) { - if (enable) { - - array.forEach(dojo.query(".treeNavigation", element), function(entry, i) { - entry.style.display = ""; - }); - - if (!self.fileTreeStore) { - // setup fileStore - self.fileTreeStore = new Observable(new Memory({ - data: [ { id: 'root', name:'3D Models'} ], - getChildren: function(object){ - return this.query({parent: object.id}); - } - })); - - self.fileTreeModel = new ObjectStoreModel({ - store: self.fileTreeStore, - query: { id: "root" } - }); - - // setup actual tree dijit - self.fileTree = new dijit.Tree({ - id: "fileTree" + self.instanceId, - model: self.fileTreeModel, - persist: false, - showRoot: false, - style: "height: 300px;", - onClick: function(item){ - if ('url' in item) { - self.imagePath = item.url; - var newListDir = self.imagePath.substring(0, self.imagePath.lastIndexOf("/")); - if (newListDir.length > 0) - newListDir += '/'; - if (newListDir !== self.listDirectory) { - self.listDirectory = newListDir; - self.refreshServer(self.serverURL, { skipTree: true }); - } - self.updateScene(); - } - }, - getIconClass: function(item, opened) { - return (!item || !('url' in item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"; - }, - getIconStyle: function(item, opened){ - if('url' in item) { - return { backgroundImage: "url('" + self.serverURL + item.url + self.imageFormat + "?width=16&height=16')"}; - } - } - }); - - self.filesDropDownElem = dojo.query("td.filesDropDown", element)[0]; - - self.serverBox = new TextBox({ - name: "Server", - value: self.serverURL, - style: "width: 65%", - - onKeyUp: function(e) { - if (self.browseButton) { - if (this.get("value") !== self.serverURL) { - self.browseButton.setAttribute('label', 'Browse'); - } else { - self.browseButton.setAttribute('label', 'Refresh'); - } - } - }, - - onKeyDown: function(e) { - var code = e.keyCode || e.which; - if( code === 13 ) { - e.preventDefault(); - self.refreshServer(this.get("value")); - return false; - } - }, - }); - - self.browseButton = new Button({ - label: "Browse", - onClick: function(){ - self.refreshServer(self.serverBox.get("value")); - } - }); - - self.filesDropDownContent = domConst.toDom('<div />'); - self.filesDropDownContent.appendChild(self.serverBox.domNode); - self.filesDropDownContent.appendChild(self.browseButton.domNode); - self.filesDropDownContent.appendChild(self.fileTree.domNode); - - self.filesToolTip = new TooltipDialog({ content:self.filesDropDownContent, style:"max-height:320px"}); - self.filesDropDown = new DropDownButton({ label: "Files", dropDown: self.filesToolTip }); - self.filesDropDownElem.appendChild(self.filesDropDown.domNode); - - self.fileStandby = new Standby({target: self.filesDropDownContent }); - self.filesDropDownContent.appendChild(self.fileStandby.domNode); - } - } else { - array.forEach(dojo.query(".treeNavigation", element), function(entry, i) { - entry.style.display = "none"; - }); - } - }; - - activateTreeNavigation(self.treeNavigationStyle); - - /** - * === MOVIE DROPDOWN ==================== - */ - - var activateMovies = function(enable) { - if (enable) { - self.movieDropDownElem = dojo.query("div.movieDropDown", element)[0]; - self.movieAddButtonElem = dojo.query("button.movieAddButton", element)[0]; - - self.movieDropDownContent = domConst.toDom( - '<div style="overflow: auto; max-height: 420px;"> \ - <table><tr class="movieFormatLengthRow" /></tr><tr class="movieWidthHeightLengthRow" /></table> \ - <div class=\"dndArea\" /> \ - </div>' - ); - - self.movieFormatLengthRowElem = dojo.query("tr.movieFormatLengthRow", self.movieDropDownContent)[0]; - self.movieWidthHeightLengthRowElem = dojo.query("tr.movieWidthHeightLengthRow", self.movieDropDownContent)[0]; - self.movieDnDArea = dojo.query("div.dndArea", self.movieDropDownContent)[0]; - - self.createMovieThumb = function(item, mode) { - if (mode == 'avatar') { - // when dragged - var avatar = dojo.create( 'div', { innerHTML: item.data }); - var avatarPose = dojo.clone(self.pose); - avatarPose.width = 60; - avatarPose.height = 60; - var avatarImgUrl = urlSuffixForPose(avatarPose); - avatar.innerHTML = '<img src=' + self.imagePath + self.imageFormat + avatarImgUrl + ' /> '; - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.imagePath + avatarImgUrl; - item.imagePath = self.imagePath; - item.serverURL = self.serverURL; - item.pose = avatarPose; - return {node: avatar, data: item, type: item.type}; - } else { - - // when added to list - var thumb = domConst.toDom("\ - <div>\ - <table><tr><td>\ - <img class=\"movieThumb\"/>\ - <img class=\"removeThumb\" style=\"vertical-align: top; margin: -3px 0px 0px -8px; width: 20px; height: 20px;\"/>\ - </td><td align=\"left\">\ - <table><tr>\ - <td>Frame:</td><td><div class=\"relFrameLength\"/></td>\ - <td><div class=\"fillInSeries\" \></td>\ - </tr><tr>\ - <td>Transition:</td><td><div class=\"relTransitionLength\"/></td>\ - </tr></table>\ - </td></tr></table>\ - </div>\ - "); - thumb = dojo.query("div", thumb)[0]; - - var thumbImgElem = dojo.query("img.movieThumb", thumb)[0]; - var removeImgElem = dojo.query("img.removeThumb", thumb)[0]; - var relFrameLengthElem = dojo.query("div.relFrameLength", thumb)[0]; - var relTransitionLengthElem = dojo.query("div.relTransitionLength", thumb)[0]; - var fillInSeriesElem = dojo.query("div.fillInSeries", thumb)[0]; - - item.getThisAndNeighborsFromDnD = function() { - var thisAndNeighbors = {}; - self.addToMovieHandler.forInItems(function(obj, key, ctx) { - if (obj.data === item) { - thisAndNeighbors.this = { key: key, obj: obj }; - } else { - thisAndNeighbors.before = { key: key, obj: obj }; - } - if (thisAndNeighbors.this) { - thisAndNeighbors.after = { key: key, obj: obj }; - return thisAndNeighbors; - } - }); - return thisAndNeighbors; - }; - - item.relFrameLengthSlider = new HorizontalSlider({ - value: 50, - title: "Relative Duration of Frame", - style: "width:150px;" - }, relFrameLengthElem); - - item.relTransitionLengthSlider = new HorizontalSlider({ - value: 100, - title: "Relative Duration of Transition", - style: "width:150px;" - }, relTransitionLengthElem); - - removeImgElem.onclick = function() { - var thisItem = item.getThisAndNeighborsFromDnD(); - if (thisItem.this) { - // haha - what a mess! - self.addToMovieHandler.selectNone(); - self.addToMovieHandler.selection[thisItem.this.key] = thisItem.this.obj; - self.addToMovieHandler.deleteSelectedNodes(); - } - // disable create button if this was the last one - if (!thisItem.after || !thisItem.before) { - self.movieCreateButton.setAttribute('disabled', true); - } - } - - item.fillInSeriesButton = new Button({ - label: "Insert Series", - style: "display: none;", - onClick: function(){ - alert("foo"); - } - }, fillInSeriesElem); - - removeImgElem.src = self.resRoot + "img/close.png"; - - var thumbPose = dojo.clone(self.pose); - thumbPose.width = self.pose.width / 10; - thumbPose.height = self.pose.height / 10; - var thumbImgUrl = urlSuffixForPose(thumbPose); - - thumbImgElem.src = self.serverURL + self.imagePath + self.imageFormat + thumbImgUrl; - // removeImgElem.src = self.resRoot + 'img/close.png'; - - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.imagePath + thumbImgUrl; - item.imagePath = self.imagePath; - item.serverURL = self.serverURL; - item.pose = thumbPose; - - return {node: thumb, data: item, type: item.type}; - } - }; - - self.addToMovieHandler = new Source(self.movieDnDArea, {copyOnly: true, creator: self.createMovieThumb}); - - self.movieFormatSelection = new Selector({ - name: "movieFormat", - style: "width: 320px", - options: [] - }); - self.populateMovieCodecs(self.serverURL + '/movie/codecs', self.movieFormatSelection); - - self.movieFormatLengthRowElem.appendChild(dojo.create('td', { innerHTML: 'Format:'} )); - self.movieFormatLengthRowElem.appendChild(dojo.create('td', { colspan: "2"})); - self.movieFormatLengthRowElem.lastChild.appendChild(self.movieFormatSelection.domNode); - - self.movieHeightSpinner = new NumberSpinner({ - value: 400, - smallDelta: 1, - style: "width: 60px", - constraints: { min:40, places:0 }, - }); - - self.movieWidthSpinner = new NumberSpinner({ - value: 600, - smallDelta: 1, - style: "width: 60px", - constraints: { min:40, places:0 }, - }); - - self.movieCreateButton = new Button({ - label: "Create", - disabled: true, - onClick: function(){ - - var form = document.createElement("form"); - - form.setAttribute("method", "post"); - form.setAttribute("action", self.serverURL + "/movie"); - - var submitData = {}; - submitData.frames = []; - submitData.movieLength = self.movieDurationSpinner.value; - submitData.format = self.movieFormatSelection.value; - submitData.width = self.movieWidthSpinner.value; - submitData.height = self.movieHeightSpinner.value; - - self.addToMovieHandler.forInItems(function(obj, key, ctx) { - var jsonData = { - iconPoseUrl: obj.data.iconPoseUrl, - imagePath: obj.data.imagePath, - serverURL: obj.data.serverURL, - pose: obj.data.pose, - relFrameLength: obj.data.relFrameLengthSlider.value, - relTransitionLength: obj.data.relTransitionLengthSlider.value, - } - submitData.frames.push(jsonData); - }); - - var hiddenField = document.createElement("input"); - hiddenField.setAttribute("type", "hidden"); - hiddenField.setAttribute("name", "data"); - hiddenField.setAttribute("value", JSON.stringify(submitData)); - - form.appendChild(hiddenField); - - document.body.appendChild(form); - form.submit(); - document.body.removeChild(form); - } - }); - - self.movieDurationSpinner = new NumberSpinner({ - value: 10, - smallDelta: 1, - style: "width: 40px", - constraints: { min:0, places:0 }, - }); - - // append format duration cell - self.movieWidthHeightLengthRowElem.appendChild(dojo.create('td', { innerHTML: 'Size:'} )); - var movieDimensionCell = dojo.create('td'); - movieDimensionCell.appendChild(self.movieWidthSpinner.domNode); - movieDimensionCell.appendChild(dojo.create('span', { innerHTML: "x"} )); - movieDimensionCell.appendChild(self.movieHeightSpinner.domNode); - movieDimensionCell.appendChild(self.movieDurationSpinner.domNode); - movieDimensionCell.appendChild(dojo.create('span', { innerHTML: "sec"} )); - self.movieWidthHeightLengthRowElem.appendChild(movieDimensionCell); - - self.movieWidthHeightLengthRowElem.appendChild(dojo.create('td', { align: "right"})); - self.movieWidthHeightLengthRowElem.lastChild.appendChild(self.movieCreateButton.domNode); - - - self.movieToolTip = new TooltipDialog({ content:self.movieDropDownContent }); - self.movieDropDown = new DropDownButton({ - label: "Movie", - style: "display: none;", - dropDown: self.movieToolTip }); - self.movieDropDownElem.appendChild(self.movieDropDown.domNode); - - self.movieAddButton = new Button({ - label: "+", - style: "margin-left: -10px; display: none;", - onClick: function(){ - if (self.movieFormatSelection.options.length == 0) { - self.populateMovieCodecs(self.serverURL + '/movie/codecs', self.movieFormatSelection); - } - // we could pass item.data here to creator - self.addToMovieHandler.insertNodes(false, [ { } ]); - self.movieCreateButton.setAttribute('disabled', false); - - } - }, self.movieAddButtonElem); - } else { - // remove movie controls - var movieControls = dojo.query("td.movieControls", element)[0]; - movieControls.parentNode.removeChild(movieControls); - } - } - activateMovies(self.enableMovies); - - // do we have parameters for the initial pose? - if(self.params && self.params.pose) - self.setScene(self.params.imagePath, self.params.pose, self.params.serverURL); - - if (self.serverURL) { - self.refreshServer(self.serverURL); - self.updateScene(); - } - - }); - }); - -}; diff --git a/apps/samples/vrml/viewer-webgl.js b/apps/samples/vrml/viewer-webgl.js deleted file mode 100644 index 19a589f..0000000 --- a/apps/samples/vrml/viewer-webgl.js +++ /dev/null @@ -1,1290 +0,0 @@ -// Define the namespace -var eu_smartvorex_femkit_ui_modelviewer = eu_smartvorex_femkit_ui_modelviewer || {}; - -eu_smartvorex_femkit_ui_modelviewer.VRMLViewer = function (element, params) { - - console.log(params); - - // private attributes - var self = this; - var batchChanges = false; - var webGLManipulatorsSetup = false; - - // private instanceId - // if (!VRMLViewer.instances) - // VRMLViewer.instances = 0; - // this.instanceId = VRMLViewer.instances++; - - // private instanceId - if (!eu_smartvorex_femkit_ui_modelviewer.VRMLViewer.instances) - eu_smartvorex_femkit_ui_modelviewer.VRMLViewer.instances = 0; - this.instanceId = eu_smartvorex_femkit_ui_modelviewer.VRMLViewer.instances++; - - // public attribute defaults - this.width = 450; - this.height = 350; - - { - var pose = { - pitch: 0, - roll: 0, - yaw: 0, - zoom: 1, - x: 0, - y: 0, - z: 0, - width: false, - height: false, - autorotate: false, - } - this.pose = pose; - } - - this.enableMovies = false; - this.enableDND = true; - this.enableWebGL = true; - this.enableSceneshots = false; - this.enableDraggables = false; - this.enablePosePublishing = true; - this.treeNavigationStyle = true; - this.listNavigationStyle = true; - this.listDirectory = ""; - - this.serverURL = "localhost:8082"; - this.webSocketURL = "localhost:8083"; - this.imagePath = ""; - this.imageFormat = ".png"; - this.resRoot = ""; - - // copy over values from constructor arguments - if (params) { - for (var param in params) { - if (self.hasOwnProperty(param)) { - self[param] = params[param]; - } else { - console.log("Unknown paramter " + param); - } - } - } - - if (!self.pose.width) - self.pose.width = self.width; - if (!self.pose.height) - self.pose.height = self.height; - - this.hasWebSockets = ("WebSocket" in window); - - if (self.enablePosePublishing && !self.hasWebSockets) { - console.log("Your browser does not support WebSockets, deactivating pose publishing"); - self.enablePosePublishing = false; - } - - var hasWebGL = function() { - try { - if (!window.WebGLRenderingContext) { - return false; - } - var canvas = document.createElement("canvas"); - var names = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"]; - for (var i = 0; i < 4; i++) { - var gl = canvas.getContext(names[i]); - if (gl) { - return true; - } - } - } catch(e) { - return false; - } - return false; - } - self.hasWebGL = hasWebGL(); - - if (self.enableWebGL && !hasWebGL()) { - console.log("Your browser does not support WebGL, falling back to sceneshots"); - self.enableWebGL = false; - self.enableSceneshots = true; - } - - // see http://stackoverflow.com/questions/4810841/how-can-i-pretty-print-json-using-javascript - function syntaxHighlight(json) { - if (typeof json != 'string') { - json = JSON.stringify(json, undefined, 2); - } - json = json.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); - return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { - var cls = 'number'; - if (/^"/.test(match)) { - if (/:$/.test(match)) { - cls = 'key'; - } else { - cls = 'string'; - } - } else if (/true|false/.test(match)) { - cls = 'boolean'; - } else if (/null/.test(match)) { - cls = 'null'; - } - return '<span class="' + cls + '">' + match + '</span>'; - }); - } - - // normalize parameters - var normalizeParams = function() { - // make sure server url begins with protocol and does *not* ends in / - if (!self.serverURL.substring(0, 7) == "http://" && - !self.serverURL.substring(0, 8) == "https://") - self.serverURL = "http://" + self.serverURL; - if (!self.serverURL.lastIndexOf("/") === self.serverURL.length) - self.serverURL += self.serverURL.substring(0, self.serverURL - 1); - - // make sure we have a listDirectory with navigation style list ending in / - if (self.modelNavigationStyle === "list" && !self.listDirectory && self.imagePath) - self.listDirectory = self.imagePath.substring(0, self.imagePath.lastIndexOf("/")); - if (!self.listDirectory.indexOf("/", self.listDirectory.length - 1) !== -1) - self.listDirectory += "/"; - - // use latest image if none given - if (!self.imagePath) - self.imagePath = self.listDirectory + "latest"; - - if (!self.imageFormat.substring(0, 1) !== ".") - self.imageFormat = "." + self.imageFormat; - } - normalizeParams(); - - var getWebGLModel = function(url) { - if (self.webGLStandby) { self.webGLStandby.show(); } - var defer = osgDB.Promise.defer(); - var node = new osg.MatrixTransform(); - //node.setMatrix(osg.Matrix.makeRotate(-Math.PI/2, 1,0,0, [])); - var loadModel = function(url) { - osg.log("loading " + url); - var req = new XMLHttpRequest(); - req.open('GET', url, true); - req.onreadystatechange = function(aEvt) { - if (req.readyState == 4) { - if(req.status == 200) { - osgDB.Promise.when(osgDB.parseSceneGraph(JSON.parse(req.responseText))).then(function(child) { - node.setMatrix(osg.Matrix.makeRotate(Math.PI/2.0, 1,0,0,[])); - node.addChild(child); - defer.resolve(node); - osg.log("success " + url); - }); - } else { - osg.log("error " + url); - } - if (self.webGLStandby) { self.webGLStandby.hide(); } - } - }; - req.send(null); - }; - loadModel(url); - return defer.promise; - } - - var urlSuffixForPose = function(pose) { - var queryString = - '?width=' + pose.width + - '&height=' + pose.height + - '&pitch=' + pose.pitch + - '&roll=' + pose.roll + - '&yaw=' + pose.yaw + - '&x=' + pose.x + - '&y=' + pose.y + - '&z=' + pose.z + - '&zoom=' + pose.zoom + - '&autorotate=' + (pose.autorotate ? '1' : '0'); - return queryString; - }; - - var moverRelativeTo = function(mover, container) { - var containerPos = absolutePosition(container); - return { - x: mover.x - containerPos.x, - y: mover.y - containerPos.y - }; - }; - - // see http://stackoverflow.com/questions/288699/get-the-position-of-a-div-span-tag - var absolutePosition = function(el) { - for (var lx=0, ly=0; el != null; lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent); - return {x: lx,y: ly}; - }; - - // update the scene - this.updateScene = function() { - if (self.serverURL && self.imagePath && !self.batchChanges) { - console.log(self.serverURL + self.imagePath + self.imageFormat + urlSuffixForPose(self.pose)); - if (self.enableWebGL) { - osgDB.Promise.when(getWebGLModel(self.serverURL + self.imagePath + '.osgjs')).then(function(model) { - self.webGLViewer.setSceneData(model); - if (!webGLManipulatorsSetup) { - self.webGLViewer.setupManipulator(new osgGA.OrbitManipulator(), false); - self.webGLViewer.getManipulator().computeHomePosition(); - } - webGLManipulatorsSetup = true; - }); - } - if (self.enableSceneshots) { - self.imgElem.src = self.serverURL + self.imagePath + self.imageFormat + urlSuffixForPose(self.pose); - if (self.enableMovies && self.movieAddButton) { - // we are showing an image, activate movie controls - self.movieAddButton.domNode.style.display = ""; - self.movieDropDown.domNode.style.display = ""; - } - } - } - }; - - // get list of supported ffmpeg codecs from server - this.populateMovieCodecs = function(server, selectElem) { - self.xhr.get({ - // The URL to request - url: server, - handleAs:"json", - headers:{"X-Requested-With":null}, - load: function(result) { - for (var codec in result.video) { - if (codec !== "mpeg1video" && - codec !== "mpeg2video" && - codec !== "mpeg4" && - codec !== "h264" && - codec !== "ayuv" && - codec !== "flashsv" && - codec !== "flashsv2" && - codec !== "flv" && - codec !== "rv40" && - codec !== "theora" && - codec !== "v210" && - codec !== "v308" && - codec !== "v408" && - codec !== "v410" && - codec !== "wmv3" && - codec !== "y41p" && - codec !== "yuv4") - continue; - //console.log(codec); - selectElem.options.push({ label: result.video[codec].longName, value: codec }); - if (codec === "mpeg4") - selectElem.options[selectElem.options.length - 1].selected = true; - } - } - }); - } - - // update list of vrml files from server - this.refreshServer = function(server, params) { - self.serverURL = server; - if (!params) - params = {}; - if (self.fileStandby) { self.fileStandby.show(); } - - self.xhr.get({ - // The URL to request - url: server, - handleAs:"json", - headers:{"X-Requested-With":null}, - error: function(result) { - - if (self.browseButton) { self.browseButton.setAttribute('label', 'Browse'); } - if (self.fileStandby) { self.fileStandby.hide(); } - - if (!params.skipTree) { - if (self.fileTreeStore) { - var allItems = self.fileTreeStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileTreeStore.remove(allItems[i].id); - } - } - } - if (!params.skipList) { - if (self.fileListStore) { - var allItems = self.fileListStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileListStore.remove(allItems[i].id); - } - } - } - }, - load: function(result) { -// self.localStorage.put("vrmlServer", self.serverURL, null); - if (self.browseButton) { self.browseButton.setAttribute('label', 'Refresh'); } - if (self.fileStandby) { self.fileStandby.hide(); } - - if (self.treeNavigationStyle && !params.skipTree) { - // empty store - var allItems = self.fileTreeStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileTreeStore.remove(allItems[i].id); - } - - // parse result as tree - (function fillstore(tree, parentId) { - // todo: respect navigation style - for (key in tree) { - if ('url' in tree[key]) { - self.fileTreeStore.add({id:parentId+key, name:key, url:tree[key].path, parent:parentId}); - } else { - self.fileTreeStore.add({id:parentId+key, name:key, parent:parentId}); - fillstore(tree[key], parentId+key); - } - } - } (result.models, "root", "")); - } - if (self.listNavigationStyle && !params.skipList) { - - // empty store - var allItems = self.fileListStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileListStore.remove(allItems[i].id); - } - - // parse result as list - if (!self.listDirectory) - console.log("Requested modelNavigationStyle === list but provided no listDirectory"); - var dirs = self.listDirectory.split("/"); - var models = result.models; - for (var dir in dirs) { - if (!dirs[dir].length) - continue; - if (dirs[dir] in models) { - models = models[dirs[dir]]; - } else { - console.log("No " + dirs[dir] + " in " + models); - } - } - for (var key in models) { - var url = self.serverURL + models[key].path; - self.fileListStore.add({id:key, value:models[key].path, label:key, name:key, url:url}); - } - self.fileListSelect.startup(); - } - //self.updateScene(); - } - }); - }; - - this.setPose = function(imagePath, imageFormat, pose, serverURL) { - if (serverURL && serverURL != self.serverURL) { - self.refreshServer(serverURL); - } - self.imagePath = imagePath; - self.imageFormat = imageFormat; - self.pose = pose; - - var pitch = (pose.pitch % (2 * 3.14159) + 0.5) * 100; - var roll = (pose.roll % (2 * 3.14159) + 0.5) * 100; - var yaw = (pose.yaw % (2 * 3.14159) + 0.5) * 100; - - var x = ((pose.x / 100) + 0.5) * 100; - var y = ((pose.y / 100) + 0.5) * 100; - - var zoom = (((pose.zoom - 1) / 3) + 0.5) * 100; - - self.pitchRollHandlerElem.parentNode.style.right = pitch + "%"; - self.pitchRollHandlerElem.parentNode.style.top = roll + "%"; - self.yawZoomHandlerElem.parentNode.style.right = yaw + "%"; - self.yawZoomHandlerElem.parentNode.style.top = zoom + "%"; - self.xyHandlerElem.parentNode.style.right = x + "%"; - self.xyHandlerElem.parentNode.style.top = y + "%"; - - self.updateScene(); - }; - - require(["dojo/dom-construct", - "dojo/_base/xhr", - "dojo/dom", - "dojo/on", - "dojo/_base/array", - "dojox/storage", - "dojo/store/Memory", - "dojo/store/Observable", - "dijit/tree/ObjectStoreModel", - "dojo/data/ObjectStore", - "dijit/Tree", - "dijit/form/TextBox", - "dijit/form/Button", - "dojox/widget/Standby", - "dijit/form/DropDownButton", - "dijit/TooltipDialog", - "dojo/dnd/Moveable", - "dojo/ready", - "dojo/dnd/Source", - "dijit/form/HorizontalSlider", - "dijit/form/Select", - "dijit/form/NumberSpinner"], - function(domConst, - xhr, - dom, - on, - array, - storage, - Memory, - Observable, - ObjectStoreModel, - ObjectStore, - Tree, - TextBox, - Button, - Standby, - DropDownButton, - TooltipDialog, - Moveable, - ready, - Source, - HorizontalSlider, - Selector, - NumberSpinner) { - - ready(function() { - - if (typeof(element) === 'string') { - element = dom.byId(element); - } - element.style.height = self.pose.height; - element.style.width = self.pose.width; - - self.element = element; - self.xhr = xhr; - - // establish our dom - element.appendChild(domConst.toDom('\ - <table>\ - <tr>\ - <td valign="top">\ - <div style="position: relative; padding: 0px; width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px">\ - <div class="screenShot" style="position: absolute; width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px">\ - <img class="screenShot" style="width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px"></img>\ - </div>\ - <div class="webGL" style="position: absolute; width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px">\ - <canvas class="webGL" style="width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px"></canvas>\ - </div>\ - <div style="z-index: -1; position: absolute; right: 45%; top: 45%">\ - <div class="progress"></div>\ - </div>\ - <div style="position: absolute; left: 10px; top: 10px">\ - <table></tr>\ - <td class="treeNavigation filesDropDown" style="vertical-align: middle"></td>\ - <td class="movieControls">\ - <div class="movieDropDown" style="display: inline"></div>\ - <button type="button" class="movieAddButton"></button>\ - </td>\ - <td align="right"><button type="button" class="resetButton"></button></td>\ - <td class="dndHandler" style="vertical-align: middle; padding-top: 4px;"></td>\ - </tr></table>\ - </div>\ - <div style="position: absolute; right: 10px; top: 15%; height: 50%">\ - <div class="zoomSlide"></div>\ - </div>\ - <div class="draggable" style="position: absolute; right: 50%; top: 50%">\ - <div class="pitchRollHandler" style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px;">\ - <table>\ - <tr>\ - <td><img class="pitchRollHandlerImg" src="' + self.resRoot + 'img/pitchRoll-handle.png" height="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="pitchLabel"></div><div class="rollLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - <div class="draggable"style="position: absolute; right: 50%; top: 50%">\ - <div class="yawZoomHandler">\ - <div style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px; position: absolute; left: -34px;">\ - <table>\ - <tr>\ - <td><img class="yawZoomHandlerImg" src="' + self.resRoot + 'img/yawZoom-handle.png" height="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="yawLabel"></div><div class="zoomLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - </div>\ - <div class="draggable"style="position: absolute; right: 50%; top: 50%">\ - <div class="xyHandler" style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px;">\ - <table>\ - <tr>\ - <td><img class="xyHandlerImg" src="' + self.resRoot + 'img/xy-handle.png" width="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="xLabel"></div><div class="yLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - <div class="listNavigation" style="position: absolute; left: 10px; bottom: 10px">\ - <table></tr>\ - <td style="vertical-align: middle"><button class="prevButton" type="button" /></td>\ - <td style="vertical-align: middle"><div class="fileList" /></td>\ - <td style="vertical-align: middle"><button class="nextButton" type="button" /></td>\ - </tr></table>\ - </div>\ - </div>\ - </td>\ - <td valign="top" height="100%">\ - </td>\ - </tr>\ - <tr>\ - <td colspan="2"><div class="messages"></div></td>\ - </tr>\ - </table>\ - ')); - - // fetch special dom nodes for content - self.messageBox = dojo.query("div.messages", element)[0]; - self.imgElem = dojo.query("img.screenShot", element)[0]; - - /** - * === WebGL ==================== - */ - var activateWebGL = function(enable) { - if (enable) { - self.canvasElem = dojo.query("canvas.webGL", element)[0]; - self.canvasElem.style.width = self.width; - self.canvasElem.style.height = self.height; - self.canvasElem.width = self.width; - self.canvasElem.height = self.height; - - // osgDB.Promise.when(getWebGLModel('http://localhost:8081/vrml/cranehook/cranehook_bad_convergence/HARD_MP_VAL_013.osgjs')).then(function(model) { - // self.webGLViewer = new osgViewer.Viewer(self.canvasElem, {antialias : true, alpha: true }); - // self.webGLViewer.init(); - // self.webGLViewer.getCamera().setClearColor([0.0, 0.0, 0.0, 0.0]); - // self.webGLViewer.setSceneData(model); - // self.webGLViewer.setupManipulator(); - // self.webGLViewer.getManipulator().computeHomePosition(); - // self.webGLViewer.run(); - // }); - - if (self.webGLViewer === undefined) { - self.webGLViewer = new osgViewer.Viewer(self.canvasElem, {antialias : true, alpha: true }); - self.webGLViewer.init(); - self.webGLViewer.getCamera().setClearColor([0.0, 0.0, 0.0, 0.0]); - self.webGLViewer.setupManipulator(); - self.webGLViewer.run(); - - self.webGLStandby = new Standby({target: self.element }); - self.element.appendChild(self.webGLStandby.domNode); - } - - // show elements - array.forEach(dojo.query(".webGL", element), function(entry, i) { - entry.style.display = "inline"; - }) - } else { - if (self.webGLViewer) { - self.webGLViewer.stop(); - } - // hide elements - array.forEach(dojo.query(".webGL", element), function(entry, i) { - entry.style.display = "none"; - }) - } - } - activateWebGL(self.enableWebGL); - - var activateScreenshot = function(enable) { - if (enable) { - array.forEach(dojo.query(".screenShot", element), function(entry, i) { - entry.style.display = "inline"; - }); - } else { - array.forEach(dojo.query(".screenShot", element), function(entry, i) { - entry.style.display = "none"; - }); - } - } - activateScreenshot(self.enableSceneshots); - - /** - * === POSE MANIPULATION AND RESET ==================== - */ - - self.resetButtonElem = dojo.query("button.resetButton", element)[0]; - self.resetButton = new Button({ - label: "Reset", - onClick: function() { - if (self.webGLViewer) { - self.webGLViewer.setupManipulator(); - self.webGLViewer.getManipulator().computeHomePosition(); - } - self.pose.x = 0; - self.pose.y = 0; - self.pose.pitch = 0; - self.pose.roll = 0; - self.pose.yaw = 0; - self.pose.zoom = 1; - - self.xyHandler.node.style.left = 0; - self.xyHandler.node.style.top = 0; - self.pitchRollHandler.node.style.left = 0; - self.pitchRollHandler.node.style.top = 0; - self.yawZoomHandler.node.style.left = 0; - self.yawZoomHandler.node.style.top = 0; - - self.updateScene(); - } - }, self.resetButtonElem); - - var activateDraggables = function(enable) { - if (enable) { - if (self.pitchRollHandler == undefined) { - self.progressElem = dojo.query("div.progress", element)[0]; - - self.pitchRollHandlerElem = dojo.query(".pitchRollHandler", element)[0]; - self.yawZoomHandlerElem = dojo.query(".yawZoomHandler", element)[0]; - self.xyHandlerElem = dojo.query(".xyHandler", element)[0]; - - self.pitchRollHandler = new Moveable(self.pitchRollHandlerElem); - self.pitchRollHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.pitchRollHandlerImg", mover.node)[0]; - var pitchLabel = dojo.query("div.pitchLabel", mover.node)[0]; - var rollLabel = dojo.query("div.rollLabel", mover.node)[0]; - pitchLabel.innerHTML = ''; - rollLabel.innerHTML = ''; - self.updateScene(); - }; - self.pitchRollHandler.onMoving = function(mover) { - var handlerImg = dojo.query(".pitchRollHandlerImg", mover.node)[0]; - var pitchLabel = dojo.query(".pitchLabel", mover.node)[0]; - var rollLabel = dojo.query(".rollLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 30; - offset.y += 20; - - self.xyHandlerElem.style.zIndex = 1; - self.yawZoomHandlerElem.style.zIndex = 1; - self.pitchRollHandlerElem.style.zIndex = 2; - - self.pose.roll = offset.x / self.pose.width - 0.5; - self.pose.pitch = offset.y / self.pose.height - 0.5; - self.pose.pitch *= -1; - self.pose.roll *= 2 * 3.14159; - self.pose.pitch *= 2 * 3.14159; - self.pose.roll = Math.ceil((self.pose.roll) * 10) / 10; - self.pose.pitch = Math.ceil((self.pose.pitch) * 10) / 10; - pitchLabel.innerHTML = 'Pitch:' + self.pose.pitch; - rollLabel.innerHTML = 'Roll:' + self.pose.roll; - }; - - self.yawZoomHandler = new Moveable(self.yawZoomHandlerElem); - self.yawZoomHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.yawZoomHandlerImg", mover.node)[0]; - var yawLabel = dojo.query("div.yawLabel", mover.node)[0]; - var zoomLabel = dojo.query("div.zoomLabel", mover.node)[0]; - yawLabel.innerHTML = ''; - zoomLabel.innerHTML = ''; - self.updateScene(); - }; - self.yawZoomHandler.onMoving = function(mover) { - var handlerImg = dojo.query("img.yawZoomHandlerImg", mover.node)[0]; - var yawLabel = dojo.query("div.yawLabel", mover.node)[0]; - var zoomLabel = dojo.query("div.zoomLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 7; - offset.y += 9; - - self.xyHandlerElem.style.zIndex = 1; - self.yawZoomHandlerElem.style.zIndex = 2; - self.pitchRollHandlerElem.style.zIndex = 1; - - // self.pose.pitch = self.pose.pitch % (2 * 3.14159); - // self.pose.roll = self.pose.roll % (2 * 3.14159); - self.pose.yaw = (self.pose.width - offset.x) / self.pose.width - 0.5; - self.pose.zoom = offset.y / self.pose.height - 0.5; - self.pose.yaw *= 2 * 3.14159; - self.pose.zoom = self.pose.zoom * 3 + 1; - self.pose.zoom = Math.ceil((self.pose.zoom) * 10) / 10; - self.pose.yaw = Math.ceil((self.pose.yaw) * 10) / 10; - yawLabel.innerHTML = 'Yaw:' + self.pose.yaw; - zoomLabel.innerHTML = 'Zoom:' + self.pose.zoom; - }; - - self.xyHandler = new Moveable(self.xyHandlerElem); - self.xyHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.xyHandlerImg", mover.node)[0]; - var xLabel = dojo.query("div.xLabel", mover.node)[0]; - var yLabel = dojo.query("div.yLabel", mover.node)[0]; - - xLabel.innerHTML = ''; - yLabel.innerHTML = ''; - - self.updateScene(); - }; - self.xyHandler.onMoving = function(mover) { - var handlerImg = dojo.query("img.xyHandlerImg", mover.node)[0]; - var xLabel = dojo.query("div.xLabel", mover.node)[0]; - var yLabel = dojo.query("div.yLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 3; - offset.y += 13; - - self.xyHandlerElem.style.zIndex = 2; - self.yawZoomHandlerElem.style.zIndex = 1; - self.pitchRollHandlerElem.style.zIndex = 1; - - self.pose.x = offset.x / self.pose.width - 0.5; - self.pose.y = offset.y / self.pose.height - 0.5; - self.pose.x *= 100; - self.pose.y *= 100; - self.pose.y = Math.ceil((self.pose.y) * 10) / 10; - self.pose.x = Math.ceil((self.pose.x) * 10) / 10; - xLabel.innerHTML = 'X:' + self.pose.x; - yLabel.innerHTML = 'Y:' + self.pose.y; - }; - } - - // show all draggables - array.forEach(dojo.query(".draggable", element), function(entry, i) { - entry.style.display = "inline"; - }) - - } else { - // show all draggables - array.forEach(dojo.query(".draggable", element), function(entry, i) { - entry.style.display = "none"; - }) - } - } - activateDraggables(self.enableDraggables); - - /** - * === DRAG HANDLER ==================== - */ - var activateDND = function(enable) { - if (enable) { - self.createAvatar = function(item, mode) { - if (mode == 'avatar') { - // create your avatar if you want - var avatar = dojo.create( 'div', { innerHTML: item.data }); - var avatarPose = dojo.clone(self.pose); - avatarPose.width=60; - avatarPose.height=60; - var avatarImgUrl = urlSuffixForPose(avatarPose); - avatar.innerHTML = '<img src=' + self.serverURL + self.imagePath + self.imageFormat + avatarImgUrl + ' /> '; - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.serverURL + self.imagePath + self.imageFormat + avatarImgUrl; - item.imagePath = self.imagePath; - item.imageFormat = self.imageFormat; - item.serverURL = self.serverURL; - item.pose = avatarPose; - return {node: avatar, data: item, type: item.type}; - } - var handler = dojo.create( 'div', { innerHTML: '<img src="' + self.resRoot + 'img/drag.png" width="20px" />' }); - return {node: handler, data: item, type: item.type}; - }; - - self.dndHandler = new Source(dojo.query("td.dndHandler", element)[0], {copyOnly: true, creator: self.createAvatar}); - self.dndHandler.insertNodes(false, [ { } ]); - - array.forEach(dojo.query(".dndHandler", element), function(entry, i) { - entry.style.display = "inline"; - }) - - } else { - array.forEach(dojo.query(".dndHandler", element), function(entry, i) { - entry.style.display = "none"; - }) - - } - } - activateDND(self.enableDND); - - /** - * === FILE NAVIGATION ==================== - */ - - var activateListNavigation = function(enable) { - if (enable) { - array.forEach(dojo.query(".listNavigation", element), function(entry, i) { - entry.style.display = "inline"; - }); - - if (!self.fileListStore) { - // setup fileStore - self.fileListStore = new Observable(new Memory({ - data: [], - })); - - self.prevButtonElem = dojo.query("button.prevButton", element)[0]; - self.nextButtonElem = dojo.query("button.nextButton", element)[0]; - self.fileListElem = dojo.query("div.fileList", element)[0]; - - self.fileListSelect = new Selector({ - store: new ObjectStore({ objectStore: self.fileListStore }), - onChange: function(name) { - var item = self.fileListStore.query({ id: name })[0]; - self.imagePath = self.listDirectory + item.name; - self.updateScene(); - } - }, self.fileListElem); - - self.prevButton = new Button({ - label: "<", - onClick: function() { - var allItems = self.fileListStore.query(); - var foundAt = 0; - for (var i = 0; i < allItems.total; i++) { - console.log(self.serverURL + self.imagePath + " === " + allItems[i].url); - if (self.serverURL + self.imagePath === allItems[i].url) { - foundAt = i; - break; - } - } - - if (foundAt > 0) { - self.imagePath = self.listDirectory + allItems[foundAt - 1].name; - self.fileListSelect.attr( 'value', allItems[foundAt - 1].id ); - if (self.serverURL + self.imagePath !== allItems[foundAt - 1].url) - console.log(self.serverURL + self.imagePath + " !== " + allItems[foundAt - 1].url); - self.updateScene(); - } - } - }, self.prevButtonElem); - - self.nextButton = new Button({ - label: ">", - onClick: function() { - var allItems = self.fileListStore.query(); - var foundAt = 0; - for (var i = 0; i < allItems.total; i++) { - //console.log(self.serverURL + self.imagePath + " === " + allItems[i].url); - if (self.serverURL + self.imagePath === allItems[i].url) { - foundAt = i; - break - } - } - if (foundAt + 1 < allItems.total) { - self.imagePath = self.listDirectory + allItems[foundAt + 1].name + ".png"; - self.fileListSelect.attr( 'value', allItems[foundAt + 1].id ); - if (self.serverURL + self.imagePath !== allItems[foundAt + 1].url) - console.log(self.serverURL + self.imagePath + " !== " + allItems[foundAt + 1].url); - self.updateScene(); - } - } - }, self.nextButtonElem); - } - } else { - array.forEach(dojo.query(".listNavigation", element), function(entry, i) { - entry.style.display = "none"; - }); - } - } - activateListNavigation(self.listNavigationStyle); - - var activateTreeNavigation = function(enable) { - if (enable) { - - array.forEach(dojo.query(".treeNavigation", element), function(entry, i) { - entry.style.display = ""; - }); - - if (!self.fileTreeStore) { - // setup fileStore - self.fileTreeStore = new Observable(new Memory({ - data: [ { id: 'root', name:'3D Models'} ], - getChildren: function(object){ - return this.query({parent: object.id}); - } - })); - - self.fileTreeModel = new ObjectStoreModel({ - store: self.fileTreeStore, - query: { id: "root" } - }); - - // setup actual tree dijit - self.fileTree = new dijit.Tree({ - id: "fileTree" + self.instanceId, - model: self.fileTreeModel, - persist: false, - showRoot: false, - style: "height: 300px;", - onClick: function(item){ - if ('url' in item) { - self.imagePath = item.url; - var newListDir = self.imagePath.substring(0, self.imagePath.lastIndexOf("/")); - if (newListDir.length > 0) - newListDir += '/'; - if (newListDir !== self.listDirectory) { - self.listDirectory = newListDir; - self.refreshServer(self.serverURL, { skipTree: true }); - } - self.updateScene(); - } - }, - getIconClass: function(item, opened) { - return (!item || !('url' in item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"; - }, - getIconStyle: function(item, opened){ - if('url' in item) { - return { backgroundImage: "url('" + self.serverURL + item.url + self.imageFormat + "?width=16&height=16')"}; - } - } - //return {backgroundImage: "url('" + item.url + "?width=16&height=16')"}; - }); - - self.filesDropDownElem = dojo.query("td.filesDropDown", element)[0]; - - self.serverBox = new TextBox({ - name: "Server", - value: self.serverURL, - style: "width: 65%", - - onKeyUp: function(e) { - if (self.browseButton) { - if (this.get("value") !== self.serverURL) { - self.browseButton.setAttribute('label', 'Browse'); - } else { - self.browseButton.setAttribute('label', 'Refresh'); - } - } - }, - - onKeyDown: function(e) { - var code = e.keyCode || e.which; - if( code === 13 ) { - e.preventDefault(); - self.refreshServer(this.get("value")); - return false; - } - }, - }); - - self.browseButton = new Button({ - label: "Browse", - onClick: function(){ - self.refreshServer(self.serverBox.get("value")); - } - }); - - self.filesDropDownContent = domConst.toDom('<div />'); - self.filesDropDownContent.appendChild(self.serverBox.domNode); - self.filesDropDownContent.appendChild(self.browseButton.domNode); - self.filesDropDownContent.appendChild(self.fileTree.domNode); - - self.filesToolTip = new TooltipDialog({ content:self.filesDropDownContent, style:"max-height:320px"}); - self.filesDropDown = new DropDownButton({ label: "Files", dropDown: self.filesToolTip }); - self.filesDropDownElem.appendChild(self.filesDropDown.domNode); - - self.fileStandby = new Standby({target: self.filesDropDownContent }); - self.filesDropDownContent.appendChild(self.fileStandby.domNode); - } - } else { - array.forEach(dojo.query(".treeNavigation", element), function(entry, i) { - entry.style.display = "none"; - }); - } - } - activateTreeNavigation(self.treeNavigationStyle); - - if (self.serverURL) { - self.refreshServer(self.serverURL); - self.updateScene(); - } - - - /** - * === Pose Publishing ==================== - */ - - var activatePosePublishing = function(enable) { - if (enable && self.hasWebSockets) { - self.poseWebSocket = new WebSocket(self.webSocketURL); - - self.poseWebSocket.onopen = function(evt) { - foo = 0; - function publishPose() { - foo++; - var viewMatrix = self.webGLViewer.getCamera().getViewMatrix(); - var roundMatrix = []; - for (var i = 0; i < 16; i++) { - roundMatrix[i] = viewMatrix[i].toFixed(5); - if (roundMatrix[i] == -0.0) roundMatrix[i] = 0.0; - } - self.poseWebSocket.send(JSON.stringify(roundMatrix)); - self.messageBox.innerHTML = "<pre>SEND" + syntaxHighlight(roundMatrix) + "</pre>"; - // self.poseWebSocket.send(foo); - // self.messageBox.innerHTML = "<pre>SEND" + foo + "</pre>"; - if (self.enablePosePublishing) { - setTimeout(publishPose, 200); - } - } - self.messageBox.innerHTML = "<pre>Starting</pre>"; - publishPose(); - }; - self.poseWebSocket.onclose = function(evt) { - }; - self.poseWebSocket.onmessage = function(evt) { - var result = JSON.parse(evt.data); - self.messageBox.innerHTML = "<pre>RCVD" + syntaxHighlight(JSON.parse(result.data.content)) + "</pre>"; - }; - self.poseWebSocket.onerror = function(evt) { - }; - } else { - - } - } - activatePosePublishing(self.enablePosePublishing); - - /** - * === MOVIE DROPDOWN ==================== - */ - - if (self.enableMovies) { - self.movieDropDownElem = dojo.query("div.movieDropDown", element)[0]; - self.movieAddButtonElem = dojo.query("button.movieAddButton", element)[0]; - - self.movieDropDownContent = domConst.toDom( - '<div style="overflow: auto; max-height: 420px;"> \ - <table><tr class="movieFormatLengthRow" /></tr><tr class="movieWidthHeightLengthRow" /></table> \ - <div class=\"dndArea\" /> \ - </div>' - ); - - self.movieFormatLengthRowElem = dojo.query("tr.movieFormatLengthRow", self.movieDropDownContent)[0]; - self.movieWidthHeightLengthRowElem = dojo.query("tr.movieWidthHeightLengthRow", self.movieDropDownContent)[0]; - self.movieDnDArea = dojo.query("div.dndArea", self.movieDropDownContent)[0]; - - self.createMovieThumb = function(item, mode) { - if (mode == 'avatar') { - // when dragged - var avatar = dojo.create( 'div', { innerHTML: item.data }); - var avatarPose = dojo.clone(self.pose); - avatarPose.width = 60; - avatarPose.height = 60; - var avatarImgUrl = urlSuffixForPose(avatarPose); - avatar.innerHTML = '<img src=' + self.imagePath + self.imageFormat + avatarImgUrl + ' /> '; - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.imagePath + avatarImgUrl; - item.imagePath = self.imagePath; - item.serverURL = self.serverURL; - item.pose = avatarPose; - return {node: avatar, data: item, type: item.type}; - } else { - - // when added to list - var thumb = domConst.toDom("\ - <div>\ - <table><tr><td>\ - <img class=\"movieThumb\"/>\ - <img class=\"removeThumb\" style=\"vertical-align: top; margin: -3px 0px 0px -8px; width: 20px; height: 20px;\"/>\ - </td><td align=\"left\">\ - <table><tr>\ - <td>Frame:</td><td><div class=\"relFrameLength\"/></td>\ - <td><div class=\"fillInSeries\" \></td>\ - </tr><tr>\ - <td>Transition:</td><td><div class=\"relTransitionLength\"/></td>\ - </tr></table>\ - </td></tr></table>\ - </div>\ - "); - thumb = dojo.query("div", thumb)[0]; - - var thumbImgElem = dojo.query("img.movieThumb", thumb)[0]; - var removeImgElem = dojo.query("img.removeThumb", thumb)[0]; - var relFrameLengthElem = dojo.query("div.relFrameLength", thumb)[0]; - var relTransitionLengthElem = dojo.query("div.relTransitionLength", thumb)[0]; - var fillInSeriesElem = dojo.query("div.fillInSeries", thumb)[0]; - - item.getThisAndNeighborsFromDnD = function() { - var thisAndNeighbors = {}; - self.addToMovieHandler.forInItems(function(obj, key, ctx) { - if (obj.data === item) { - thisAndNeighbors.this = { key: key, obj: obj }; - } else { - thisAndNeighbors.before = { key: key, obj: obj }; - } - if (thisAndNeighbors.this) { - thisAndNeighbors.after = { key: key, obj: obj }; - return thisAndNeighbors; - } - }); - return thisAndNeighbors; - }; - - item.relFrameLengthSlider = new HorizontalSlider({ - value: 50, - title: "Relative Duration of Frame", - style: "width:150px;" - }, relFrameLengthElem); - - item.relTransitionLengthSlider = new HorizontalSlider({ - value: 100, - title: "Relative Duration of Transition", - style: "width:150px;" - }, relTransitionLengthElem); - - removeImgElem.onclick = function() { - var thisItem = item.getThisAndNeighborsFromDnD(); - if (thisItem.this) { - // haha - what a mess! - self.addToMovieHandler.selectNone(); - self.addToMovieHandler.selection[thisItem.this.key] = thisItem.this.obj; - self.addToMovieHandler.deleteSelectedNodes(); - } - // disable create button if this was the last one - if (!thisItem.after || !thisItem.before) { - self.movieCreateButton.setAttribute('disabled', true); - } - } - - item.fillInSeriesButton = new Button({ - label: "Insert Series", - style: "display: none;", - onClick: function(){ - alert("foo"); - } - }, fillInSeriesElem); - - removeImgElem.src = self.resRoot + "img/close.png"; - - var thumbPose = dojo.clone(self.pose); - thumbPose.width = self.pose.width / 10; - thumbPose.height = self.pose.height / 10; - var thumbImgUrl = urlSuffixForPose(thumbPose); - - thumbImgElem.src = self.serverURL + self.imagePath + self.imageFormat + thumbImgUrl; - // removeImgElem.src = self.resRoot + 'img/close.png'; - - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.imagePath + thumbImgUrl; - item.imagePath = self.imagePath; - item.serverURL = self.serverURL; - item.pose = thumbPose; - - return {node: thumb, data: item, type: item.type}; - } - }; - - self.addToMovieHandler = new Source(self.movieDnDArea, {copyOnly: true, creator: self.createMovieThumb}); - - self.movieFormatSelection = new Selector({ - name: "movieFormat", - style: "width: 320px", - options: [] - }); - self.populateMovieCodecs(self.serverURL + '/movie/codecs', self.movieFormatSelection); - - self.movieFormatLengthRowElem.appendChild(dojo.create('td', { innerHTML: 'Format:'} )); - self.movieFormatLengthRowElem.appendChild(dojo.create('td', { colspan: "2"})); - self.movieFormatLengthRowElem.lastChild.appendChild(self.movieFormatSelection.domNode); - - self.movieHeightSpinner = new NumberSpinner({ - value: 400, - smallDelta: 1, - style: "width: 60px", - constraints: { min:40, places:0 }, - }); - - self.movieWidthSpinner = new NumberSpinner({ - value: 600, - smallDelta: 1, - style: "width: 60px", - constraints: { min:40, places:0 }, - }); - - self.movieCreateButton = new Button({ - label: "Create", - disabled: true, - onClick: function(){ - - var form = document.createElement("form"); - - form.setAttribute("method", "post"); - form.setAttribute("action", self.serverURL + "/movie"); - - var submitData = {}; - submitData.frames = []; - submitData.movieLength = self.movieDurationSpinner.value; - submitData.format = self.movieFormatSelection.value; - submitData.width = self.movieWidthSpinner.value; - submitData.height = self.movieHeightSpinner.value; - - self.addToMovieHandler.forInItems(function(obj, key, ctx) { - var jsonData = { - iconPoseUrl: obj.data.iconPoseUrl, - imagePath: obj.data.imagePath, - serverURL: obj.data.serverURL, - pose: obj.data.pose, - relFrameLength: obj.data.relFrameLengthSlider.value, - relTransitionLength: obj.data.relTransitionLengthSlider.value, - } - submitData.frames.push(jsonData); - }); - - var hiddenField = document.createElement("input"); - hiddenField.setAttribute("type", "hidden"); - hiddenField.setAttribute("name", "data"); - hiddenField.setAttribute("value", JSON.stringify(submitData)); - - form.appendChild(hiddenField); - - // this will not save the returned binary file - // self.xhr.post({ - // form: form, - // load: function(data){ - // alert("asd"); - // } - // }); - - document.body.appendChild(form); - form.submit(); - document.body.removeChild(form); - } - }); - - self.movieDurationSpinner = new NumberSpinner({ - value: 10, - smallDelta: 1, - style: "width: 40px", - constraints: { min:0, places:0 }, - }); - - // append format duration cell - self.movieWidthHeightLengthRowElem.appendChild(dojo.create('td', { innerHTML: 'Size:'} )); - var movieDimensionCell = dojo.create('td'); - movieDimensionCell.appendChild(self.movieWidthSpinner.domNode); - movieDimensionCell.appendChild(dojo.create('span', { innerHTML: "x"} )); - movieDimensionCell.appendChild(self.movieHeightSpinner.domNode); - movieDimensionCell.appendChild(self.movieDurationSpinner.domNode); - movieDimensionCell.appendChild(dojo.create('span', { innerHTML: "sec"} )); - self.movieWidthHeightLengthRowElem.appendChild(movieDimensionCell); - - self.movieWidthHeightLengthRowElem.appendChild(dojo.create('td', { align: "right"})); - self.movieWidthHeightLengthRowElem.lastChild.appendChild(self.movieCreateButton.domNode); - - - self.movieToolTip = new TooltipDialog({ content:self.movieDropDownContent }); - self.movieDropDown = new DropDownButton({ - label: "Movie", - style: "display: none;", - dropDown: self.movieToolTip }); - self.movieDropDownElem.appendChild(self.movieDropDown.domNode); - - self.movieAddButton = new Button({ - label: "+", - style: "margin-left: -10px; display: none;", - onClick: function(){ - if (self.movieFormatSelection.options.length == 0) { - self.populateMovieCodecs(self.serverURL + '/movie/codecs', self.movieFormatSelection); - } - // we could pass item.data here to creator - self.addToMovieHandler.insertNodes(false, [ { } ]); - self.movieCreateButton.setAttribute('disabled', false); - - } - }, self.movieAddButtonElem); - } else { - // remove movie controls - var movieControls = dojo.query("td.movieControls", element)[0]; - movieControls.parentNode.removeChild(movieControls); - } - - // do we have parameters for the initial pose? - if(self.params && self.params.pose) - self.setPose(self.params.imagePath, self.params.pose, self.params.serverURL); - - }); - }); - - -}
\ No newline at end of file diff --git a/apps/samples/vrml/viewer.css b/apps/samples/vrml/viewer.css deleted file mode 100644 index 089d29a..0000000 --- a/apps/samples/vrml/viewer.css +++ /dev/null @@ -1,157 +0,0 @@ -/* Progress Indicator */ -.mblProgressIndicator { - position: relative; - top: 0px; -} -.mblHeading .mblProgressIndicator { - margin: 5px; - float: left; -} -.mblProgContainer { - position: absolute; - width: 100%; - height: 100%; -} -.mblProgressIndicatorCenter { - position: absolute; - top: 180px; - left: 50%; -} -.mblProgressIndicatorCenter .mblProgContainer { - left: -50%; - -webkit-transform-origin: 50% 0; - -moz-transform-origin: 50% 0; -} -.mblProg { - position: absolute; - left: 2px; - top: 0px; - width: 11px; - font-size: 1px; - height: 4px; - overflow: hidden; - -webkit-transform-origin: 0 2px; - -moz-transform-origin: 0 2px; - background-color: #c0c0c0; - border-radius: 2px; -} -.mblProg0 { - -webkit-transform: translate(18px, 10px) rotate(-90.1deg); - -moz-transform: translate(18px, 10px) rotate(-90.1deg); -} -.mblProg1 { - -webkit-transform: translate(22px, 11px) rotate(-60deg); - -moz-transform: translate(22px, 11px) rotate(-60deg); -} -.mblProg2 { - -webkit-transform: translate(25px, 14px) rotate(-30deg); - -moz-transform: translate(25px, 14px) rotate(-30deg); -} -.mblProg3 { - -webkit-transform: translate(26px, 18px) rotate(0deg); - -moz-transform: translate(26px, 18px) rotate(0deg); -} -.mblProg4 { - -webkit-transform: translate(25px, 22px) rotate(30deg); - -moz-transform: translate(25px, 22px) rotate(30deg); -} -.mblProg5 { - -webkit-transform: translate(22px, 25px) rotate(60deg); - -moz-transform: translate(22px, 25px) rotate(60deg); -} -.mblProg6 { - -webkit-transform: translate(18px, 26px) rotate(90.1deg); - -moz-transform: translate(18px, 26px) rotate(90.1deg); -} -.mblProg7 { - -webkit-transform: translate(14px, 25px) rotate(120deg); - -moz-transform: translate(14px, 25px) rotate(120deg); -} -.mblProg8 { - -webkit-transform: translate(11px, 22px) rotate(150deg); - -moz-transform: translate(11px, 22px) rotate(150deg); -} -.mblProg9 { - -webkit-transform: translate(10px, 18px) rotate(180deg); - -moz-transform: translate(10px, 18px) rotate(180deg); -} -.mblProg10 { - -webkit-transform: translate(11px, 14px) rotate(210deg); - -moz-transform: translate(11px, 14px) rotate(210deg); -} -.mblProg11 { - -webkit-transform: translate(14px, 11px) rotate(240deg); - -moz-transform: translate(14px, 11px) rotate(240deg); -} -.mblProg0Color { - background-color: #c0c0c0; -} -.mblProg1Color { - background-color: #c0c0c0; -} -.mblProg2Color { - background-color: #c0c0c0; -} -.mblProg3Color { - background-color: #c0c0c0; -} -.mblProg4Color { - background-color: #c0c0c0; -} -.mblProg5Color { - background-color: #c0c0c0; -} -.mblProg6Color { - background-color: #b8b9b8; -} -.mblProg7Color { - background-color: #aeafae; -} -.mblProg8Color { - background-color: #a4a5a4; -} -.mblProg9Color { - background-color: #9a9a9a; -} -.mblProg10Color { - background-color: #8e8e8e; -} -.mblProg11Color { - background-color: #838383; -} -.mblProgWhite .mblProg0Color { - background-color: #adb9c9; -} -.mblProgWhite .mblProg1Color { - background-color: #adb9c9; -} -.mblProgWhite .mblProg2Color { - background-color: #adb9c9; -} -.mblProgWhite .mblProg3Color { - background-color: #adb9c9; -} -.mblProgWhite .mblProg4Color { - background-color: #adb9c9; -} -.mblProgWhite .mblProg5Color { - background-color: #adb9c9; -} -.mblProgWhite .mblProg6Color { - background-color: #acb9cb; -} -.mblProgWhite .mblProg7Color { - background-color: #b7c2d2; -} -.mblProgWhite .mblProg8Color { - background-color: #c4cdda; -} -.mblProgWhite .mblProg9Color { - background-color: #d1d8e2; -} -.mblProgWhite .mblProg10Color { - background-color: #dee3ea; -} -.mblProgWhite .mblProg11Color { - background-color: #eceff3; -} diff --git a/apps/samples/vrml/viewer.html b/apps/samples/vrml/viewer.html deleted file mode 100644 index c585aaa..0000000 --- a/apps/samples/vrml/viewer.html +++ /dev/null @@ -1,177 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html> -<head> - <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> - <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/tundra/tundra.css"> - <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox/layout/resources/FloatingPane.css"> - <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox/layout/resources/ResizeHandle.css"> - <link rel="stylesheet" href="viewer.css"> - - <style type="text/css"> - .alternateDock { - position:absolute; - background-color:#ededed; - right:0px; top:0px; - border-left:1px solid #ccc; - height:100%; - - } - #alternateDock ul.dojoxDockList { display:block; } - .testFixedSize { - width:300px; - height:200px; - padding:7px; - } - - .dijitMenuItemLabel { - font-size: 12px; - } - - .tundra .dijitTooltipContainer { - background-color:rgba(200,200,200,0.5); - background:rgba(200,200,200,0.5); - } -/* .removeThumb { - background-image: url(img/close.png); - background-repeat: no-repeat; - background-size: 100%; - text-align: center; - border: 0px; - width: 20px; - height: 20px; - vertical-align: top; - margin: -3px 0px 0px -8px; - } -*/ </style> - - <script type="text/javascript"> - // dojoConfig = { - // async : false, - // isDebug : true, - // debugAtAllCosts : true, - // } - </script> - - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/osg.js"></script> - <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js"></script> - <script type="text/javascript" src="viewer-webgl.js"></script> - <script type="text/javascript" src="annotations.js"></script> - - <script type="text/javascript"> - - require(["dojo/domReady!", "dojo"], function(dom, dojo) { - // var viewer1 = new VRMLViewer("scene1", { - // pose: { - // pitch : 0, - // roll : 0, - // yaw : 0, - // zoom : 1, - // x : 0, - // y : 0, - // z : 0, - // autorotate : true - // }, - // height: 300, - // width: 400, - // enableMovies: false, - // enableDND: false, - // enableWebGL: true, - // enableSceneshots: false, - // enableDraggables: false, - // enablePosePublishing: true, - // listNavigationStyle: true, - // treeNavigationStyle: true, - // listDirectory: "10975/57", - // imagePath: "10975/57/latest", - // imageFormat: "png", - // serverURL: "http://femkit.smartvortex.eu:8086/vrml/", - // }); - - var vrmlViewer = new eu_smartvorex_femkit_ui_modelviewer.VRMLViewer("scene1", { - resRoot: "/img/tridi/", - enableMovies: false, - enableDND: false, - enableWebGL: true, - enableSceneshots: false, - enableDraggables: false, - listNavigationStyle: true, - treeNavigationStyle: true, - width: 550, - height: 550, - imagePath: "/10975/56/latest", - imageFormat: "png", - listDirectory: "/10975/56", - serverURL: "http://femkit.smartvortex.eu:8086/vrml", - }); - - // http://femkit.smartvortex.eu:8086/vrml/10975/57/latest.osgjs - - // var viewer2 = new VRMLViewer("scene2", { - // pose: { - // pitch : 0, - // roll : 0, - // yaw : 0, - // zoom : 1, - // x : 0, - // y : 0, - // z : 0, - // autorotate : true - // }, - // height: 300, - // width: 400, - // enableMovies: false, - // enableDND: false, - // enableWebGL: false, - // enableSceneshots: true, - // enableDraggables: false, - // enablePosePublishing: true, - // listNavigationStyle: false, - // treeNavigationStyle: false, - // listDirectory: "/cranehook/cranehook_bad_convergence", - // imagePath: "/cranehook/cranehook_bad_convergence/HARD_MP_VAL_000", - // imageFormat: "png", - // serverURL: "http://femkit.smartvortex.eu:8086/vrml/", - // }); - - // setTimeout(function() { - // setInterval(function(){ - // var pose1 = viewer1.getPose(); - // var pose2 = viewer2.getPose(); - // console.log("Pose1 - pitch: " + pose1.pitch + ", roll: " + pose1.roll + ", yaw: " + pose1.yaw); - // console.log("Pose2 - pitch: " + pose2.pitch + ", roll: " + pose2.roll + ", yaw: " + pose2.yaw); - // - // pose1.pitch += 0.1; - // pose2.pitch += 0.1; - // - // pose1.roll += 0.2; - // pose2.roll += 0.2; - // - // pose1.yaw += 0.4; - // pose2.yaw += 0.4; - // - // viewer1.setPose(pose2); - // viewer2.setPose(pose2); - // - // }, 400); - // }, 1000); - }); - - - </script> - </head> - <body class="tundra"> - <table align="center"> - <tr> - <td ><br /><br /><br /><br /><br /><br /> - <div id="scene1" /> - </td> - <td><br /><br /><br /><br /><br /><br /> - <div id="scene2" /> - </td> - </tr> - <tr><td> - <div id="annotations1"></div> - </td></tr> - </table> - </body> -</html> diff --git a/apps/samples/vrml/viewer.js b/apps/samples/vrml/viewer.js deleted file mode 100644 index 4b59a8c..0000000 --- a/apps/samples/vrml/viewer.js +++ /dev/null @@ -1,984 +0,0 @@ -function VRMLViewer(element, params) { - - // private attributes - var self = this; - var batchChanges = false; - - // private instanceId - if (!VRMLViewer.instances) - VRMLViewer.instances = 0; - this.instanceId = VRMLViewer.instances++; - - // public attribute defaults - this.width = 450; - this.height = 350; - - { - var pose = { - pitch: 0, - roll: 0, - yaw: 0, - zoom: 1, - x: 0, - y: 0, - z: 0, - width: this.width, - height: this.height, - autorotate: false, - } - this.pose = pose; - } - - this.enableMovies = true; - this.enableDND = true; - this.modelNavigationStyle = "tree"; // tree, list, none - this.poseNavigationStyle = "draggables"; // draggables, sliders - this.listDirectory = ""; - this.serverURL = "localhost:8080"; - this.imagePath = ""; - this.resRoot = ""; - - // copy over values from constructor arguments - if (params) { - for (var param in params) { - if (self.hasOwnProperty(param)) - self[param] = params[param]; - } - } - - // normalize parameters - - // make sure server url begins with protocol and does *not* ends in / - if (!self.serverURL.substring(0, 7) == "http://" && - !self.serverURL.substring(0, 8) == "https://") - self.serverURL = "http://" + self.serverURL; - if (!self.serverURL.lastIndexOf("/") === self.serverURL.length) - self.serverURL += self.serverURL.substring(0, self.serverURL - 1); - - // make sure we have a listDirectory with navigation style list ending in / - if (self.modelNavigationStyle === "list" && !self.listDirectory && self.imagePath) - self.listDirectory = self.imagePath.substring(0, self.imagePath.lastIndexOf("/")); - if (!self.listDirectory.indexOf("/", self.listDirectory.length - 1) !== -1) - self.listDirectory += "/"; - - // use latest image if none given - if (!self.imagePath) - self.imagePath = self.listDirectory + "latest.png"; - - // privileged public methods - this.updateScene = function() { - if (self.serverURL && self.imagePath && !self.batchChanges) { - self.imgElem.src = self.serverURL + self.imagePath + urlSuffixForPose(self.pose); - if (self.enableMovies) { - // we are showing an image, activate movie controls - self.movieAddButton.domNode.style.display = ""; - self.movieDropDown.domNode.style.display = ""; - } - } - }; - - var urlSuffixForPose = function(pose) { - var queryString = - '?width=' + pose.width + - '&height=' + pose.height + - '&pitch=' + pose.pitch + - '&roll=' + pose.roll + - '&yaw=' + pose.yaw + - '&x=' + pose.x + - '&y=' + pose.y + - '&z=' + pose.z + - '&zoom=' + pose.zoom + - '&autorotate=' + (pose.autorotate ? '1' : '0'); - return queryString; - }; - - var moverRelativeTo = function(mover, container) { - var containerPos = absolutePosition(container); - return { - x: mover.x - containerPos.x, - y: mover.y - containerPos.y - }; - }; - - // see http://stackoverflow.com/questions/288699/get-the-position-of-a-div-span-tag - var absolutePosition = function(el) { - for (var lx=0, ly=0; el != null; lx += el.offsetLeft, ly += el.offsetTop, el = el.offsetParent); - return {x: lx,y: ly}; - }; - - this.populateMovieCodecs = function(server, selectElem) { - self.xhr.get({ - // The URL to request - url: server, - handleAs:"json", - headers:{"X-Requested-With":null}, - load: function(result) { - for (var codec in result.video) { - if (codec !== "mpeg1video" && - codec !== "mpeg2video" && - codec !== "mpeg4" && - codec !== "h264" && - codec !== "ayuv" && - codec !== "flashsv" && - codec !== "flashsv2" && - codec !== "flv" && - codec !== "rv40" && - codec !== "theora" && - codec !== "v210" && - codec !== "v308" && - codec !== "v408" && - codec !== "v410" && - codec !== "wmv3" && - codec !== "y41p" && - codec !== "yuv4") - continue; - //console.log(codec); - selectElem.options.push({ label: result.video[codec].longName, value: codec }); - if (codec === "mpeg4") - selectElem.options[selectElem.options.length - 1].selected = true; - } - } - }); - } - - this.setServer = function(serverURL) { - if (!serverURL || serverURL == self.serverURL) { - // nothing to do - return; - } - - self.serverURL = serverURL; - if (self.fileStandby) { self.fileStandby.show(); } - - self.xhr.get({ - // The URL to request - url: serverURL, - handleAs:"json", - headers:{"X-Requested-With":null}, - error: function(result) { - - if (self.browseButton) { self.browseButton.setAttribute('label', 'Browse'); } - if (self.fileStandby) { self.fileStandby.hide(); } - var allItems = self.fileStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileStore.remove(allItems[i].id); - } - }, - load: function(result) { - self.localStorage.put("vrmlServer", self.serverURL, null); - if (self.browseButton) { self.browseButton.setAttribute('label', 'Refresh'); } - if (self.fileStandby) { self.fileStandby.hide(); } - - // empty store - var allItems = self.fileStore.query(); - for (var i = 0; i < allItems.total; i++) { - self.fileStore.remove(allItems[i].id); - } - - if (self.modelNavigationStyle === "tree") { - - // parse result as tree - (function fillstore(tree, parentId) { - // todo: respect navigation style - for (key in tree) { - if ('url' in tree[key]) { - self.fileStore.add({id:parentId+key, name:key, url:self.serverURL + tree[key].path, parent:parentId}); - } else { - self.fileStore.add({id:parentId+key, name:key, parent:parentId}); - fillstore(tree[key], parentId+key); - } - } - } (result.models, "root", "")); - } else if (self.modelNavigationStyle === "list") { - - // parse result as list - if (!self.listDirectory) - console.log("Requested modelNavigationStyle === list but provided no listDirectory"); - var dirs = self.listDirectory.split("/"); - var models = result.models; - for (var dir in dirs) { - if (!dirs[dir].length) - continue; - if (dirs[dir] in models) { - models = models[dirs[dir]]; - } else { - console.log("No " + dirs[dir] + " in " + models); - } - } - for (var key in models) { - var url = self.serverURL + models[key].path; - self.fileStore.add({id:key, value:url, label:key, name:key, url:url}); - } - self.fileListSelect.startup(); - } - - self.updateScene(); - } - }); - }; - - this.setModel = function(imagePath) { - self.imagePath = imagePath; - } - - this.setPose = function(imagePath, pose, serverURL) { - if (serverURL && serverURL != self.serverURL) { - self.refreshServer(serverURL); - } - self.imagePath = imagePath; - self.pose = pose; - - var pitch = (pose.pitch % (2 * 3.14159) + 0.5) * 100; - var roll = (pose.roll % (2 * 3.14159) + 0.5) * 100; - var yaw = (pose.yaw % (2 * 3.14159) + 0.5) * 100; - - var x = ((pose.x / 100) + 0.5) * 100; - var y = ((pose.y / 100) + 0.5) * 100; - - var zoom = (((pose.zoom - 1) / 3) + 0.5) * 100; - - self.pitchRollHandlerElem.parentNode.style.right = pitch + "%"; - self.pitchRollHandlerElem.parentNode.style.top = roll + "%"; - self.yawZoomHandlerElem.parentNode.style.right = yaw + "%"; - self.yawZoomHandlerElem.parentNode.style.top = zoom + "%"; - self.xyHandlerElem.parentNode.style.right = x + "%"; - self.xyHandlerElem.parentNode.style.top = y + "%"; - - self.updateScene(); - }; - - require(["dojo/dom-construct", - "dojo/_base/xhr", - "dojo/dom", - "dojo/on", - "dojox/storage", - "dojo/store/Memory", - "dojo/store/Observable", - "dijit/tree/ObjectStoreModel", - "dojo/data/ObjectStore", - "dijit/Tree", - "dijit/form/TextBox", - "dijit/form/Button", - "dojox/widget/Standby", - "dijit/form/DropDownButton", - "dijit/TooltipDialog", - "dojo/dnd/Moveable", - "dojo/ready", - "dojo/dnd/Source", - "dijit/form/HorizontalSlider", - "dijit/form/Select", - "dijit/form/NumberSpinner"], - function(domConst, - xhr, - dom, - on, - storage, - Memory, - Observable, - ObjectStoreModel, - ObjectStore, - Tree, - TextBox, - Button, - Standby, - DropDownButton, - TooltipDialog, - Moveable, - ready, - Source, - HorizontalSlider, - Selector, - NumberSpinner) { - - ready(function() { - - if (typeof(element) === 'string') { - element = dom.byId(element); - } - element.style.height = self.pose.height; - element.style.width = self.pose.width; - - self.element = element; - self.xhr = xhr; - self.localStorage = dojox.storage.manager.getProvider(); - self.localStorage.initialize(); - - // establish our dom - element.appendChild(domConst.toDom('\ - <table>\ - <tr>\ - <td valign="top">\ - <div style="position: relative; padding: 0px">\ - <img class="model" src="' + self.resRoot + 'img/Tutorial.png" style="z-index: -1; width: ' + self.pose.width + 'px; height: ' + self.pose.height + 'px"></img>\ - <div style="z-index: 1; position: absolute; right: 45%; top: 45%">\ - <div class="progress"></div>\ - </div>\ - <div style="position: absolute; left: 10px; top: 10px">\ - <table></tr>\ - <td class="filesDropDown" style="vertical-align: middle"></td>\ - <td class="movieControls">\ - <div class="movieDropDown" style="display: inline"></div>\ - <button type="button" class="movieAddButton"></button>\ - </td>\ - <td align="right"><button type="button" class="resetButton"></button></td>\ - <td class="dragHandler" style="vertical-align: middle; padding-top: 4px;"></td>\ - </tr></table>\ - </div>\ - <div style="position: absolute; right: 10px; top: 15%; height: 50%">\ - <div class="zoomSlide"></div>\ - </div>\ - <div style="position: absolute; right: 50%; top: 50%">\ - <div class="pitchRollHandler" style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px;">\ - <table>\ - <tr>\ - <td><img class="pitchRollHandlerImg" src="' + self.resRoot + 'img/pitchRoll-handle.png" height="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="pitchLabel"></div><div class="rollLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - <div style="position: absolute; right: 50%; top: 50%">\ - <div class="yawZoomHandler">\ - <div style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px; position: absolute; left: -34px;">\ - <table>\ - <tr>\ - <td><img class="yawZoomHandlerImg" src="' + self.resRoot + 'img/yawZoom-handle.png" height="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="yawLabel"></div><div class="zoomLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - </div>\ - <div style="position: absolute; right: 50%; top: 50%">\ - <div class="xyHandler" style="font-size: 0.5em; background-color: rgba(255,255,255,0.5); border-radius: 5px; moz-border-radius: 5px;">\ - <table>\ - <tr>\ - <td><img class="xyHandlerImg" src="' + self.resRoot + 'img/xy-handle.png" width="20px" style="padding: 2px 0px 0px 4px;" /></td>\ - <td><div class="xLabel"></div><div class="yLabel"></div></td>\ - </tr>\ - </table>\ - </div>\ - </div>\ - <div class="listNavigation" style="position: absolute; left: 10px; bottom: 10px">\ - <table></tr>\ - <td style="vertical-align: middle"><button class="prevButton" type="button" /></td>\ - <td style="vertical-align: middle"><div class="fileList" /></td>\ - <td style="vertical-align: middle"><button class="nextButton" type="button" /></td>\ - </tr></table>\ - </div>\ - </div>\ - </td>\ - <td valign="top" height="100%">\ - </td>\ - </tr>\ - <tr>\ - <td colspan="2"><div class="messages"></div></td>\ - </tr>\ - </table>\ - ')); - - // fetch special dom nodes for content - self.messageBox = dojo.query("div.messages", element)[0]; - self.imgElem = dojo.query("img.model", element)[0]; - - /** - * === POSE MANIPULATION AND RESET ==================== - */ - - self.resetButtonElem = dojo.query("button.resetButton", element)[0]; - self.progressElem = dojo.query("div.progress", element)[0]; - - self.pitchRollHandlerElem = dojo.query(".pitchRollHandler", element)[0]; - self.yawZoomHandlerElem = dojo.query(".yawZoomHandler", element)[0]; - self.xyHandlerElem = dojo.query(".xyHandler", element)[0]; - - self.pitchRollHandler = new Moveable(self.pitchRollHandlerElem); - self.pitchRollHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.pitchRollHandlerImg", mover.node)[0]; - var pitchLabel = dojo.query("div.pitchLabel", mover.node)[0]; - var rollLabel = dojo.query("div.rollLabel", mover.node)[0]; - - pitchLabel.innerHTML = ''; - rollLabel.innerHTML = ''; - - self.updateScene(); - }; - self.pitchRollHandler.onMoving = function(mover) { - // mover.node.style.backgroundColor = "rgba(255,255,255,0.5)"; - // mover.node.style.borderRadius = "5px"; - // mover.node.style.mozBorderRadius = "5px"; - // mover.node.style.webkitBorderRadius = "5px"; - var handlerImg = dojo.query(".pitchRollHandlerImg", mover.node)[0]; - var pitchLabel = dojo.query(".pitchLabel", mover.node)[0]; - var rollLabel = dojo.query(".rollLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 30; - offset.y += 20; - - self.xyHandlerElem.style.zIndex = 1; - self.yawZoomHandlerElem.style.zIndex = 1; - self.pitchRollHandlerElem.style.zIndex = 2; - - // self.pose.pitch = self.pose.pitch % (2 * 3.14159); - // self.pose.roll = self.pose.roll % (2 * 3.14159); - self.pose.roll = offset.x / self.pose.width - 0.5; - self.pose.pitch = offset.y / self.pose.height - 0.5; - self.pose.pitch *= -1; - self.pose.roll *= 2 * 3.14159; - self.pose.pitch *= 2 * 3.14159; - self.pose.roll = Math.ceil((self.pose.roll) * 10) / 10; - self.pose.pitch = Math.ceil((self.pose.pitch) * 10) / 10; - pitchLabel.innerHTML = 'Pitch:' + self.pose.pitch; - rollLabel.innerHTML = 'Roll:' + self.pose.roll; - }; - - self.yawZoomHandler = new Moveable(self.yawZoomHandlerElem); - self.yawZoomHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.yawZoomHandlerImg", mover.node)[0]; - var yawLabel = dojo.query("div.yawLabel", mover.node)[0]; - var zoomLabel = dojo.query("div.zoomLabel", mover.node)[0]; - - yawLabel.innerHTML = ''; - zoomLabel.innerHTML = ''; - - self.updateScene(); - }; - self.yawZoomHandler.onMoving = function(mover) { - var handlerImg = dojo.query("img.yawZoomHandlerImg", mover.node)[0]; - var yawLabel = dojo.query("div.yawLabel", mover.node)[0]; - var zoomLabel = dojo.query("div.zoomLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 7; - offset.y += 9; - - self.xyHandlerElem.style.zIndex = 1; - self.yawZoomHandlerElem.style.zIndex = 2; - self.pitchRollHandlerElem.style.zIndex = 1; - - // self.pose.pitch = self.pose.pitch % (2 * 3.14159); - // self.pose.roll = self.pose.roll % (2 * 3.14159); - self.pose.yaw = (self.pose.width - offset.x) / self.pose.width - 0.5; - self.pose.zoom = offset.y / self.pose.height - 0.5; - self.pose.yaw *= 2 * 3.14159; - self.pose.zoom = self.pose.zoom * 3 + 1; - self.pose.zoom = Math.ceil((self.pose.zoom) * 10) / 10; - self.pose.yaw = Math.ceil((self.pose.yaw) * 10) / 10; - yawLabel.innerHTML = 'Yaw:' + self.pose.yaw; - zoomLabel.innerHTML = 'Zoom:' + self.pose.zoom; - }; - - self.xyHandler = new Moveable(self.xyHandlerElem); - self.xyHandler.onMoveStop = function(mover) { - var handlerImg = dojo.query("img.xyHandlerImg", mover.node)[0]; - var xLabel = dojo.query("div.xLabel", mover.node)[0]; - var yLabel = dojo.query("div.yLabel", mover.node)[0]; - - xLabel.innerHTML = ''; - yLabel.innerHTML = ''; - - self.updateScene(); - }; - self.xyHandler.onMoving = function(mover) { - var handlerImg = dojo.query("img.xyHandlerImg", mover.node)[0]; - var xLabel = dojo.query("div.xLabel", mover.node)[0]; - var yLabel = dojo.query("div.yLabel", mover.node)[0]; - var offset = moverRelativeTo(handlerImg, self.element); - - offset.x += 3; - offset.y += 13; - - self.xyHandlerElem.style.zIndex = 2; - self.yawZoomHandlerElem.style.zIndex = 1; - self.pitchRollHandlerElem.style.zIndex = 1; - - self.pose.x = offset.x / self.pose.width - 0.5; - self.pose.y = offset.y / self.pose.height - 0.5; - self.pose.x *= 100; - self.pose.y *= 100; - self.pose.y = Math.ceil((self.pose.y) * 10) / 10; - self.pose.x = Math.ceil((self.pose.x) * 10) / 10; - xLabel.innerHTML = 'X:' + self.pose.x; - yLabel.innerHTML = 'Y:' + self.pose.y; - }; - - - /** - * === DRAG HANDLER ==================== - */ - if (self.enableDND) { - self.createAvatar = function(item, mode) { - if (mode == 'avatar') { - // create your avatar if you want - var avatar = dojo.create( 'div', { innerHTML: item.data }); - var avatarPose = dojo.clone(self.pose); - avatarPose.width=60; - avatarPose.height=60; - var avatarImgUrl = urlSuffixForPose(avatarPose); - avatar.innerHTML = '<img src=' + self.imagePath + avatarImgUrl + ' /> '; - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.imagePath + avatarImgUrl; - item.imagePath = self.imagePath; - item.serverURL = self.serverURL; - item.pose = avatarPose; - return {node: avatar, data: item, type: item.type}; - } - var handler = dojo.create( 'div', { innerHTML: '<img src="' + self.resRoot + 'img/drag.png" width="20px" />' }); - return {node: handler, data: item, type: item.type}; - }; - - self.dragHandler = new Source(dojo.query("td.dragHandler", element)[0], {copyOnly: true, creator: self.createAvatar}); - self.dragHandler.insertNodes(false, [ { } ]); - } - - /** - * === FILE NAVIGATION ==================== - */ - - if (self.modelNavigationStyle !== 'none') { - if (self.modelNavigationStyle === 'list') { - - // setup fileStore - self.fileStore = new Observable(new Memory({ - data: [], - })); - - self.prevButtonElem = dojo.query("button.prevButton", element)[0]; - self.nextButtonElem = dojo.query("button.nextButton", element)[0]; - self.fileListElem = dojo.query("div.fileList", element)[0]; - - var os = new ObjectStore({ objectStore: self.fileStore }); - - self.fileListSelect = new Selector({ - store: os, - onChange: function(name) { - var item = self.fileStore.query({ id: name })[0]; - self.imagePath = self.listDirectory + item.name + ".png"; - self.updateScene(); - } - }, self.fileListElem); - - self.prevButton = new Button({ - label: "<", - onClick: function() { - var allItems = self.fileStore.query(); - var foundAt = 0; - for (var i = 0; i < allItems.total; i++) { - //console.log(self.serverURL + self.imagePath + " === " + allItems[i].url); - if (self.serverURL + self.imagePath === allItems[i].url) { - foundAt = i; - break; - } - } - - if (foundAt > 0) { - self.imagePath = self.listDirectory + allItems[foundAt - 1].name + ".png"; - self.fileListSelect.attr( 'value', allItems[foundAt - 1].id ); - if (self.serverURL + self.imagePath !== allItems[foundAt - 1].url) - console.log(self.serverURL + self.imagePath + " !== " + allItems[foundAt - 1].url); - self.updateScene(); - } - } - }, self.prevButtonElem); - - self.nextButton = new Button({ - label: ">", - onClick: function() { - var allItems = self.fileStore.query(); - var foundAt = 0; - for (var i = 0; i < allItems.total; i++) { - //console.log(self.serverURL + self.imagePath + " === " + allItems[i].url); - if (self.serverURL + self.imagePath === allItems[i].url) { - foundAt = i; - break - } - } - if (foundAt + 1 < allItems.total) { - self.imagePath = self.listDirectory + allItems[foundAt + 1].name + ".png"; - self.fileListSelect.attr( 'value', allItems[foundAt + 1].id ); - if (self.serverURL + self.imagePath !== allItems[foundAt + 1].url) - console.log(self.serverURL + self.imagePath + " !== " + allItems[foundAt + 1].url); - self.updateScene(); - } - } - }, self.nextButtonElem); - - } else { - - // setup fileStore - self.fileStore = new Observable(new Memory({ - data: [ { id: 'root', name:'3D Models'} ], - getChildren: function(object){ - return this.query({parent: object.id}); - } - })); - - self.fileTreeModel = new ObjectStoreModel({ - store: self.fileStore, - query: { id: "root" } - }); - - // setup actual tree dijit - self.fileList = new dijit.Tree({ - id: "fileList" + self.instanceId, - model: self.fileTreeModel, - persist: false, - showRoot: false, - style: "height: 300px;", - onClick: function(item){ - if ('url' in item) { - self.imagePath = item.url; - self.updateScene(); - } - }, - getIconClass: function(item, opened) { - return (!item || !('url' in item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"; - }, - getIconStyle: function(item, opened){ - if('url' in item) { - return { backgroundImage: "url('" + item.url + "?width=16&height=16')"}; - } - } - //return {backgroundImage: "url('" + item.url + "?width=16&height=16')"}; - }); - - self.filesDropDownElem = dojo.query("td.filesDropDown", element)[0]; - - self.serverBox = new TextBox({ - name: "Server", - value: self.serverURL, - style: "width: 65%", - - onKeyUp: function(e) { - if (self.browseButton) { - if (this.get("value") !== self.serverURL) { - self.browseButton.setAttribute('label', 'Browse'); - } else { - self.browseButton.setAttribute('label', 'Refresh'); - } - } - }, - - onKeyDown: function(e) { - var code = e.keyCode || e.which; - if( code === 13 ) { - e.preventDefault(); - self.refreshServer(this.get("value")); - return false; - } - }, - }); - - self.browseButton = new Button({ - label: "Browse", - onClick: function(){ - self.refreshServer(self.serverBox.get("value")); - } - }); - - self.filesDropDownContent = domConst.toDom('<div />'); - self.filesDropDownContent.appendChild(self.serverBox.domNode); - self.filesDropDownContent.appendChild(self.browseButton.domNode); - self.filesDropDownContent.appendChild(self.fileList.domNode); - - self.filesToolTip = new TooltipDialog({ content:self.filesDropDownContent, style:"max-height:320px"}); - self.filesDropDown = new DropDownButton({ label: "Files", dropDown: self.filesToolTip }); - self.filesDropDownElem.appendChild(self.filesDropDown.domNode); - - self.fileStandby = new Standby({target: self.filesDropDownContent }); - self.filesDropDownContent.appendChild(self.fileStandby.domNode); - } - } - - var savedServerURL = self.localStorage.get("vrmlServer"); - if (savedServerURL && !self.serverURL) { - self.serverURL = savedServerURL; - } - if (self.serverURL) { - self.refreshServer(self.serverURL); - } - /** - * === MOVIE DROPDOWN ==================== - */ - - if (self.enableMovies) { - self.movieDropDownElem = dojo.query("div.movieDropDown", element)[0]; - self.movieAddButtonElem = dojo.query("button.movieAddButton", element)[0]; - - self.movieDropDownContent = domConst.toDom( - '<div style="overflow: auto; max-height: 420px;"> \ - <table><tr class="movieFormatLengthRow" /></tr><tr class="movieWidthHeightLengthRow" /></table> \ - <div class=\"dndArea\" /> \ - </div>' - ); - - self.movieFormatLengthRowElem = dojo.query("tr.movieFormatLengthRow", self.movieDropDownContent)[0]; - self.movieWidthHeightLengthRowElem = dojo.query("tr.movieWidthHeightLengthRow", self.movieDropDownContent)[0]; - self.movieDnDArea = dojo.query("div.dndArea", self.movieDropDownContent)[0]; - - self.createMovieThumb = function(item, mode) { - if (mode == 'avatar') { - // when dragged - var avatar = dojo.create( 'div', { innerHTML: item.data }); - var avatarPose = dojo.clone(self.pose); - avatarPose.width = 60; - avatarPose.height = 60; - var avatarImgUrl = urlSuffixForPose(avatarPose); - avatar.innerHTML = '<img src=' + self.imagePath + avatarImgUrl + ' /> '; - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.imagePath + avatarImgUrl; - item.imagePath = self.imagePath; - item.serverURL = self.serverURL; - item.pose = avatarPose; - return {node: avatar, data: item, type: item.type}; - } else { - - // when added to list - var thumb = domConst.toDom("\ - <div>\ - <table><tr><td>\ - <img class=\"movieThumb\"/>\ - <img class=\"removeThumb\" style=\"vertical-align: top; margin: -3px 0px 0px -8px; width: 20px; height: 20px;\"/>\ - </td><td align=\"left\">\ - <table><tr>\ - <td>Frame:</td><td><div class=\"relFrameLength\"/></td>\ - <td><div class=\"fillInSeries\" \></td>\ - </tr><tr>\ - <td>Transition:</td><td><div class=\"relTransitionLength\"/></td>\ - </tr></table>\ - </td></tr></table>\ - </div>\ - "); - thumb = dojo.query("div", thumb)[0]; - - var thumbImgElem = dojo.query("img.movieThumb", thumb)[0]; - var removeImgElem = dojo.query("img.removeThumb", thumb)[0]; - var relFrameLengthElem = dojo.query("div.relFrameLength", thumb)[0]; - var relTransitionLengthElem = dojo.query("div.relTransitionLength", thumb)[0]; - var fillInSeriesElem = dojo.query("div.fillInSeries", thumb)[0]; - - item.getThisAndNeighborsFromDnD = function() { - var thisAndNeighbors = {}; - self.addToMovieHandler.forInItems(function(obj, key, ctx) { - if (obj.data === item) { - thisAndNeighbors.this = { key: key, obj: obj }; - } else { - thisAndNeighbors.before = { key: key, obj: obj }; - } - if (thisAndNeighbors.this) { - thisAndNeighbors.after = { key: key, obj: obj }; - return thisAndNeighbors; - } - }); - return thisAndNeighbors; - }; - - item.relFrameLengthSlider = new HorizontalSlider({ - value: 50, - title: "Relative Duration of Frame", - style: "width:150px;" - }, relFrameLengthElem); - - item.relTransitionLengthSlider = new HorizontalSlider({ - value: 100, - title: "Relative Duration of Transition", - style: "width:150px;" - }, relTransitionLengthElem); - - removeImgElem.onclick = function() { - var thisItem = item.getThisAndNeighborsFromDnD(); - if (thisItem.this) { - // haha - what a mess! - self.addToMovieHandler.selectNone(); - self.addToMovieHandler.selection[thisItem.this.key] = thisItem.this.obj; - self.addToMovieHandler.deleteSelectedNodes(); - } - // disable create button if this was the last one - if (!thisItem.after || !thisItem.before) { - self.movieCreateButton.setAttribute('disabled', true); - } - } - - item.fillInSeriesButton = new Button({ - label: "Insert Series", - style: "display: none;", - onClick: function(){ - alert("foo"); - } - }, fillInSeriesElem); - - removeImgElem.src = self.resRoot + "img/close.png"; - - var thumbPose = dojo.clone(self.pose); - thumbPose.width = self.pose.width / 10; - thumbPose.height = self.pose.height / 10; - var thumbImgUrl = urlSuffixForPose(thumbPose); - - thumbImgElem.src = self.imagePath + thumbImgUrl; - // removeImgElem.src = self.resRoot + 'img/close.png'; - - item.srcEcc = "VRMLViewer"; - item.iconPoseUrl = self.imagePath + thumbImgUrl; - item.imagePath = self.imagePath; - item.serverURL = self.serverURL; - item.pose = thumbPose; - - return {node: thumb, data: item, type: item.type}; - } - }; - - self.addToMovieHandler = new Source(self.movieDnDArea, {copyOnly: true, creator: self.createMovieThumb}); - - self.movieFormatSelection = new Selector({ - name: "movieFormat", - style: "width: 320px", - options: [] - }); - self.populateMovieCodecs("http://" + self.serverURL + '/movie/codecs', self.movieFormatSelection); - - self.movieFormatLengthRowElem.appendChild(dojo.create('td', { innerHTML: 'Format:'} )); - self.movieFormatLengthRowElem.appendChild(dojo.create('td', { colspan: "2"})); - self.movieFormatLengthRowElem.lastChild.appendChild(self.movieFormatSelection.domNode); - - self.movieHeightSpinner = new NumberSpinner({ - value: 400, - smallDelta: 1, - style: "width: 60px", - constraints: { min:40, places:0 }, - }); - - self.movieWidthSpinner = new NumberSpinner({ - value: 600, - smallDelta: 1, - style: "width: 60px", - constraints: { min:40, places:0 }, - }); - - self.movieCreateButton = new Button({ - label: "Create", - disabled: true, - onClick: function(){ - - var form = document.createElement("form"); - - form.setAttribute("method", "post"); - form.setAttribute("action", self.serverURL + "/movie"); - - var submitData = {}; - submitData.frames = []; - submitData.movieLength = self.movieDurationSpinner.value; - submitData.format = self.movieFormatSelection.value; - submitData.width = self.movieWidthSpinner.value; - submitData.height = self.movieHeightSpinner.value; - - self.addToMovieHandler.forInItems(function(obj, key, ctx) { - var jsonData = { - iconPoseUrl: obj.data.iconPoseUrl, - imagePath: obj.data.imagePath, - serverURL: obj.data.serverURL, - pose: obj.data.pose, - relFrameLength: obj.data.relFrameLengthSlider.value, - relTransitionLength: obj.data.relTransitionLengthSlider.value, - } - submitData.frames.push(jsonData); - }); - - var hiddenField = document.createElement("input"); - hiddenField.setAttribute("type", "hidden"); - hiddenField.setAttribute("name", "data"); - hiddenField.setAttribute("value", JSON.stringify(submitData)); - - form.appendChild(hiddenField); - - // this will not save the returned binary file - // self.xhr.post({ - // form: form, - // load: function(data){ - // alert("asd"); - // } - // }); - - document.body.appendChild(form); - form.submit(); - document.body.removeChild(form); - } - }); - - self.movieDurationSpinner = new NumberSpinner({ - value: 10, - smallDelta: 1, - style: "width: 40px", - constraints: { min:0, places:0 }, - }); - - // append format duration cell - self.movieWidthHeightLengthRowElem.appendChild(dojo.create('td', { innerHTML: 'Size:'} )); - var movieDimensionCell = dojo.create('td'); - movieDimensionCell.appendChild(self.movieWidthSpinner.domNode); - movieDimensionCell.appendChild(dojo.create('span', { innerHTML: "x"} )); - movieDimensionCell.appendChild(self.movieHeightSpinner.domNode); - movieDimensionCell.appendChild(self.movieDurationSpinner.domNode); - movieDimensionCell.appendChild(dojo.create('span', { innerHTML: "sec"} )); - self.movieWidthHeightLengthRowElem.appendChild(movieDimensionCell); - - self.movieWidthHeightLengthRowElem.appendChild(dojo.create('td', { align: "right"})); - self.movieWidthHeightLengthRowElem.lastChild.appendChild(self.movieCreateButton.domNode); - - - self.movieToolTip = new TooltipDialog({ content:self.movieDropDownContent }); - self.movieDropDown = new DropDownButton({ - label: "Movie", - style: "display: none;", - dropDown: self.movieToolTip }); - self.movieDropDownElem.appendChild(self.movieDropDown.domNode); - - self.movieAddButton = new Button({ - label: "+", - style: "margin-left: -10px; display: none;", - onClick: function(){ - if (self.movieFormatSelection.options.length == 0) { - self.populateMovieCodecs(self.serverURL + '/movie/codecs', self.movieFormatSelection); - } - // we could pass item.data here to creator - self.addToMovieHandler.insertNodes(false, [ { } ]); - self.movieCreateButton.setAttribute('disabled', false); - - } - }, self.movieAddButtonElem); - } else { - // remove movie controls - var movieControls = dojo.query("td.movieControls", element)[0]; - movieControls.parentNode.removeChild(movieControls); - } - - self.resetButton = new Button({ - label: "Reset", - onClick: function(){ - self.pose.x = 0; - self.pose.y = 0; - self.pose.pitch = 0; - self.pose.roll = 0; - self.pose.yaw = 0; - self.pose.zoom = 1; - - self.xyHandler.node.style.left = 0; - self.xyHandler.node.style.top = 0; - self.pitchRollHandler.node.style.left = 0; - self.pitchRollHandler.node.style.top = 0; - self.yawZoomHandler.node.style.left = 0; - self.yawZoomHandler.node.style.top = 0; - - self.updateScene(); - } - }, self.resetButtonElem); - - // do we have parameters for the initial pose? - if(self.params && self.params.pose) - self.setPose(self.params.imagePath, self.params.pose, self.params.serverURL); - - }); - }); - - -} diff --git a/apps/samples/vrml/vrml-server.caching.scxml b/apps/samples/vrml/vrml-server.caching.scxml deleted file mode 100644 index 2d935cd..0000000 --- a/apps/samples/vrml/vrml-server.caching.scxml +++ /dev/null @@ -1,416 +0,0 @@ -<scxml datamodel="ecmascript" name="vrml"> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string. .js" /> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/array.last.js" /> - <script> - var wrls = {}; // information of the wrl, vrml files - var models = {}; // information of the osgb files - var processed = {}; // information about processed files - - var pathDelim = ':'; // we need to flatten directories - this will seperate them in filenames - - /** - * This pattern matches the query string we use as part of generated image filenames - */ - var numPattern = '(-?[0-9]+\.?[0-9]*)'; - var formatPattern = new RegExp( - '-(' + numPattern + // pitch - '_' + numPattern + // roll - '_' + numPattern + // yaw - '_' + numPattern + // zoom - '_' + numPattern + // x - '_' + numPattern + // y - '_' + numPattern + // z - '_' + numPattern + // width - '_' + numPattern + // height - '_(off|on)' + // autorotate - ')\\.\\w+$'); // end - - /** - * Transform a file we found into a processed or model struct - */ - function fileToStruct(file) { - var struct = {}; - var formatMatch = formatPattern.exec(file.name); - // is this a processed file? - if (formatMatch && formatMatch.length == 12) { - struct.key = file.relDir.replace(/\//g, pathDelim).substr(1) + file.name.substr(0, file.name.length - formatMatch[0].length); - struct.format = formatMatch[1] + '.' + file.extension; - struct.pitch = parseFloat(formatMatch[2]); - struct.roll = parseFloat(formatMatch[3]); - struct.yaw = parseFloat(formatMatch[4]); - struct.zoom = parseFloat(formatMatch[5]); - struct.x = parseFloat(formatMatch[6]); - struct.y = parseFloat(formatMatch[7]); - struct.z = parseFloat(formatMatch[8]); - struct.width = parseFloat(formatMatch[9]); - struct.height = parseFloat(formatMatch[10]); - struct.autorotate = parseFloat(formatMatch[11]); - } else { - struct.key = file.relDir.replace(/\//g, pathDelim).substr(1) + file.strippedName; - } - return struct; - } - - /** - * Transform a http request into something to look up in the processed structure - */ - function reqToStruct(req) { - var struct = {}; - - var query = (('query' in req) ? req.query : {}); - - struct.pitch = (('pitch' in query && isNumber(query.pitch)) ? query.pitch : 0); - struct.roll = (('roll' in query && isNumber(query.roll)) ? query.roll : 0); - struct.yaw = (('yaw' in query && isNumber(query.yaw)) ? query.yaw : 0); - struct.zoom = (('zoom' in query && isNumber(query.zoom)) ? query.zoom : 1); - struct.x = (('x' in query && isNumber(query.x)) ? query.x : 0); - struct.y = (('y' in query && isNumber(query.y)) ? query.y : 0); - struct.z = (('z' in query && isNumber(query.z)) ? query.z : 0); - struct.width = (('width' in query && isNumber(query.width)) ? query.width : 640); - struct.height = (('height' in query && isNumber(query.height)) ? query.height : 480); - struct.autorotate = (('autorotate' in query && (query.autorotate === 'on' || query.autorotate === 'off')) ? query.autorotate : 'on'); - - var fileComp = req.pathComponent[req.pathComponent.length - 1]; - struct.file = fileComp.substr(0, fileComp.indexOf('.')); - struct.ext = fileComp.substr(fileComp.indexOf('.') + 1); - - struct.key = _event.data.pathComponent.slice(1, _event.data.pathComponent.length - 1).join(pathDelim); - if (struct.key.length > 0) - struct.key += pathDelim; - struct.key += struct.file; - - struct.format = - struct.pitch + '_' + - struct.roll + '_' + - struct.yaw + '_' + - struct.zoom + '_' + - struct.x + '_' + - struct.y + '_' + - struct.z + '_' + - struct.width + '_' + - struct.height + '_' + - struct.autorotate + '.' + - struct.ext; - return struct; - } - - function isSupportedFormat(extension) { - if (extension === "gif") - return true; - if (extension === "jpg") - return true; - if (extension === "jpeg") - return true; - if (extension === "png") - return true; - if (extension === "tif") - return true; - if (extension === "tiff") - return true; - if (extension === "bmp") - return true; - return false; - } - - // list all available models in a summary format for the topmost request - function overviewList() { - var struct = {}; - struct.models = {}; - for (key in models) { - var model = models[key]; - var group = models[key].group - var name = model.strippedName.split(pathDelim).last(); - var entry = assign(struct, ['models'].concat(group.substr(1).split('/')).concat(name), {}); - entry.url = - _ioprocessors['http'].location + model.relDir + model.strippedName.split(pathDelim).join('/') + '.png'; - entry.path = model.relDir + model.strippedName.split(pathDelim).join('/') + '.png'; - } - return struct; - } - - // check whether a given string represents a number - function isNumber(n) { - return !isNaN(parseFloat(n)) && isFinite(n); - } - - // allow to set deep keys in an object - function assign(obj, path, value) { - if (typeof path === 'string') - path = path.split('.'); - if (!(path instanceof Array)) - return undefined; - - lastKeyIndex = path.length-1; - for (var i = 0; i < lastKeyIndex; ++ i) { - key = path[i]; - if (key.length == 0) - continue; - if (!(key in obj)) - obj[key] = {} - obj = obj[key]; - } - obj[path[lastKeyIndex]] = value; - return obj[path[lastKeyIndex]]; - } - </script> - <state id="main"> - <!-- Stop processing if no vrml-path was given on command line --> - <transition target="final" cond="_x['args']['vrml-path'] == undefined || _x['args']['vrml-path'].length == 0"> - <log expr="'No --vrml-path given'" /> - </transition> - - <!-- Stop processing if no tmp-path was given on command line --> - <transition target="final" cond="_x['args']['tmp-path'] == undefined || _x['args']['tmp-path'].length == 0"> - <log expr="'No --tmp-path given'" /> - </transition> - - <!-- Stop processing if any error occurs --> - <transition target="final" event="error"> - <log expr="'An error occured:'" /> - <script>dump(_event);</script> - </transition> - - <!-- Start the directory monitor for generated files --> - <invoke type="dirmon" id="dirmon.processed"> - <param name="dir" expr="_x['args']['tmp-path']" /> - <param name="recurse" expr="false" /> - <param name="reportExisting" expr="true" /> - <!-- Called for every file we found --> - <finalize> - <script> - _event.fileStruct = fileToStruct(_event.data.file); - - if (_event.data.file.extension === "osgb") { - // this is a binary 3D file converted from the wrls - - if (_event.name === "file.deleted") { - delete models[_event.fileStruct.key]; - print("Removed a vanished osgb file at " + _event.fileStruct.key + "\n"); - } else { - models[_event.fileStruct.key] = _event.data.file; - models[_event.fileStruct.key].group = '/' + _event.data.file.name.split(pathDelim).slice(0,-1).join('/'); - print("Inserted a new osgb file at " + _event.fileStruct.key + "\n"); - } - - } else if ('format' in _event.fileStruct) { - // this is a processed file generated for some request - - if (_event.name === "file.deleted") { - delete processed[_event.fileStruct.key][_event.fileStruct.format]; - print("Removed a vanished processed file at " + _event.fileStruct.key + "\n"); - } else { - if (!(_event.fileStruct.key in processed)) { - processed[_event.fileStruct.key] = {} - } - processed[_event.fileStruct.key][_event.fileStruct.format] = _event.data.file; - print("Inserted a new processed file at " + _event.fileStruct.key + "\n"); - } - } else { - print("Ignoring " + _event.data.file.name + "\n"); - } - </script> - </finalize> - </invoke> - - <!-- Start the directory monitor for wrl files --> - <invoke type="dirmon" id="dirmon.vrml"> - <param name="dir" expr="_x['args']['vrml-path']" /> - <param name="recurse" expr="true" /> - <param name="suffix" expr="'vrml wrl'" /> - <finalize> - <script> - _event.fileStruct = fileToStruct(_event.data.file); - if (_event.name === "file.existing" || _event.name === "file.added") { - wrls[_event.fileStruct.key] = _event.data.file; - print("Inserting wrl " + _event.data.file.path + " from " +_event.data.file.relDir + " at " + _event.fileStruct.key + "\n"); - } - if (_event.name === "file.deleted") { - delete wrls[_event.fileStruct.key]; - print("Deleting wrl " + _event.data.file.path + " from " +_event.data.file.relDir + " at " + _event.fileStruct.key + "\n"); - } - </script> - <if cond="models && - (!(_event.fileStruct.key in models) || - wrls[_event.fileStruct.key].mtime > models[_event.fileStruct.key].mtime) - "> - <send target="#_osgvonvert.osgb"> - <param name="source" expr="_event.data.file.path" /> - <param name="dest" expr="_x['args']['tmp-path'] + '/' + _event.fileStruct.key + '.osgb'" /> - </send> - </if> - </finalize> - </invoke> - - <!-- Start the osgconvert invoker to transform 3D files --> - <invoke type="osgconvert" id="osgvonvert.osgb"> - <param name="threads" expr="4" /> - <finalize> - <script> - //dump(_event); - </script> - <!-- <file operation="write" contentexpr="_event.data.content" sandbox="off" urlexpr="_event.data.dest" /> --> - </finalize> - <!--finalize> - <script> - // we could put the file into the osgbs or processed here, but we rely on the directory monitors for now - print("Received " + _event.name + " regarding " + _event.data.dest + "\n"); - </script> - </finalize--> - </invoke> - - <!-- Start a nested SCXML interpreter to create movies from the images --> - <!-- <invoke type="scxml" id="scxml.ffmpeg" src="ffmpeg-server.scxml" autoforward="true"> - <param name="modelDir" expr="_x['args']['tmp-path']" /> - </invoke> --> - - <!-- Idle here --> - <state id="idle"> - <!--onentry> - <log expr="_event" /> - </onentry --> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length >= 2 && - _event.data.pathComponent[_event.data.pathComponent.length - 1].indexOf('.') !== -1"> - <!-- request for a specific format - http://host/vrml/relative/path/format?query=string --> - <script> - _event.fileStruct = reqToStruct(_event.data); - _event.dest = _x['args']['tmp-path'] + '/' + _event['fileStruct'].key + '-' + _event['fileStruct'].format; - print("Got a request for [" + _event['fileStruct'].key + '-' + _event['fileStruct'].format + "]\n"); -// dump(_event); - </script> - <if cond="_event['fileStruct'].key in models && isSupportedFormat(_event['fileStruct'].ext)"> - <!-- There is such a file available as osgb --> - <if cond=" - _event['fileStruct'].key in processed && - _event['fileStruct'].format in processed[_event['fileStruct'].key]"> - <script> - //print("Sending " + processed[_event['fileStruct'].key][_event['fileStruct'].format].path + "\n"); - </script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content fileexpr="processed[_event['fileStruct'].key][_event['fileStruct'].format].path" /> - </respond> - <else /> - <if cond="_event.name. ('postponed')"> - <!-- - A postponed event we couldn't answer - --> - <respond status="404" to="_event.origin"> - <header name="Connection" value="close" /> - </respond> - <else /> - <script> - print("Processing outfile " + _event['dest'] + " from model " + _event['file'] + "\n"); - </script> - <send target="#_osgvonvert.osgb"> - <param name="source" expr="models[_event['fileStruct'].key].path" /> - <param name="dest" expr="_event['dest']" /> - <param name="pitch" expr="_event.fileStruct.pitch" /> - <param name="roll" expr="_event.fileStruct.roll" /> - <param name="yaw" expr="_event.fileStruct.yaw" /> - <param name="zoom" expr="_event.fileStruct.zoom" /> - <param name="x" expr="_event.fileStruct.x" /> - <param name="y" expr="_event.fileStruct.y" /> - <param name="z" expr="_event.fileStruct.z" /> - <param name="width" expr="_event.fileStruct.width" /> - <param name="height" expr="_event.fileStruct.height" /> - <param name="autorotate" expr="_event.fileStruct.autorotate" /> - </send> - <!-- - Redeliver the event once the untilexpr is true. The untilexpr has to evaluate - into another valid expression that we will check again on stable configurations. - --> - <postpone - untilexpr=" - '\'' + _event['fileStruct'].key + '\' in processed && - \'' + _event['fileStruct'].format + '\'' + ' in processed[\'' + _event['fileStruct'].key + '\'] || - _event.name === \'convert.failure\' && _event.data.dest === \'' + _event['dest'] + '\'' - "/> - </if> - </if> - <else /> - <!-- There is no such model --> - <respond status="404" to="_event.origin"> - <header name="Connection" value="close" /> - </respond> - </if> - </transition> - - <!-- - process request for JSON datastructures - --> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 2 && - _event.data.pathComponent[1] === 'models'"> - <script>//dump(_event)</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="models" /> - </respond> - </transition> - - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 2 && - _event.data.pathComponent[1] === 'processed'"> - <script>//dump(_event)</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="processed" /> - </respond> - </transition> - - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 2 && - _event.data.pathComponent[1] === 'wrls'"> - <script>//dump(_event)</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="wrls" /> - </respond> - </transition> - - <!-- request for topmost list of all files --> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 1"> - <script>//dump(_event);</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="overviewList()" /> - </respond> - </transition> - - <!-- XHR CORS preflight response --> - <transition event="http.options" target="idle"> - <script>//dump(_event);</script> - <respond status="200" to="_event.origin"> - <header name="Access-Control-Allow-Origin" value="*" /> - <header name="Access-Control-Allow-Methods" value="GET, OPTIONS" /> - <header name="Access-Control-Allow-Headers" value="X-Requested-With" /> - </respond> - </transition> - - <transition event="render.done" target="idle"> - <script>dump(_event);</script> - <respond status="200" to="_event.data.context"> - <header name="Connection" value="close" /> - <header name="Content-Type" valueexpr="_event.data.mimetype" /> - <header name="Content-Disposition" valueexpr="'attachment; filename=' + _event.data.filename" /> - <content expr="_event.data.movie" /> - </respond> - </transition> - - </state> - </state> - <state id="final" final="true" /> -</scxml>
\ No newline at end of file diff --git a/apps/samples/vrml/vrml-server.pre-osgjs.scxml b/apps/samples/vrml/vrml-server.pre-osgjs.scxml deleted file mode 100644 index a51c5f3..0000000 --- a/apps/samples/vrml/vrml-server.pre-osgjs.scxml +++ /dev/null @@ -1,333 +0,0 @@ -<scxml datamodel="ecmascript" name="vrml"> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string. .js" /> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/array.last.js" /> - <script> - var wrls = {}; // information of the wrl, vrml files - var models = {}; // information of the osgb files - - var pathDelim = ':'; // we need to flatten directories - this will seperate them in filenames - - /** - * Transform a http request into a pose - */ - function reqToStruct(req) { - var struct = {}; - - var query = (('query' in req) ? req.query : {}); - - struct.pitch = (('pitch' in query && isNumber(query.pitch)) ? query.pitch : 0); - struct.roll = (('roll' in query && isNumber(query.roll)) ? query.roll : 0); - struct.yaw = (('yaw' in query && isNumber(query.yaw)) ? query.yaw : 0); - struct.zoom = (('zoom' in query && isNumber(query.zoom)) ? query.zoom : 1); - struct.x = (('x' in query && isNumber(query.x)) ? query.x : 0); - struct.y = (('y' in query && isNumber(query.y)) ? query.y : 0); - struct.z = (('z' in query && isNumber(query.z)) ? query.z : 0); - struct.width = (('width' in query && isNumber(query.width)) ? query.width : 640); - struct.height = (('height' in query && isNumber(query.height)) ? query.height : 480); - struct.autorotate = (('autorotate' in query && (query.autorotate === 'on' || query.autorotate === 'off')) ? query.autorotate : 'on'); - - var fileComp = req.pathComponent[req.pathComponent.length - 1]; - struct.file = fileComp.substr(0, fileComp.indexOf('.')); - struct.ext = fileComp.substr(fileComp.indexOf('.') + 1); - - struct.key = _event.data.pathComponent.slice(1, _event.data.pathComponent.length - 1).join(pathDelim); - if (struct.key.length > 0) - struct.key += pathDelim; - - // support for meta file "latest.ext" - if (struct.file === "latest") { - var latestStamp = 0; - for (var key in models) { - if (key.substring(0, struct.key.length) == struct.key) { - if (models[key].ctime > latestStamp) { - var name = models[key].strippedName; - struct.file = name.substring(name.lastIndexOf(pathDelim) + 1); - latestStamp = models[key].ctime; - } - } - } - } - - struct.key += struct.file; - - return struct; - } - - function keyForFile(file) { - var key = file.relDir.replace(/\//g, pathDelim).substr(1) + file.strippedName; - return key; - } - - function isSupportedFormat(extension) { - if (extension === "gif") - return true; - if (extension === "jpg") - return true; - if (extension === "jpeg") - return true; - if (extension === "png") - return true; - if (extension === "tif") - return true; - if (extension === "tiff") - return true; - if (extension === "bmp") - return true; - return false; - } - - // list all available models in a summary format for the topmost request - function overviewList() { - var struct = {}; - struct.models = {}; - for (key in models) { - var model = models[key]; - var group = models[key].group - var name = model.strippedName.split(pathDelim).last(); - var entry = assign(struct, ['models'].concat(group.substr(1).split('/')).concat(name), {}); - entry.url = - _ioprocessors['http'].location + model.relDir + model.strippedName.split(pathDelim).join('/') + '.png'; - entry.path = model.relDir + model.strippedName.split(pathDelim).join('/') + '.png'; - } - return struct; - } - - // check whether a given string represents a number - function isNumber(n) { - return !isNaN(parseFloat(n)) && isFinite(n); - } - - // allow to set deep keys in an object - function assign(obj, path, value) { - if (typeof path === 'string') - path = path.split('.'); - if (!(path instanceof Array)) - return undefined; - - lastKeyIndex = path.length-1; - for (var i = 0; i < lastKeyIndex; ++ i) { - key = path[i]; - if (key.length == 0) - continue; - if (!(key in obj)) - obj[key] = {} - obj = obj[key]; - } - obj[path[lastKeyIndex]] = value; - return obj[path[lastKeyIndex]]; - } - </script> - <state id="main"> - <!-- Stop processing if no vrml-path was given on command line --> - <transition target="final" cond="_x['args']['vrml-path'] == undefined || _x['args']['vrml-path'].length == 0"> - <log expr="'No --vrml-path given'" /> - </transition> - - <!-- Stop processing if no tmp-path was given on command line --> - <transition target="final" cond="_x['args']['tmp-path'] == undefined || _x['args']['tmp-path'].length == 0"> - <log expr="'No --tmp-path given'" /> - </transition> - - <!-- Stop processing if any error occurs --> - <transition target="final" event="error"> - <log expr="'An error occured:'" /> - <script>dump(_event);</script> - </transition> - - <!-- Start the directory monitor for generated files --> - <invoke type="dirmon" id="dirmon.processed"> - <param name="dir" expr="_x['args']['tmp-path']" /> - <param name="recurse" expr="false" /> - <param name="reportExisting" expr="true" /> - <param name="suffix" expr="'osgb'" /> - <!-- Called for every file we found --> - <finalize> - <script> - var key = keyForFile(_event.data.file); - // this is a binary 3D file converted from the wrls - - if (_event.name === "file.deleted") { - delete models[key]; - print("Removed a vanished osgb file at " + key + "\n"); - } else { - models[key] = _event.data.file; - models[key].group = '/' + _event.data.file.name.split(pathDelim).slice(0,-1).join('/'); - print("Inserted a new osgb file at " + key + "\n"); - } - </script> - </finalize> - </invoke> - - <!-- Start the directory monitor for wrl files --> - <invoke type="dirmon" id="dirmon.vrml"> - <param name="dir" expr="_x['args']['vrml-path']" /> - <param name="recurse" expr="true" /> - <param name="suffix" expr="'vrml wrl'" /> - <finalize> - <script> - _event.key = keyForFile(_event.data.file); - if (_event.name === "file.existing" || _event.name === "file.added") { - wrls[_event.key] = _event.data.file; - var dirMonFile = _event.data.file.relDir.substr(1) + _event.data.file.strippedName + ".osgb" - // we already procressed this file - if (_invokers['dirmon.processed'].file[dirMonFile]) { - models[_event.key] = _event.data.file; - } - print("Inserting wrl " + _event.data.file.path + " from " + _event.data.file.relDir + " at " + _event.key + "\n"); - } - if (_event.name === "file.deleted") { - delete wrls[_event.key]; - delete models[_event.key]; - print("Deleting wrl " + _event.data.file.path + " from " + _event.data.file.relDir + " at " + _event.key + "\n"); - } - </script> - <if cond="models && _event.name !== 'file.deleted' && - (!(_event.key in models) || wrls[_event.key].mtime > models[_event.key].mtime)"> - <send target="#_osgvonvert.osgb"> - <param name="source" expr="_event.data.file.path" /> - <param name="dest" expr="_x['args']['tmp-path'] + '/' + _event.key + '.osgb'" /> - </send> - </if> - </finalize> - </invoke> - - <!-- Start the osgconvert invoker to transform 3D files --> - <invoke type="osgconvert" id="osgvonvert.osgb"> - <param name="threads" expr="4" /> - <finalize> - <script> - //dump(_event); - </script> - <if cond="'context' in _event.data"> - <!-- this was generated in reply to a request --> - <if cond="_event.name. ('success')"> - <respond status="200" to="_event.data.context"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <header name="Content-Type" valueexpr="_event.data.content[_event.data.format].mimetype" /> - <content expr="_event.data.content[_event.data.format]" /> - </respond> - <else /> - <respond status="404" to="_event.data.context"> - <header name="Connection" value="close" /> - </respond> - </if> - </if> - </finalize> - </invoke> - - <!-- Start a nested SCXML interpreter to create movies from the images --> - <invoke type="scxml" id="scxml.ffmpeg" src="ffmpeg-server.invoked.scxml" autoforward="true"> - <param name="modelDir" expr="_x['args']['tmp-path']" /> - </invoke> - - <!-- Idle here --> - <state id="idle"> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length >= 2 && - _event.data.pathComponent[_event.data.pathComponent.length - 1].indexOf('.') !== -1"> - <!-- request for a specific format http://host/vrml/relative/path/format?query=string --> - <script> - //dump(_invokers['dirmon.vrml']); - _event.fileStruct = reqToStruct(_event.data); - </script> - <if cond="_event.fileStruct.key in models && isSupportedFormat(_event['fileStruct'].ext)"> - <!-- There is such a file available as osgb --> - <send target="#_osgvonvert.osgb"> - <param name="source" expr="models[_event['fileStruct'].key].path" /> - <param name="format" expr="_event['fileStruct'].ext" /> - <param name="pitch" expr="_event.fileStruct.pitch" /> - <param name="roll" expr="_event.fileStruct.roll" /> - <param name="yaw" expr="_event.fileStruct.yaw" /> - <param name="zoom" expr="_event.fileStruct.zoom" /> - <param name="x" expr="_event.fileStruct.x" /> - <param name="y" expr="_event.fileStruct.y" /> - <param name="z" expr="_event.fileStruct.z" /> - <param name="width" expr="_event.fileStruct.width" /> - <param name="height" expr="_event.fileStruct.height" /> - <param name="autorotate" expr="_event.fileStruct.autorotate" /> - <param name="context" expr="_event.origin" /> - </send> - <else /> - <!-- There is no such model --> - <respond status="404" to="_event.origin"> - <header name="Connection" value="close" /> - </respond> - </if> - </transition> - - <!-- - process request for JSON datastructures - --> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 2 && - _event.data.pathComponent[1] === 'models'"> - <script>//dump(_event)</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="models" /> - </respond> - </transition> - - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 2 && - _event.data.pathComponent[1] === 'wrls'"> - <script>//dump(_event)</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="wrls" /> - </respond> - </transition> - - <!-- request for topmost list of all files --> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 1"> - <script>//dump(_event);</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="overviewList()" /> - </respond> - </transition> - - <!-- XHR CORS preflight response --> - <transition event="http.options" target="idle"> - <script>//dump(_event);</script> - <respond status="200" to="_event.origin"> - <header name="Access-Control-Allow-Origin" value="*" /> - <header name="Access-Control-Allow-Methods" value="GET, OPTIONS" /> - <header name="Access-Control-Allow-Headers" value="X-Requested-With" /> - </respond> - </transition> - - <transition event="render.done" target="idle"> - <script>//dump(_event);</script> - <respond status="200" to="_event.data.context"> - <header name="Connection" value="close" /> - <header name="Content-Type" valueexpr="_event.data.mimetype" /> - <header name="Content-Disposition" valueexpr="'attachment; filename=' + _event.data.filename" /> - <content expr="_event.data.movie" /> - </respond> - </transition> - - <transition event="send.codecs" target="idle"> - <script>//dump(_event);</script> - <respond status="200" to="_event.data.context"> - <header name="Connection" value="close" /> - <header name="Content-Type" valueexpr="_event.data.mimetype" /> - <header name="Content-Disposition" valueexpr="'attachment; filename=' + _event.data.filename" /> - <content expr="_event.data.codecs" /> - </respond> - </transition> - - </state> - </state> - <state id="final" final="true" /> -</scxml>
\ No newline at end of file diff --git a/apps/samples/vrml/vrml-server.scxml b/apps/samples/vrml/vrml-server.scxml deleted file mode 100644 index 529a469..0000000 --- a/apps/samples/vrml/vrml-server.scxml +++ /dev/null @@ -1,356 +0,0 @@ -<scxml datamodel="ecmascript" name="vrml"> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string. .js" /> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/array.last.js" /> - <script> - var wrls = {}; // information of the wrl, vrml files - var models = {}; // information of the osgb / osgjs files - - var pathDelim = ':'; // we need to flatten directories - this will seperate them in filenames - - /** - * Transform a http request into a pose - */ - function reqToStruct(req) { - var struct = {}; - - var query = (('query' in req) ? req.query : {}); - - struct.pitch = (('pitch' in query && isNumber(query.pitch)) ? query.pitch : 0); - struct.roll = (('roll' in query && isNumber(query.roll)) ? query.roll : 0); - struct.yaw = (('yaw' in query && isNumber(query.yaw)) ? query.yaw : 0); - struct.zoom = (('zoom' in query && isNumber(query.zoom)) ? query.zoom : 1); - struct.x = (('x' in query && isNumber(query.x)) ? query.x : 0); - struct.y = (('y' in query && isNumber(query.y)) ? query.y : 0); - struct.z = (('z' in query && isNumber(query.z)) ? query.z : 0); - struct.width = (('width' in query && isNumber(query.width)) ? query.width : 640); - struct.height = (('height' in query && isNumber(query.height)) ? query.height : 480); - struct.autorotate = (('autorotate' in query && (query.autorotate === 'on' || query.autorotate === 'off')) ? query.autorotate : 'on'); - - var fileComp = req.pathComponent[req.pathComponent.length - 1]; - struct.file = fileComp.substr(0, fileComp.indexOf('.')); - struct.ext = fileComp.substr(fileComp.indexOf('.') + 1); - - struct.key = _event.data.pathComponent.slice(1, _event.data.pathComponent.length - 1).join(pathDelim); - if (struct.key.length > 0) - struct.key += pathDelim; - - // support for meta file "latest.ext" - if (struct.file === "latest") { - var latestStamp = 0; - for (var key in models) { - if (key.substring(0, struct.key.length) == struct.key) { - if (models[key].ctime > latestStamp) { - var name = models[key].strippedName; - struct.file = name.substring(name.lastIndexOf(pathDelim) + 1); - latestStamp = models[key].ctime; - } - } - } - } - - struct.key += struct.file; - return struct; - } - - function keyForFile(file) { - var key = file.relDir.replace(/\//g, pathDelim).substr(1) + file.strippedName; - return key; - } - - function isSupportedFormat(extension) { - if (extension === "gif") - return true; - if (extension === "jpg") - return true; - if (extension === "jpeg") - return true; - if (extension === "png") - return true; - if (extension === "tif") - return true; - if (extension === "tiff") - return true; - if (extension === "bmp") - return true; - if (extension === "osgjs") - return true; - return false; - } - - // list all available models in a summary format for the topmost request - function overviewList() { - var struct = {}; - struct.models = {}; - for (key in models) { - var model = models[key]; - var group = models[key].group - var name = model.strippedName.split(pathDelim).last(); - var entry = assign(struct, ['models'].concat(group.substr(1).split('/')).concat(name), {}); - entry.url = - _ioprocessors['http'].location + model.relDir + model.strippedName.split(pathDelim).join('/'); - entry.path = model.relDir + model.strippedName.split(pathDelim).join('/'); - } - return struct; - } - - // check whether a given string represents a number - function isNumber(n) { - return !isNaN(parseFloat(n)) && isFinite(n); - } - - // allow to set deep keys in an object - function assign(obj, path, value) { - if (typeof path === 'string') - path = path.split('.'); - if (!(path instanceof Array)) - return undefined; - - lastKeyIndex = path.length-1; - for (var i = 0; i < lastKeyIndex; ++ i) { - key = path[i]; - if (key.length == 0) - continue; - if (!(key in obj)) - obj[key] = {} - obj = obj[key]; - } - obj[path[lastKeyIndex]] = value; - return obj[path[lastKeyIndex]]; - } - </script> - <state id="main"> - <!-- Stop processing if no vrml-path was given on command line --> - <transition target="final" cond="_x.args == undefined || _x.args['vrml-path'] == undefined || _x.args['vrml-path'].length == 0"> - <log expr="'No --vrml-path given'" /> - </transition> - - <!-- Stop processing if no tmp-path was given on command line --> - <transition target="final" cond="_x.args == undefined || _x.args['tmp-path'] == undefined || _x.args['tmp-path'].length == 0"> - <log expr="'No --tmp-path given'" /> - </transition> - - <!-- Stop processing if any error occurs --> - <transition target="final" event="error"> - <log expr="'An error occured:'" /> - <script>dump(_event);</script> - </transition> - - <!-- Start the directory monitor for generated files --> - <invoke type="dirmon" id="dirmon.processed"> - <param name="dir" expr="_x['args']['tmp-path']" /> - <param name="recurse" expr="false" /> - <param name="reportExisting" expr="true" /> - <param name="suffix" expr="'osgb'" /> - <!-- Called for every file we found --> - <finalize> - <script> - var key = keyForFile(_event.data.file); - // this is a binary 3D file converted from the wrls - if (_event.name === "file.deleted") { - delete models[key]; - print("Removed a vanished osgb file at " + key + "\n"); - } else { - models[key] = _event.data.file; - models[key].group = '/' + _event.data.file.name.split(pathDelim).slice(0,-1).join('/'); - print("Inserted a new osgb file at " + key + "\n"); - } - </script> - </finalize> - </invoke> - - <!-- Start the directory monitor for wrl files --> - <invoke type="dirmon" id="dirmon.vrml"> - <param name="dir" expr="_x['args']['vrml-path']" /> - <param name="recurse" expr="true" /> - <param name="suffix" expr="'vrml wrl'" /> - <finalize> - <script> - _event.key = keyForFile(_event.data.file); - if (_event.name === "file.existing" || _event.name === "file.added") { - wrls[_event.key] = _event.data.file; - var dirMonFile = _event.data.file.relDir.substr(1) + _event.data.file.strippedName + ".osgb" - // we already procressed this file - if (_invokers['dirmon.processed'].file[dirMonFile]) { - models[_event.key] = _event.data.file; - } - print("Inserting wrl " + _event.data.file.path + " from " + _event.data.file.relDir + " at " + _event.key + "\n"); - } - if (_event.name === "file.deleted") { - delete wrls[_event.key]; - delete models[_event.key]; - print("Deleting wrl " + _event.data.file.path + " from " + _event.data.file.relDir + " at " + _event.key + "\n"); - } - </script> - <if cond="models && _event.name !== 'file.deleted' && - (!(_event.key in models) || wrls[_event.key].mtime > models[_event.key].mtime)"> - <send target="#_osgvonvert.toNative"> - <param name="source" expr="_event.data.file.path" /> - <param name="dest" expr="_x['args']['tmp-path'] + '/' + _event.key + '.osgb'" /> - <param name="optimizegeometry" expr="true" /> - </send> - </if> - </finalize> - </invoke> - - <!-- Start the osgconvert invoker to transform 3D files --> - <invoke type="osgconvert" id="osgvonvert.toNative"> - <param name="threads" expr="4" /> - </invoke> - - <invoke type="osgconvert" id="osgvonvert.toClient"> - <param name="threads" expr="4" /> - <finalize> - <script> - //dump(_event); - </script> - <if cond="'context' in _event.data"> - <!-- this was generated in reply to a request --> - <if cond="_event.name. ('success')"> - <respond status="200" to="_event.data.context"> - <header name="Connection" value="close" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <header name="Content-Type" valueexpr="_event.data.content[_event.data.format].mimeType" /> - <content expr="_event.data.content[_event.data.format]" /> - </respond> - <else /> - <respond status="404" to="_event.data.context"> - <header name="Connection" value="close" /> - </respond> - </if> - </if> - </finalize> - </invoke> - - <!-- Start a nested SCXML interpreter to create movies from the images --> - <invoke type="scxml" id="scxml.ffmpeg" src="ffmpeg-server.invoked.scxml" autoforward="true"> - <param name="modelDir" expr="_x['args']['tmp-path']" /> - </invoke> - - <!-- Idle here --> - <state id="idle"> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length >= 2 && - _event.data.pathComponent[_event.data.pathComponent.length - 1].indexOf('.') !== -1"> - <!-- request for a specific format http://host/vrml/relative/path/format?query=string --> - <script> - //dump(_invokers['dirmon.vrml']); - _event.fileStruct = reqToStruct(_event.data); - </script> - <if cond="_event.fileStruct.key in models && isSupportedFormat(_event['fileStruct'].ext)"> - <!-- There is such a file available as osgb --> - <send target="#_osgvonvert.toClient"> - <param name="source" expr="models[_event['fileStruct'].key].path" /> - <param name="format" expr="_event['fileStruct'].ext" /> - <param name="pitch" expr="_event.fileStruct.pitch" /> - <param name="roll" expr="_event.fileStruct.roll" /> - <param name="yaw" expr="_event.fileStruct.yaw" /> - <param name="zoom" expr="_event.fileStruct.zoom" /> - <param name="x" expr="_event.fileStruct.x" /> - <param name="y" expr="_event.fileStruct.y" /> - <param name="z" expr="_event.fileStruct.z" /> - <param name="width" expr="_event.fileStruct.width" /> - <param name="height" expr="_event.fileStruct.height" /> - <param name="autorotate" expr="_event.fileStruct.autorotate" /> - <param name="context" expr="_event.origin" /> - </send> - <else /> - <!-- There is no such model --> - <send target="#_osgvonvert.toClient"> - <param name="source" expr="'/scratch/vrml/404.wrl'" /> - <param name="format" expr="_event['fileStruct'].ext" /> - <param name="pitch" expr="_event.fileStruct.pitch" /> - <param name="roll" expr="_event.fileStruct.roll" /> - <param name="yaw" expr="_event.fileStruct.yaw" /> - <param name="zoom" expr="_event.fileStruct.zoom" /> - <param name="x" expr="_event.fileStruct.x" /> - <param name="y" expr="_event.fileStruct.y" /> - <param name="z" expr="_event.fileStruct.z" /> - <param name="width" expr="_event.fileStruct.width" /> - <param name="height" expr="_event.fileStruct.height" /> - <param name="autorotate" expr="_event.fileStruct.autorotate" /> - <param name="context" expr="_event.origin" /> - </send> - - </if> - </transition> - - <!-- - process request for JSON datastructures - --> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 2 && - _event.data.pathComponent[1] === 'models'"> - <script>//dump(_event)</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="models" /> - </respond> - </transition> - - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 2 && - _event.data.pathComponent[1] === 'wrls'"> - <script>//dump(_event)</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="wrls" /> - </respond> - </transition> - - <!-- request for topmost list of all files --> - <transition event="http.get" target="idle" cond=" - _event.data.pathComponent.length == 1"> - <script>//dump(_event);</script> - <respond status="200" to="_event.origin"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <header name="Access-Control-Allow-Origin" value="*" /> - <content expr="overviewList()" /> - </respond> - </transition> - - <!-- XHR CORS preflight response --> - <transition event="http.options" target="idle"> - <script>//dump(_event);</script> - <respond status="200" to="_event.origin"> - <header name="Access-Control-Allow-Origin" value="*" /> - <header name="Access-Control-Allow-Methods" value="GET, OPTIONS" /> - <header name="Access-Control-Allow-Headers" value="X-Requested-With" /> - </respond> - </transition> - - <transition event="ws.*" target="idle"> - <script>dump(_event);</script> - <send targetexpr="_event.origin" type="websocket"> - <content expr="_event" /> <!-- reply with event --> - </send> - </transition> - - <transition event="render.done" target="idle"> - <script>//dump(_event);</script> - <respond status="200" to="_event.data.context"> - <header name="Connection" value="close" /> - <header name="Content-Type" valueexpr="_event.data.movie.mimeType" /> - <header name="Content-Disposition" valueexpr="'attachment; filename=' + _event.data.filename" /> - <content expr="_event.data.movie" /> - </respond> - </transition> - - <transition event="send.codecs" target="idle"> - <script>//dump(_event);</script> - <respond status="200" to="_event.data.context"> - <header name="Connection" value="close" /> - <header name="Content-Type" value="application/json" /> - <content expr="_event.data.codecs" /> - </respond> - </transition> - - </state> - </state> - <state id="final" final="true" /> -</scxml> diff --git a/apps/samples/websockets/websockets.html b/apps/samples/websockets/websockets.html deleted file mode 100644 index 88e4def..0000000 --- a/apps/samples/websockets/websockets.html +++ /dev/null @@ -1,79 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> -<html> - <head> - <meta charset="utf-8"> - <title> - WebSocket Test - </title> - <script language="javascript" type="text/javascript"> - var wsUri = "ws://localhost:8082/websockets"; -// var wsUri = "ws://echo.websocket.org"; - - var output; - - var littlePacket = "0123456789ABCDEF"; - var mediumPacket = ""; - var hugePacket = ""; - for (var i = 0; i < 16; i++) { - mediumPacket += littlePacket; - } - for (var i = 0; i < 16; i++) { - hugePacket += mediumPacket; - } - - function init() { - output = document.getElementById("output"); - testWebSocket(); - } - function testWebSocket() { - websocket = new WebSocket(wsUri); - websocket.onopen = function(evt) { - onOpen(evt) - }; - websocket.onclose = function(evt) { - onClose(evt) - }; - websocket.onmessage = function(evt) { - onMessage(evt) - }; - websocket.onerror = function(evt) { - onError(evt) - }; - } - function onOpen(evt) { - writeToScreen("CONNECTED"); - doSend(littlePacket); - doSend(mediumPacket); - //doSend(hugePacket); - } - function onClose(evt) { - writeToScreen("DISCONNECTED"); - } - function onMessage(evt) { - var value = evt.data.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); - writeToScreen('<span style="color: blue;">RESPONSE: <pre>' + value + '</pre><\/span>'); -// websocket.close(); - } - function onError(evt) { - writeToScreen('<span style="color: red;">ERROR:<\/span> ' + evt.data); - } - function doSend(message) { - writeToScreen("SENT: " + message); - websocket.send(message); - } - function writeToScreen(message) { - var pre = document.createElement("p"); - pre.style.wordWrap = "break-word"; - pre.innerHTML = message; - output.appendChild(pre); - } - window.addEventListener("load", init, false); - </script> - </head> - <body> - <h2> - WebSocket Test - </h2> - <div id="output"></div> - </body> -</html> diff --git a/apps/samples/websockets/websockets.scxml b/apps/samples/websockets/websockets.scxml deleted file mode 100644 index 25fdb7a..0000000 --- a/apps/samples/websockets/websockets.scxml +++ /dev/null @@ -1,39 +0,0 @@ -<scxml datamodel="ecmascript" name="websockets"> - <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" /> - <datamodel> - <data id="test"> - { - foo1: "bar1", - foo2: "bar2", - foo3: "bar3", - } - </data> - </datamodel> - <state id="main"> - <transition target="main" event="ws.*"> - <script> - dump(_event); - </script> - <if cond="_event.data.type === 'text'"> - <send targetexpr="_event.origin" type="websocket"> - <content expr="_event.data.content" /> - </send> - <send targetexpr="_event.origin" type="websocket"> - <content expr="test" /> - </send> - <send targetexpr="_event.origin" type="websocket"> - <content expr="document.evaluate('//scxml').asNodeSet()[0]" /> - </send> - <send target="/websockets" type="websocket"> - <content expr="_event.data.content" /> - </send> - <send target="/websockets" type="websocket"> - <content expr="test" /> - </send> - <send target="/websockets" type="websocket"> - <content expr="document.evaluate('//scxml').asNodeSet()[0]" /> - </send> - </if> - </transition> - </state> -</scxml>
\ No newline at end of file diff --git a/apps/uscxml-analyze.cpp b/apps/uscxml-analyze.cpp deleted file mode 100644 index 33a536a..0000000 --- a/apps/uscxml-analyze.cpp +++ /dev/null @@ -1,239 +0,0 @@ -#include "uscxml/config.h" -#include "uscxml/Interpreter.h" -#include "uscxml/debug/Complexity.h" -#include "uscxml/transform/ChartToFSM.h" -#include "uscxml/dom/DOMUtils.h" -#include <glog/logging.h> -#include <fstream> -#include <iostream> - -#include "uscxml/Factory.h" -#include "uscxml/server/HTTPServer.h" -#include "getopt.h" - -#ifdef HAS_SIGNAL_H -#include <signal.h> -#endif - -#ifdef HAS_EXECINFO_H -#include <execinfo.h> -#endif - -#ifdef HAS_DLFCN_H -#include <dlfcn.h> -#endif - -#define ANNOTATE(envKey, annotationParam) \ -envVarIsTrue(envKey) || std::find(annotations.begin(), annotations.end(), annotationParam) != annotations.end() - -void printUsageAndExit(const char* progName) { - // remove path from program name - std::string progStr(progName); - if (progStr.find_last_of(PATH_SEPERATOR) != std::string::npos) { - progStr = progStr.substr(progStr.find_last_of(PATH_SEPERATOR) + 1, progStr.length() - (progStr.find_last_of(PATH_SEPERATOR) + 1)); - } - - printf("%s version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n", progStr.c_str()); - printf("Usage\n"); - printf("\t%s", progStr.c_str()); - printf(" [-a {ASPECTS}] [-lN]"); -#ifdef BUILD_AS_PLUGINS - printf(" [-p pluginPath]"); -#endif - printf(" [URL]"); - printf("\n"); - printf("Options\n"); - printf("\t-a {ASPECTS} : analyze with regard to comma seperated aspects\n"); - printf("\t 'issues' - find common pitfalls and syntactical errors\n"); - printf("\t 'metrics' - print metrics about the state-chart's complexity\n"); - printf("\t-lN : Set loglevel to N\n"); - printf("\n"); - exit(1); -} - -int main(int argc, char** argv) { - using namespace uscxml; - - std::string pluginPath; - std::string inputFile; - std::list<std::string> aspects; - -#if defined(HAS_SIGNAL_H) && !defined(WIN32) - signal(SIGPIPE, SIG_IGN); -#endif - - // setup logging - google::LogToStderr(); - google::InitGoogleLogging(argv[0]); - - optind = 0; - opterr = 0; - - struct option longOptions[] = { - {"help", required_argument, 0, 'p'}, - {"plugin-path", required_argument, 0, 'p'}, - {"aspect", optional_argument, 0, 'a'}, - {"loglevel", required_argument, 0, 'l'}, - {0, 0, 0, 0} - }; - - // parse global options - int optionInd = 0; - int option; - for (;;) { - option = getopt_long_only(argc, argv, "a:p:l:h", longOptions, &optionInd); - if (option == -1) { - break; - } - switch(option) { - // cases without short option - case 0: { - break; - } - // cases with short-hand options - case 'p': - pluginPath = optarg; - break; - case 'a': - aspects = tokenize(optarg, ','); - break; - case 'l': - break; - case 'h': - case '?': { - printUsageAndExit(argv[0]); - break; - } - default: - break; - } - } - - if (optind < argc) { - inputFile = argv[optind]; - } - - // register plugins - if (pluginPath.length() > 0) { - Factory::setDefaultPluginPath(pluginPath); - } - - // start HTTP server - HTTPServer::getInstance(31444, 31445, NULL); - - Interpreter interpreter; - try { - if (inputFile.size() == 0 || inputFile == "-") { - LOG(INFO) << "Reading SCXML from STDIN"; - std::stringstream ss; - std::string line; - while (std::getline(std::cin, line)) { - ss << line; - } - URL tmp("anonymous.scxml"); - tmp.toAbsoluteCwd(); - interpreter = Interpreter::fromXML(ss.str(), tmp); - } else { - interpreter = Interpreter::fromURL(inputFile); - } - if (!interpreter) { - LOG(ERROR) << "Cannot create interpreter from " << inputFile; - exit(EXIT_FAILURE); - } - - // analyze here - if (aspects.size() == 0 || std::find(aspects.begin(), aspects.end(), "issues") != aspects.end()) { - std::list<InterpreterIssue> issues = interpreter.validate(); - for (std::list<InterpreterIssue>::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) { - std::cout << *issueIter << std::endl; - } - } - - if (aspects.size() == 0 || std::find(aspects.begin(), aspects.end(), "metrics") != aspects.end()) { - - Arabica::XPath::NodeSet<std::string> states = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "state"); - Arabica::XPath::NodeSet<std::string> final = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "final"); - Arabica::XPath::NodeSet<std::string> parallels = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "parallel"); - Arabica::XPath::NodeSet<std::string> shallowHistories = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[@type='shallow']"); - shallowHistories.push_back(interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[not(@type)]")); - Arabica::XPath::NodeSet<std::string> deepHistories = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "history[@type='deep']"); - Arabica::XPath::NodeSet<std::string> transitions = interpreter.getNodeSetForXPath("//" + interpreter.getNameSpaceInfo().xpathPrefix + "transition"); - - std::cout << "### Number of XML elements" << std::endl; - std::cout << "# <state> + <final> + <parallel> + <history>" << std::endl; - std::cout << "nr_states: " << (states.size() + final.size() + parallels.size() + shallowHistories.size() + deepHistories.size()) << std::endl; - std::cout << "# <parallel>" << std::endl; - std::cout << "nr_parallel: " << parallels.size() << std::endl; - std::cout << "# <history type=\"flat\">" << std::endl; - std::cout << "nr_hist_flat: " << shallowHistories.size() << std::endl; - std::cout << "# <history type=\"deep\">" << std::endl; - std::cout << "nr_hist_deep: " << deepHistories.size() << std::endl; - std::cout << "# <transition>" << std::endl; - std::cout << "nr_trans: " << transitions.size() << std::endl; - std::cout << "#" << std::endl; - - - std::cout << "### Transition Histogram: number of transitions, number of active configurations" << std::endl; - - size_t numberOfLegalConfs = 0; - size_t lastBin = 0; - std::cout << "th: "; - std::string seperator = ""; - std::map<size_t, size_t> histogram = Complexity::getTransitionHistogramm(interpreter.getDocument().getDocumentElement()); - for (std::map<size_t, size_t>::iterator binIter = histogram.begin(); binIter != histogram.end(); binIter++) { - while (binIter->first > lastBin) { - lastBin++; - std::cout << seperator << "0"; - seperator = ", "; - } - std::cout << seperator << binIter->second; - seperator = ", "; - numberOfLegalConfs += binIter->second; - lastBin = binIter->first + 1; - } - std::cout << std::endl << "#" << std::endl; - - - std::stringstream transPowerSetSS; - std::string transPowerSetSeperator = ""; - for (std::map<size_t, size_t>::reverse_iterator binIter = histogram.rbegin(); binIter != histogram.rend(); binIter++) { - transPowerSetSS << transPowerSetSeperator << binIter->second << " * " << "2**" << binIter->first; - transPowerSetSeperator = " + "; - } - std::cout << "# Sum of Powersets:" << std::endl; - std::cout << "ps_sum: " << transPowerSetSS.str() << std::endl; - std::cout << "#" << std::endl; - - std::cout << "### Upper bounds:" << std::endl; - std::cout << "# \tActive configurations: " << std::endl; - std::cout << "up_ac: " << numberOfLegalConfs << std::endl; - std::cout << "# \tGlobal configurations: " << std::endl; - std::cout << "up_gc: " << Complexity::stateMachineComplexity(interpreter) << std::endl; - - std::cout << "# \tGlobal configurations (no history): " << std::endl; - std::cout << "up_gcnh: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY) << std::endl; - - std::cout << "# \tGlobal configurations (no nested data): " << std::endl; - std::cout << "up_gcnd: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_NESTED_DATA) << std::endl; - - std::cout << "# \tGlobal configurations (no unreachable): " << std::endl; - std::cout << "up_gcnu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; - - std::cout << "# \tGlobal configurations (no nested data, no history): " << std::endl; - std::cout << "up_gcnhd: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_NESTED_DATA) << std::endl; - - std::cout << "# \tGlobal configurations (no history, no unreachable): " << std::endl; - std::cout << "up_gcnhu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; - - std::cout << "# \tGlobal configurations (no nested data, no unreachable): " << std::endl; - std::cout << "up_gcndu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_NESTED_DATA | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; - - std::cout << "# \tGlobal configurations (no nested data, no history, no unreachable): " << std::endl; - std::cout << "up_gcnhdu: " << Complexity::stateMachineComplexity(interpreter, uscxml::Complexity::IGNORE_HISTORY | uscxml::Complexity::IGNORE_NESTED_DATA | uscxml::Complexity::IGNORE_UNREACHABLE) << std::endl; - } - } catch (Event e) { - std::cout << e << std::endl; - } - - return EXIT_SUCCESS; -}
\ No newline at end of file diff --git a/apps/uscxml-browser.cpp b/apps/uscxml-browser.cpp index f223cef..cf666c9 100644 --- a/apps/uscxml-browser.cpp +++ b/apps/uscxml-browser.cpp @@ -1,94 +1,12 @@ #include "uscxml/config.h" #include "uscxml/Interpreter.h" -#include "uscxml/dom/DOMUtils.h" +#include "uscxml/util/DOM.h" -#ifndef BUILD_MINIMAL -# include "uscxml/debug/DebuggerServlet.h" -#endif -#include <glog/logging.h> +#include <easylogging++.h> -#include "uscxml/Factory.h" +#include "uscxml/plugins/Factory.h" #include "uscxml/server/HTTPServer.h" -#ifdef HAS_SIGNAL_H -#include <signal.h> -#endif - -#ifdef HAS_EXECINFO_H -#include <execinfo.h> -#endif - -#ifdef HAS_DLFCN_H -#include <dlfcn.h> -#endif - -#ifdef CMAKE_BUILD_TYPE_DEBUG - -#ifdef HAS_EXECINFO_H -void printBacktrace(void** array, int size) { - char** messages = backtrace_symbols(array, size); - for (size_t i = 0; i < size && messages != NULL; ++i) { - std::cerr << "\t" << messages[i] << std::endl; - } - std::cerr << std::endl; - free(messages); -} - -#ifdef HAS_DLFCN_H -// see https://gist.github.com/nkuln/2020860 -typedef void (*cxa_throw_type)(void *, void *, void (*) (void *)); -cxa_throw_type orig_cxa_throw = 0; - -void load_orig_throw_code() { - orig_cxa_throw = (cxa_throw_type) dlsym(RTLD_NEXT, "__cxa_throw"); -} - -extern "C" -CXA_THROW_SIGNATURE { - std::cerr << __FUNCTION__ << " will throw exception from " << std::endl; - if (orig_cxa_throw == 0) - load_orig_throw_code(); - - void *array[50]; - size_t size = backtrace(array, 50); - printBacktrace(array, size); - orig_cxa_throw(thrown_exception, pvtinfo, dest); -} -#endif -#endif - - -// see http://stackoverflow.com/questions/2443135/how-do-i-find-where-an-exception-was-thrown-in-c -void customTerminate() { - static bool tried_throw = false; - try { - // try once to re-throw currently active exception - if (!tried_throw) { - tried_throw = true; - throw; - } else { - tried_throw = false; - } - } catch (const std::exception &e) { - std::cerr << __FUNCTION__ << " caught unhandled exception. what(): " - << e.what() << std::endl; - } catch (const uscxml::Event &e) { - std::cerr << __FUNCTION__ << " caught unhandled exception. Event: " - << e << std::endl; - } catch (...) { - std::cerr << __FUNCTION__ << " caught unknown/unhandled exception." - << std::endl; - } - -#ifdef HAS_EXECINFO_H - void * array[50]; - int size = backtrace(array, 50); - - printBacktrace(array, size); -#endif - abort(); -} -#endif int main(int argc, char** argv) { using namespace uscxml; @@ -97,16 +15,8 @@ int main(int argc, char** argv) { signal(SIGPIPE, SIG_IGN); #endif -#ifdef CMAKE_BUILD_TYPE_DEBUG - std::set_terminate(customTerminate); -#endif - InterpreterOptions options = InterpreterOptions::fromCmdLine(argc, argv); - // setup logging - google::LogToStderr(); - google::InitGoogleLogging(argv[0]); - if (options.pluginPath.length() > 0) { Factory::setDefaultPluginPath(options.pluginPath); } @@ -135,15 +45,6 @@ int main(int argc, char** argv) { } HTTPServer::getInstance(options.httpPort, options.wsPort, sslConf); -#ifndef BUILD_MINIMAL - DebuggerServlet* debugger; - if (options.withDebugger) { - debugger = new DebuggerServlet(); - debugger->copyToInvokers(true); - HTTPServer::getInstance()->registerServlet("/debug", debugger); - } -#endif - // instantiate and configure interpreters std::list<Interpreter> interpreters; for(int i = 0; i < options.interpreters.size(); i++) { @@ -157,7 +58,7 @@ int main(int argc, char** argv) { Interpreter interpreter = Interpreter::fromURL(documentURL); if (interpreter) { - if (options.checking) { + if (options.validate) { std::list<InterpreterIssue> issues = interpreter.validate(); for (std::list<InterpreterIssue>::iterator issueIter = issues.begin(); issueIter != issues.end(); issueIter++) { std::cout << *issueIter << std::endl; @@ -168,22 +69,12 @@ int main(int argc, char** argv) { } - interpreter.setCmdLineOptions(options.additionalParameters); - interpreter.setCmdLineOptions(currOptions->additionalParameters); - interpreter.setCapabilities(options.getCapabilities()); - if (options.verbose) { - StateTransitionMonitor* vm = new StateTransitionMonitor(); + StateTransitionMonitor* vm = new StateTransitionMonitor(interpreter); vm->copyToInvokers(true); - interpreter.addMonitor(vm); + interpreter.setMonitor(vm); } -#ifndef BUILD_MINIMAL - if (options.withDebugger) { - interpreter.addMonitor(debugger); - } -#endif - interpreters.push_back(interpreter); } else { @@ -194,35 +85,19 @@ int main(int argc, char** argv) { } } - // start interpreters + // run interpreters try { std::list<Interpreter>::iterator interpreterIter = interpreters.begin(); - while(interpreterIter != interpreters.end()) { - interpreterIter->start(); - interpreterIter++; - } - - bool stillRunning = true; - // call from main thread for UI events - while(interpreters.size() > 0) { - interpreterIter = interpreters.begin(); - while(interpreterIter != interpreters.end()) { - stillRunning = interpreterIter->runOnMainThread(25); - if (!stillRunning) { - interpreters.erase(interpreterIter++); - } else { - interpreterIter++; - } - } - } - -#ifndef BUILD_MINIMAL - if (options.withDebugger) { - // idle and wait for CTRL+C or debugging events - while(true) - tthread::this_thread::sleep_for(tthread::chrono::seconds(1)); - } -#endif + while (interpreters.size() > 0) { + while(interpreterIter != interpreters.end()) { + InterpreterState state = interpreterIter->step(); + if (state == USCXML_FINISHED) { + interpreterIter = interpreters.erase(interpreterIter); + } else { + interpreterIter++; + } + } + } } catch (Event e) { std::cout << e << std::endl; } diff --git a/apps/uscxml-browser.vbs b/apps/uscxml-browser.vbs deleted file mode 100644 index fc8ea9a..0000000 --- a/apps/uscxml-browser.vbs +++ /dev/null @@ -1,177 +0,0 @@ -' -' Description: VBScript/VBS open file dialog -' Compatible with most Windows platforms -' Author: wangye <pcn88 at hotmail dot com> -' Website: http://wangye.org -' -' dir is the initial directory; if no directory is -' specified "Desktop" is used. -' filter is the file type filter; format "File type description|*.ext" -' -Public Function GetOpenFileName(dir, filter) - Const msoFileDialogFilePicker = 3 - - If VarType(dir) <> vbString Or dir="" Then - dir = CreateObject( "WScript.Shell" ).SpecialFolders( "Desktop" ) - End If - - If VarType(filter) <> vbString Or filter="" Then - filter = "All files|*.*" - End If - - Dim i,j, objDialog, TryObjectNames - TryObjectNames = Array( _ - "UserAccounts.CommonDialog", _ - "MSComDlg.CommonDialog", _ - "MSComDlg.CommonDialog.1", _ - "Word.Application", _ - "SAFRCFileDlg.FileOpen", _ - "InternetExplorer.Application" _ - ) - - On Error Resume Next - Err.Clear - - For i=0 To UBound(TryObjectNames) - Set objDialog = WSH.CreateObject(TryObjectNames(i)) - If Err.Number<>0 Then - Err.Clear - Else - Exit For - End If - Next - - Select Case i - Case 0,1,2 - ' 0. UserAccounts.CommonDialog XP Only. - ' 1.2. MSComDlg.CommonDialog MSCOMDLG32.OCX must registered. - If i=0 Then - objDialog.InitialDir = dir - Else - objDialog.InitDir = dir - End If - objDialog.Filter = filter - If objDialog.ShowOpen Then - GetOpenFileName = objDialog.FileName - End If - Case 3 - ' 3. Word.Application Microsoft Office must installed. - objDialog.Visible = False - Dim objOpenDialog, filtersInArray - filtersInArray = Split(filter, "|") - Set objOpenDialog = _ - objDialog.Application.FileDialog( _ - msoFileDialogFilePicker) - With objOpenDialog - .Title = "Open File(s):" - .AllowMultiSelect = False - .InitialFileName = dir - .Filters.Clear - For j=0 To UBound(filtersInArray) Step 2 - .Filters.Add filtersInArray(j), _ - filtersInArray(j+1), 1 - Next - If .Show And .SelectedItems.Count>0 Then - GetOpenFileName = .SelectedItems(1) - End If - End With - objDialog.Visible = True - objDialog.Quit - Set objOpenDialog = Nothing - Case 4 - ' 4. SAFRCFileDlg.FileOpen xp 2003 only - ' See http://www.robvanderwoude.com/vbstech_ui_fileopen.php - If objDialog.OpenFileOpenDlg Then - GetOpenFileName = objDialog.FileName - End If - Case 5 - - Dim IEVersion,IEMajorVersion, hasCompleted - hasCompleted = False - Dim shell - Set shell = CreateObject("WScript.Shell") - ' 下面获取IE版本 - IEVersion = shell.RegRead( _ - "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Version") - If InStr(IEVersion,".")>0 Then - ' 获取主版本号 - IEMajorVersion = CInt(Left(IEVersion, InStr(IEVersion,".")-1)) - If IEMajorVersion>7 Then - ' 如果版本号大于7,也就是大于IE7,则采取MSHTA方案 - ' Bypasses c:\fakepath\file.txt problem - ' http://pastebin.com/txVgnLBV - Dim fso - Set fso = CreateObject("Scripting.FileSystemObject") - - Dim tempFolder : Set tempFolder = fso.GetSpecialFolder(2) - Dim tempName : tempName = fso.GetTempName() - Dim tempFile : Set tempFile = tempFolder.CreateTextFile(tempName & ".hta") - Dim tempBaseName - tempBaseName = tempFolder & "\" & tempName - tempFile.Write _ - "<html>" & _ - " <head>" & _ - " <title>Browse</title>" & _ - " </head>" & _ - " <body>" & _ - " <input type='file' id='f'>" & _ - " <script type='text/javascript'>" & _ - " var f = document.getElementById('f');" & _ - " f.click();" & _ - " var fso = new ActiveXObject('Scripting.FileSystemObject');" & _ - " var file = fso.OpenTextFile('" & _ - Replace(tempBaseName,"\", "\\") & ".txt" & "', 2, true);" & _ - " file.Write(f.value);" & _ - " file.Close();" & _ - " window.close();" & _ - " </script>" & _ - " </body>" & _ - "</html>" - tempFile.Close - Set tempFile = Nothing - Set tempFolder = Nothing - shell.Run tempBaseName & ".hta", 1, True - Set tempFile = fso.OpenTextFile(tempBaseName & ".txt", 1) - GetOpenFileName = tempFile.ReadLine - tempFile.Close - fso.DeleteFile tempBaseName & ".hta" - fso.DeleteFile tempBaseName & ".txt" - Set tempFile = Nothing - Set fso = Nothing - hasCompleted = True ' 标记为已完成 - End If - End If - If Not hasCompleted Then - ' 5. InternetExplorer.Application IE must installed - objDialog.Navigate "about:blank" - Dim objBody, objFileDialog - Set objBody = _ - objDialog.document.getElementsByTagName("body")(0) - objBody.innerHTML = "<input type='file' id='fileDialog'>" - while objDialog.Busy Or objDialog.ReadyState <> 4 - WScript.sleep 10 - Wend - Set objFileDialog = objDialog.document.all.fileDialog - objFileDialog.click - GetOpenFileName = objFileDialog.value - End If - objDialog.Quit - Set objFileDialog = Nothing - Set objBody = Nothing - Set shell = Nothing - Case Else - ' Sorry I cannot do that! - End Select - - Set objDialog = Nothing -End Function - -scxmlFile = GetOpenFileName(CreateObject("WScript.Shell").SpecialFolders("MyDocuments"), "All Files|*.*|SCXML Files|*.scxml") - -if scxmlFile <> "" then - set wshShell = WScript.CreateObject("WScript.Shell") - set objFs = WScript.CreateObject("Scripting.FileSystemObject") - wshShell.CurrentDirectory = objFs.GetParentFolderName(Wscript.ScriptFullName) -' WScript.Echo scxmlFile - wshShell.Run("mmi-browser.exe """ & scxmlFile & """") -end if
\ No newline at end of file diff --git a/apps/uscxml-debugger.html b/apps/uscxml-debugger.html deleted file mode 100644 index 3aece02..0000000 --- a/apps/uscxml-debugger.html +++ /dev/null @@ -1,2836 +0,0 @@ -<!doctype html> -<html> -<head> - <!-- <link href="http://localhost/~sradomski/jsPlumb/font-awesome.css" rel="stylesheet"> --> - <!-- <link rel="stylesheet" href="http://localhost/~sradomski/jsPlumb/demo-all.css"> --> - <!-- <link rel="stylesheet" href="http://localhost/~sradomski/jsPlumb/demo.css"> --> - - <!-- script src="https://google-code-prettify.googlecode.com/svn/loader/prettify.js?autoload=false"></script --> - <!--script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js?autoload=false&lang=xml" defer="defer"></script--> - - <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> - <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script> - <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script> - <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/additional-methods.min.js"></script> - <script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> - - <script src="http://cdn.jsdelivr.net/ace/1.1.01/min/ace.js" charset="utf-8"></script> - <script src="http://vkbeautify.googlecode.com/files/vkbeautify.0.99.00.beta.js" charset="utf-8"></script> - <script src="http://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.9.3/typeahead.min.js" charset="utf-8"></script> - <script src="http://dean.edwards.name/base/Base.js" charset="utf-8"></script> - <!-- alternatively http://maxailloud.github.io/confirm-bootstrap/#liveDemo --> - - <script src="https://rawgithub.com/jibe914/Bootstrap-Confirmation/master/bootstrap3-confirmation.js" charset="utf-8"></script> - <!--script src="https://raw.githubusercontent.com/jibe914/Bootstrap-Confirmation/master/bootstrap3-confirmation.js" charset="utf-8"></script--> - <!-- script src="https://raw.github.com/Tavicu/bootstrap-confirmation/master/bootstrap-confirmation.js" charset="utf-8"></script --> - - - <script src="https://rawgithub.com/msurguy/ladda-bootstrap/master/dist/spin.js" charset="utf-8"></script> - <script src="https://rawgithub.com/msurguy/ladda-bootstrap/master/dist/ladda.js" charset="utf-8"></script> - <script src="https://rawgithub.com/prettycode/Object.identical.js/master/Object.identical.js" charset="utf-8"></script> - - - <!-- <link rel="stylesheet" href="jQuery-File-Upload/css/style.css"> - <link rel="stylesheet" href="jQuery-File-Upload/css/jquery.fileupload.css"> --> - - - - <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" /> - <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> - <!-- <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css"> --> - <!-- <link rel="stylesheet" href="http://twitter.github.io/typeahead.js/css/main.css" /> --> - <link rel="stylesheet" href="https://raw.githubusercontent.com/hyspace/typeahead.js-bootstrap3.less/master/typeahead.css" /> - <link rel="stylesheet" href="https://rawgithub.com/msurguy/ladda-bootstrap/master/dist/ladda-themeless.min.css" /> - - <!-- script src="jquery-ui-1.10.4.uscxml/js/jquery-1.10.2.js"></script> - <script src="http://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.min.js" charset="utf-8"></script> - <link rel="stylesheet" href="http://twitter.github.io/typeahead.js/css/main.css" /> - <script src="Base.js"></script> - <script src="jquery-ui-1.10.4.uscxml/js/jquery-ui-1.10.4.custom.js"></script> - <script src="http://localhost/~sradomski/ace/ace.js" charset="utf-8"></script> - <script src="http://localhost/~sradomski/vkbeautify.0.99.00.beta.js" charset="utf-8"></script> - <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.min.css"> - - <script src='http://localhost/~sradomski/jsPlumb/jquery.min.js'></script> - <script src='http://localhost/~sradomski/jsPlumb/jquery-ui.min.js'></script> - <script src='http://localhost/~sradomski/jsPlumb/jquery.ui.touch-punch.min.js'></script> - <script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.1.01/ace.js"></script> - <script src='http://localhost/~sradomski/jsPlumb/jquery.jsPlumb-1.5.5.js'></script> - <script src="http://localhost/~sradomski/ace/ace.js" charset="utf-8"></script> - <script src="http://localhost/~sradomski/jquery.dropdown.min.js" charset="utf-8"></script> - <script src="http://localhost/~sradomski/bootstrap/js/bootstrap.min.js"></script --> - - <!-- link href="jquery.dropdown.css" rel="stylesheet" / --> - <!-- <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/dark-hive/jquery-ui.css"> --> - <!-- link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css" --> - - <style type="text/css"> - - body { -/* font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";*/ - } - - .windowlet { - position: absolute; - top: 3em; - left: 5em; - box-shadow: 5px 2px 19px #aaa; - -o-box-shadow: 5px 2px 19px #aaa; - -webkit-box-shadow: 5px 2px 19px #aaa; - -moz-box-shadow: 5px 2px 19px #aaa; - } - - .windowlet .panel-body { - padding: 8px; - } - - .windowlet textarea { - resize:vertical; - } - - .debug { - position:fixed !important; - width: 320px; - min-width: 250px; - } - - .debug > .panel > .panel-group { -/* overflow: hidden;*/ - margin-bottom: 0px; - } - - .debug > .panel { - margin-bottom: 0; - } - - .debug > .panel > .panel-footer { - padding: 5px 5px; - font-family:Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace; - font-size: 10px; - } - - .panel-group .panel { -/* border: 1px solid transparent;*/ - overflow: visible; - } - - .debug-header { - cursor: move; -/* padding: 10px 15px 5px 15px; -*/ } - - .subtitle { - font-size: 0.7em; - font-weight: normal; - } - - /* nested panels */ - .panel .panel .panel-heading { - padding: 8px 15px; - } - - .panel .panel-group .panel { - border-radius: 0px; - } - - .panel .panel .panel-title { - font-size: 100%; /* Override explicit font-size from bootstrap */ - } - - .panel .panel { - font-size: 90%; - } - - .panel-group .panel+.panel { - margin-top: 0px; - } - - .panel-heading { - position: relative; - } - .heading-decoration { - position: absolute; - right: 40px; - top: 4px; - } - - .heading-decoration .badge { - float: left; - margin-top: 2px; - margin-right: 5px; - } - - .panel-heading .panel-toggle:after { - /* symbol for "opening" panels */ - font-family: 'Glyphicons Halflings'; /* essential for enabling glyphicon */ - content: "\e114"; /* adjust as needed, taken from bootstrap.css */ - float: right; /* adjust as needed */ - color: grey; /* adjust as needed */ - } - .panel-heading.collapsed .panel-toggle:after { - /* symbol for "collapsed" panels */ - content: "\e080"; /* adjust as needed, taken from bootstrap.css */ - } - - /* see http://stackoverflow.com/questions/18059161/css-issue-on-twitter-typeahead-with-bootstrap-3 */ - .twitter-typeahead .tt-hint { - display: block; - height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.428571429; - border: 1px solid transparent; - } - - .form-group .twitter-typeahead { - width: 100%; - } - - .messages-content textarea.messages { - font-size: 10px; - cursor: auto; - white-space: pre; - overflow: auto; - font-family:Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace; - height: 16em; - } - - ul.dropdown-menu li.server-session { - padding-left: 0.7em; - } - - ul.recent-documents span.recent-document-features { - padding-left: 0.7em; - } - - .tooltip-inner { - background-color: #333; - } - .tooltip.bottom .tooltip-arrow { - border-bottom-color: #333; - background-color: #FFF transparent; - } - - .dom { - font-size: 10px; - font-family:Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace; - color: #666; - } - - .dom .active-state { - color: #000; - } - - .dom .xpath-selected { - color: #A00; - font-weight: bold; - } - - </style> - - <script type="text/javascript"> - - var SCXMLEditor = Base.extend({ - constructor: function(params) { - $.extend(this, params); - - this.debugger = new SCXMLEditor.Debugger.USCXML({ - debuggerURL: "http://localhost:8088", - scxmlEditor: this, - }); - - this.xmlView = new SCXMLEditor.XMLView({ - destNode: $("body").find(".dom")[0], - }); - - $(this.debugger.getNode()).appendTo($("body")); - }, - - scxmlDOM: undefined, - scxmlURL: undefined, - scxmlRoot: undefined, - scxmlStates: {}, - - setDocumentNameFromURL: function(url) { - var tmp = $('<a>', { href:url } )[0]; - $(this.debugger.debugDocumentNameNode).html(tmp.pathname.split('/').pop()); - $(this.debugger.saveBreakpointsNode).closest("li").removeClass("disabled"); - }, - - loadURL: function(scxmlURL) { - this.scxmlURL = scxmlURL; - this.setDocumentNameFromURL(scxmlURL); - - if (scxmlURL in this.debugger.recentDocuments) { - // load breakpoints - if ('breakpoints' in this.debugger.recentDocuments[scxmlURL]) { - for (var index in this.debugger.recentDocuments[scxmlURL].breakpoints) { - var breakpointData = this.debugger.recentDocuments[scxmlURL].breakpoints[index]; - var breakpoint = new SCXMLEditor.Debugger.Breakpoint({ - data: breakpointData - }); - - var serializedBreakpoint = JSON.stringify(breakpoint.toWireFormat()); - var alreadyExists = false; - - // check if such a breakpoint already exists - for (var index in this.debugger.breakpoints) { - var otherBreakpoint = this.debugger.breakpoints[index]; - if (serializedBreakpoint === JSON.stringify(otherBreakpoint.toWireFormat())) { - alreadyExists = true; - break; - } - } - - if (!alreadyExists) - this.debugger.addBreakpoint(breakpoint); - } - } - } - - // get instance into scope chain - var scxmlEdit = this; - $.ajax({ - type: "GET", - dataType: "text xml", - url: scxmlURL, - success: function (dom) { - scxmlEdit.loadDOM(dom); - }, - error: function(data) { - console.log(data); - } - }); - }, - - loadDOM: function(scxmlDOM) { - this.scxmlDOM = scxmlDOM; - this.scxmlRoot = $(scxmlDOM).find("scxml")[0]; - - // notify the debugger - this.debugger.loadDOM(scxmlDOM); - - // var domText = SCXMLEditor.xmlToString(this.scxmlDOM); - // $("body").find("pre.dom").text(domText); - if (this.xmlView) { - this.xmlView.setXML(this.scxmlDOM); - this.xmlView.prettyPrint(); - } - - // add 'nested' class to states of nested scxml documents - $(this.scxmlRoot).find("scxml").find("state, final, parallel, history").addClass("nested"); - $(this.getNode()).appendTo(this.containerNode); - }, - - getNode: function() { - this.node = document.createElement('div'); - this.node.className = "scxml-editor"; - this.node.innerHTML = '\ - <div class="state-tree"></div>\ - <div class="tools"></div>\ - '; - - this.stateTreeNode = $(this.node).children("div.state-tree"); - this.toolsNode = $(this.node).children("div.tools"); - - // var rootState = new SCXMLEditor.PortletStateView({ - // scxmlState: this.scxmlRoot, - // scxmlEditor: this - // }); - // this.rootNode = rootState.getNode(); - // $(this.rootNode).appendTo(this.stateTreeNode); - // $(this.rootNode).draggable(); - - return this.node; - }, - - getAllChildStates: function() { - return $(this.scxmlRoot).find("state, parallel, final, history").not(".nested"); - }, - - getAllStateIds: function() { - var stateIds = []; - var self = this; - $.each(this.getAllChildStates(), function(index, state) { - stateIds.push(SCXMLEditor.getStateId(state)); - }); - return stateIds; - } - - }); - - SCXMLEditor.getStateId = function(state) { - return $(state).attr("id") || $(state).attr("name") || "scxml"; - } - - SCXMLEditor.getStateType = function(state) { - return state.nodeName.toLowerCase(); - } - - SCXMLEditor.xmlToString = function (xmlNode) { - var text = xmlNode.xml || (new XMLSerializer()).serializeToString(xmlNode); - return vkbeautify.xml(text); - } - - SCXMLEditor.XMLView = Base.extend({ - constructor: function(params) { - $.extend(this, params); - }, - - prettyPrint: function(destNode) { - var self = this; - - function escapeText(text) { - return $('<div/>').text(text).html(); - } - function prettyIndent(xmlNode, indentation) { - var outputText = ''; - var indenter = ''; - - for (var i = 0; i < indentation; i++) { - indenter += " "; - } - var isActive = false; - var isXPathSelected = false; - - switch(xmlNode.nodeType) { - case Node.ELEMENT_NODE: - if (xmlNode.nodeName.toLowerCase() === "state") { - var stateId = xmlNode.getAttribute("id"); - if ($.inArray(stateId, self.activeStates) >= 0) { - outputText += '<span class="active-state">'; - isActive = true; - } - } - - if (xpathNodeSet && xpathNodeSet.snapshotLength > 0) { - for (var i = 0; i < xpathNodeSet.snapshotLength; i++) { - var currNode = xpathNodeSet.snapshotItem(i); - // console.log("Comparing:"); - // console.log(currNode); - // console.log(xmlNode); - if (currNode === xmlNode) { - // console.log("currNode:"); - // console.log(currNode); - outputText += '<span class="xpath-selected">'; - isXPathSelected = true; - break; - } - } - } - - outputText += indenter; - outputText += '<' + xmlNode.nodeName; - for (var j = 0; j < xmlNode.attributes.length; j++) { - var attribute = xmlNode.attributes.item(j); - outputText += " " + attribute.nodeName + "=\"" + attribute.nodeValue + "\""; - } - if (!xmlNode.hasChildNodes()) { - outputText += ' />'; - outputText += '<br />'; - } else { - outputText += '>'; - outputText += '<br />'; - } - break; - case Node.COMMENT_NODE: - outputText += indenter; - outputText += '<!-- ' + escapeText(xmlNode.nodeValue.trim()) + ' -->'; - outputText += '<br />'; - break; - case Node.TEXT_NODE: - var text = xmlNode.nodeValue.trim(); - if (text.length > 0) { - outputText += indenter; - outputText += escapeText(text); - outputText += '<br />'; - } - break; - case Node.ATTRIBUTE_NODE: - case Node.CDATA_SECTION_NODE: - case Node.ENTITY_REFERENCE_NODE: - case Node.ENTITY_NODE: - case Node.PROCESSING_INSTRUCTION_NODE: - case Node.DOCUMENT_NODE: - case Node.DOCUMENT_TYPE_NODE: - case Node.DOCUMENT_FRAGMENT_NODE: - case Node.NOTATION_NODE: - default: - } - - var child = xmlNode.firstChild; - while(child) { - outputText += prettyIndent(child, indentation + 1); - child = child.nextSibling; - } - - switch(xmlNode.nodeType) { - case Node.ELEMENT_NODE: - if (xmlNode.hasChildNodes()) { - outputText += indenter; - outputText += '</' + xmlNode.nodeName; - outputText += '>'; - outputText += '<br />'; - } - break; - default: - } - - if (isActive) { - outputText += '</span>'; - } - if (isXPathSelected) { - outputText += '</span>'; - } - - return outputText; - } - - if (typeof this.xmlNode == "string") { - this.xmlNode = $.parseXML(this.xmlNode); - } - - // this.xpath = "//*[local-name() = \"state\"][@id=\"s0\"]/*[local-name() = \"onentry\"][1]/*[local-name() = \"foreach\"][1]"; - // this.xpath = "//*[local-name() = \"state\"][@id=\"s0\"]/*[local-name() = \"onentry\"][1]/*[local-name() = \"foreach\"][1]"; - var xpathNodeSet = undefined; - - // console.log("xpath:"); - // console.log(this.xpath); - - if (this.xpath) { - try { - xpathNodeSet = this.xmlNode.evaluate( - this.xpath, - this.xmlNode, - function (prefix) { - switch (prefix) { - case 'scxml': - default: - return 'http://www.w3.org/2005/07/scxml'; - } - return null; - }, - XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, - null); - for (var i = 0; i < xpathNodeSet.snapshotLength; i++) { - var currNode = xpathNodeSet.snapshotItem(i); - // console.log("Got node:"); - // console.log(currNode); - } - - } catch(e) { - console.log(e); - } - } - - - var xmlMarkup = '<font color=#888>' + prettyIndent(this.xmlNode, 0) + '</font>'; - - - if (destNode) { - $(destNode).html(xmlMarkup); - } else { - $(this.destNode).html(xmlMarkup); - } - }, - - setDestinationNode: function(destNode) { - this.destNode = destNode; - }, - - setXML: function(xmlNode) { - this.xmlNode = xmlNode; - }, - - setElementXPath: function(xpath) { - this.xpath = xpath; - }, - - setActiveStates: function(states) { - this.activeStates = states; - }, - }); - - // base class of all views onto a state - SCXMLEditor.StateView = Base.extend({ - constructor: function(params) { - $.extend(this, params); - this.scxmlStateType = SCXMLEditor.getStateType(this.scxmlState); - this.scxmlStateId = SCXMLEditor.getStateId(this.scxmlState); - - $(this.scxmlState).bind("DOMSubtreeModified", this.scxmlStateSubtreeModified) - }, - - node: undefined, - scxmlStateType: undefined, - scxmlStateId: undefined, - scxmlState: undefined, - - getNode: function() { - console.log("SCXMLEditor.StateView.getNode()"); - }, - - scxmlStateSubtreeModified: function() { - console.log("SCXMLEditor.StateView.scxmlStateSubtreeModified()"); - }, - - isRoot: function() { - return $(this.scxmlState).prop("tagName").toLowerCase() === "scxml"; - }, - - getDirectChildStates: function() { - return $(this.scxmlState).children("state, parallel, final, history").not(".nested"); - }, - - getAllChildStates: function() { - return $(this.scxmlState).find("state, parallel, final, history").not(".nested"); - }, - - createTransitions: function() { - - } - }); - - // view a state in a small windowlet - SCXMLEditor.ToolsStateView = SCXMLEditor.StateView.extend({ - constructor: function(params) { - this.base(params); - }, - - getNode: function() { - - var tools = this; - - this.node = document.createElement('div'); - this.node.className = 'windowlet tools ui-widget-content'; - this.node.innerHTML = '\ - <div class="ui-widget-header">' + this.getStateId() + '<span class="ui-icon ui-icon-close"></span></div>\ - '; - - $(this.node).children( ".ui-widget-header" ).children( ".ui-icon-close" ).click(function() { - $(tools.node).remove(); - }); - - $(this.node).resizable(); - $(this.node).draggable(); - $(this.node).css("position", "absolute"); - $(this.node).appendTo(this.containerNode); - - return this.node; - }, - - scxmlStateSubtreeModified: function() { - console.log("SCXMLEditor.StateView.scxmlStateSubtreeModified()"); - }, - - }); - - SCXMLEditor.PortletStateView = SCXMLEditor.StateView.extend({ - constructor: function(params) { - this.base(params); - }, - - getNode: function() { - - this.node = document.createElement('div'); - this.node.className = 'portlet'; - - this.node.innerHTML = '\ - <div class="portlet-header"><span class="stateId">' + this.scxmlStateId + '</span></div>\ - <div class="portlet-content"></div>\ - '; - - this.portletHeader = $(this.node).children("div.portlet-header")[0]; - this.portletContent = $(this.node).children("div.portlet-content")[0]; - - var scxmlState = this.scxmlState; - - var settingsButton = document.createElement('button'); - settingsButton.innerHTML = 'Settings'; - $(settingsButton).button({ - icons: { - primary: "ui-icon-gear", - secondary: "ui-icon-triangle-1-s" - }, - text: false - }); - - var settingsMenu = document.createElement('ul'); - settingsMenu.innerHTML = '\ - <li><a href="#"><span class="ui-icon ui-icon-plus"></span>Add nested State</a></li>\ - <li><a href="#"><span class="ui-icon ui-icon-arrow-4-diag"></span>Move this State</a></li>\ - <li><a href="#"><span class="ui-icon ui-icon-trash"></span>Remove this State</a></li>\ - <li>-</li>\ - <li><a href="#"><span class="ui-icon ui-icon-transfer-e-w"></span>Transitions</a></li>\ - <li><a href="#"><span class="ui-icon ui-icon-gear"></span>Executable Content</a></li>\ - <li><a href="#"><span class="ui-icon ui-icon-tag"></span>Datamodel</a></li>\ - <li><a href="#"><span class="ui-icon ui-icon-document"></span>Invokers</a></li>\ - <li><a href="#"><span class="ui-icon ui-icon-zoomin"></span>States</a></li>\ - '; - - $(settingsMenu).menu().hide(); - - $(settingsButton).click(function() { - $(settingsMenu).show().position({ - my: "left top", - at: "left top", - of: this - }); - $(settingsMenu).find("a").click(function event() { - $(settingsMenu).hide(); - }); - $(settingsMenu).mouseleave(function(event) { - $(settingsMenu).hide(); - }); - return false; - }) - - $(settingsMenu).prependTo(this.portletHeader); - $(settingsButton).prependTo(this.portletHeader); - - var childs = this.getDirectChildStates(); - var nrChilds = childs.length + 1; - - var nrCols = Math.ceil(Math.sqrt(nrChilds)); - var nrRows = Math.ceil(nrChilds / nrCols); - - // console.log(nrCols + ' / ' + nrRows); - for (var col = 0; col < nrCols; col++) { - var colNode = document.createElement('div'); - colNode.className = "column"; - - for (var row = 0; row < nrRows; row++) { - if (childs.length > col * nrRows + row) { - var child = childs[col * nrRows + row]; - var childPortlet = new SCXMLEditor.PortletStateView({ - scxmlState: child, - scxmlEditor: this.scxmlEditor - }); - $(childPortlet.getNode()).appendTo(colNode); - } - } - $(colNode).appendTo(this.portletContent); - - $(colNode).sortable({ - connectWith: ".column", - handle: ".portlet-header", - cancel: ".portlet-toggle", - placeholder: "portlet-placeholder ui-corner-all" - }); - } - - // see https://api.jqueryui.com/theming/icons/ - $(this.node) - .addClass( "ui-widget ui-widget-content ui-helper-clearfix ui-corner-all" ) - .children( ".portlet-header" ) - .addClass( "ui-widget-header ui-corner-all" ) - .prepend( "<span class='ui-icon ui-icon-minusthick portlet-toggle'></span>") - .prepend( "<span class='ui-icon ui-icon-newwin portlet-detach'></span>") - .append( " "); - - $(this.node).children( ".portlet-header" ).children( ".portlet-toggle" ).click(function() { - var icon = $(this); - icon.toggleClass( "ui-icon-minusthick ui-icon-plusthick" ); - icon.closest( ".portlet" ).children( ".portlet-content" ).toggle(); - }); - - $(this.node).children( ".portlet-header" ).children( ".portlet-detach" ).click(function() { - var detach = $(this); - detach.toggleClass( "ui-icon-arrowthickstop-1-s ui-icon-newwin" ); - this.tools = new SCXMLEditor.ToolsStateView({ - scxmlState: scxmlState, - scxmlEditor: this.scxmlEditor - }); - $(this.tools.getNode()).appendTo($("body")); // TODO ought to be relative? - }); - return this.node; - - }, - }) - - SCXMLEditor.Debugger = Base.extend({ - constructor: function(params) { - this.breakpointsEnabled = true; - $.extend(this, params); - }, - - breakpoints: [], - currEvent: {}, - - loadDOM: function(scxmlDOM) { - // called by the editor, inherit to e.g. activate buttons - }, - - getNode: function() { - - var debug = this; - this.node = document.createElement('div'); - this.node.className = 'windowlet debug'; - $(this.node).css("position", "absolute"); - - // data-parent="#accordion" missing from <a> to show multiple panels - this.node.innerHTML = '\ - <div class="panel panel-default">\ - <div class="panel-heading debug-header">\ - <h4 class="panel-title">Debugger<span class="toolbar pull-right"></span></h4>\ - <!--span class="subtitle document-name">No Document loaded</span -->\ - </div>\ - <div class="panel-group">\ -<!-- Breakpoints -->\ - <div class="breakpoints panel panel-default">\ - <div class="panel-heading" data-toggle="collapse" data-target="#collapseBreakpoints">\ - <span class="panel-toggle"></span>\ - <h4 class="panel-title">Breakpoints<br/><span class="subtitle current-breakpoint"></span>\ - <i class="heading-decoration pull-right">\ - <div class="btn-group">\ - <button title="Deactivate all Breakpoints" class="deactivate btn btn-default btn-xs btn-primary"><span class="glyphicon glyphicon-off"></span></button>\ - </div>\ - <div class="btn-group">\ - <button title="Add a new Breakpoint" class="new btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span></button>\ - <button \ - title="Remove all Breakpoints" class="delete-all btn btn-default btn-xs"><span class="glyphicon glyphicon-remove"></span></button>\ - </div>\ - </i>\ - </h4>\ - </div>\ - <div id="collapseBreakpoints" class="breakpoints-content panel-collapse collapse">\ - </div>\ - </div>\ -<!-- Current Event -->\ - <!--div class="event panel panel-default">\ - <div class="panel-heading" data-toggle="collapse" data-target="#collapseEvent">\ - <h4 class="panel-title">Current Event\ - <i class="heading-decoration pull-right">\ - <div class="btn-group">\ - <button title="Insert a new Event" class="new btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span></button>\ - <button title="Edit current Event" class="edit btn btn-default btn-xs"><span class="glyphicon glyphicon-pencil"></span></button>\ - <button title="View Event in Window" class="view btn btn-default btn-xs"><span class="glyphicon glyphicon-search"></span></button>\ - </div>\ - </i>\ - <span class="panel-toggle"></span></h4>\ - </div>\ - <div id="collapseEvent" class="panel-collapse collapse">\ - <div class="panel-body event-content"></div>\ - </div>\ - </div-->\ -<!-- Active States -->\ - <!-- div class="states panel panel-default">\ - <div class="panel-heading" data-toggle="collapse" data-target="#collapseStates">\ - <h4 class="panel-title">Active States<span class="panel-toggle"></span></h4>\ - </div>\ - <div id="collapseStates" class="panel-collapse collapse">\ - <div class="panel-body states-content">\ - Anim pariatur cliche reprehenderit, enim eiusmod high life\ - </div>\ - </div>\ - </div -->\ -<!-- Datamodel -->\ - <div class="datamodel panel panel-default">\ - <div class="panel-heading" data-toggle="collapse" data-target="#collapseDatamodel">\ - <h4 class="panel-title">Datamodel\ - <!--i class="heading-decoration pull-right">\ - <div class="btn-group">\ - <button title="Clear Log" class="clear btn btn-default btn-xs"><span class="glyphicon glyphicon-trash"></span></button>\ - <button title="View Log in Window" class="view btn btn-default btn-xs"><span class="glyphicon glyphicon-search"></span></button>\ - </div>\ - </i-->\ - <span class="panel-toggle"></span></h4>\ - </div>\ - <div id="collapseDatamodel" class="panel-collapse collapse">\ - <div class="panel-body datamodel-content"></div>\ - </div>\ - </div>\ -<!-- Assets -->\ - <!--div class="assets panel panel-default">\ - <div class="panel-heading" data-toggle="collapse" data-target="#collapseAssets">\ - <h4 class="panel-title">Assets\ - <i class="heading-decoration pull-right">\ - <div class="btn-group">\ - <button title="New Asset" class="view btn btn-default btn-xs"><span class="glyphicon glyphicon-plus"></span></button>\ - </div>\ - </i>\ - <span class="panel-toggle"></span></h4>\ - </div>\ - <div id="collapseAssets" class="panel-collapse collapse">\ - <div class="panel-body assets-content"></div>\ - </div>\ - </div-->\ -<!-- Message -->\ - <div class="messages panel panel-default">\ - <div class="panel-heading" data-toggle="collapse" data-target="#collapseMessages">\ - <h4 class="panel-title">Messages\ - <i class="heading-decoration pull-right">\ - <span class="badge"></span>\ - <div class="btn-group">\ - <button title="Clear Log" class="clear btn btn-default btn-xs"><span class="glyphicon glyphicon-trash"></span></button>\ - <button title="Text Wrap" class="textwrap btn btn-default btn-xs"><span class="glyphicon glyphicon-align-left"></span></button>\ - </div>\ - </i>\ - <span class="panel-toggle"></span></h4>\ - </div>\ - <div id="collapseMessages" class="panel-collapse collapse in">\ - <div class="panel-body messages-content">\ - <textarea class="form-control messages" wrap="off" readonly></textarea>\ - </div>\ - </div>\ - </div>\ - </div>\ - <div class="panel-footer">\ - <span class="status-indicators"></span>\ - <span class="pull-right document-name"></span>\ - </div>\ - </div>\ - '; - - $(this.node).find("div.panel-collapse").not(".in").prev().addClass("collapsed"); - - - // get some nodes - this.debugFooterNode = $(this.node).find(".panel-footer")[0]; - this.statusIndicatorNode = $(this.node).find(".status-indicators")[0]; - this.debugDocumentNameNode = $(this.node).find(".document-name")[0]; - this.currentBreakpointNode = $(this.node).find(".current-breakpoint")[0]; - this.toolbarNode = $(this.node).find(".toolbar")[0]; - - this.messagesNode = $(this.node).find("div.messages-content")[0]; - this.messagesBadgeNode = $(this.node).find("div.messages").find("span.badge")[0]; - this.clearMessagesButton = $(this.node).find("div.messages").find("button.clear")[0]; - this.textwrapMessagesButton = $(this.node).find("div.messages").find("button.textwrap")[0]; - this.messagesTextarea = $(this.node).find("div.messages-content").find("textarea")[0]; - - this.breakpointNode = $(this.node).find("div.breakpoints-content")[0]; - this.deleteAllBreakpointsButton = $(this.node).find("div.breakpoints").find("button.delete-all")[0]; - this.disableBreakpointsButton = $(this.node).find("div.breakpoints").find("button.deactivate")[0]; - this.addNewBreakpointsButton = $(this.node).find("div.breakpoints").find("button.new")[0]; - - this.currEventNode = $(this.node).find("div.event-content")[0]; - this.insertEventButton = $(this.node).find("div.event").find("button.new")[0]; - this.editEventButton = $(this.node).find("div.event").find("button.edit")[0]; - this.viewEventButton = $(this.node).find("div.event").find("button.view")[0]; - - this.dataModelNode = $(this.node).find("div.datamodel-content")[0]; - this.clearDataModelLogButton = $(this.node).find("div.datamodel").find("button.clear")[0]; - this.viewDataModelLogButton = $(this.node).find("div.datamodel").find("button.view")[0]; - - this.initBreakpoints(); - this.initToolBar(); -// this.initCurrEvent(); - this.initDataModel(); - this.initMessages(); - - // enable tooltips - $(this.node).find("button").tooltip({ - placement: 'bottom', - container: 'body', - delay: { show: 300, hide: 100 } - }); - - $(this.node).resizable({grid: [1, 100000]}); - $(this.node).draggable({ - handle: $(this.node).find("div.debug-header") - }); - - return this.node; - }, - - initMessages: function() { - var debug = this; - - $(this.clearMessagesButton).prop('disabled', true); - - $(this.node).find('#collapseMessages') - .unbind('show.bs.collapse') - .unbind('shown.bs.collapse') - .on('show.bs.collapse', function () { - $(debug.messagesBadgeNode).html(""); // remove number from badge - }).on('shown.bs.collapse', function () { - debug.messagesTextarea.scrollTop = debug.messagesTextarea.scrollHeight; // scroll to bottom (won't work when hidden) - }); - - $(this.messagesTextarea) - .unbind('mouseenter') - .unbind('mouseleave') - .mouseenter(function () { - $(this).addClass("dont-scroll"); - }) - .mouseleave(function () { - $(this).removeClass("dont-scroll"); - }); - - $(this.clearMessagesButton) - .unbind('mouseenter') - .unbind('mouseleave') - .unbind('click') - .mouseenter(function() { - $(this).addClass("btn-warning"); - }).mouseleave(function() { - $(this).removeClass("btn-warning"); - }).click(function() { - debug.messagesTextarea.value = ""; - $(debug.messagesBadgeNode).html(""); - $(this).prop('disabled', true); - $(this).removeClass("btn-warning"); - $(this).tooltip("hide"); - return false; - }); - - $(this.textwrapMessagesButton).unbind('click') - .click(function() { - if ($(debug.messagesTextarea).attr("wrap") == "on") { - $(this).removeClass("active"); - $(debug.messagesTextarea).attr("wrap", "off"); - } else { - $(this).addClass("active"); - $(debug.messagesTextarea).attr("wrap", "on"); - } - return false; - }); - - - }, - - initToolBar: function() { - var debug = this; - - this.toolbarNode.innerHTML = '\ - <div class="btn-group">\ - <button class="control btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown">\ - <span class="glyphicon glyphicon-cog"></span>\ - <span class="caret"></span>\ - </button>\ - <ul class="dropdown-menu">\ - <li><a class="load-from-url" href="#"><i class="glyphicon glyphicon-import"></i> Load Document</a></li>\ - <li><a class="save-breakpoints" href="#"><i class="glyphicon glyphicon-floppy-save"></i> Save Breakpoints</a></li>\ - </ul>\ - </div>\ - <div class="btn-group">\ - <button title="Start Execution" class="start btn btn-default btn-xs"><span class="glyphicon glyphicon-play"></span></button>\ - <div class="btn-group" data-toggle="buttons-checkbox">\ - <button title="Pause Execution" class="pause btn btn-default btn-xs"><span class="glyphicon glyphicon-pause"></span></button>\ - </div>\ - <button title="Step Execution" class="step btn btn-default btn-xs"><span class="glyphicon glyphicon-step-forward"></span></button>\ - </div>\ - ' - this.controlButtonNode = $(this.toolbarNode).children("div.btn-group").children("button.control")[0]; - this.controlDropdownNode = $(this.toolbarNode).children("div.btn-group").children("ul.dropdown-menu")[0]; - this.loadFromURLNode = $(this.toolbarNode).find("a.load-from-url")[0]; - this.saveBreakpointsNode = $(this.toolbarNode).find("a.save-breakpoints")[0]; - this.startButtonNode = $(this.toolbarNode).children("div.btn-group").children("button.start")[0]; - this.pauseButtonNode = $(this.toolbarNode).children("div.btn-group").find("button.pause")[0]; - this.stepButtonNode = $(this.toolbarNode).children("div.btn-group").children("button.step")[0]; - this.globalDropDownNode = $(this.toolbarNode).find(".dropdown-menu")[0]; - - $(this.loadFromURLNode).unbind('click').click(function() { - debug.showLoadDialog(); - return false; - }); - - $(this.saveBreakpointsNode) - .unbind('click').click(function() { - debug.recentDocuments[debug.scxmlEditor.scxmlURL].breakpoints = []; - for (var key in debug.breakpoints) { - debug.recentDocuments[debug.scxmlEditor.scxmlURL].breakpoints.push(debug.breakpoints[key].toWireFormat()); - } - localStorage.recentDocuments = JSON.stringify(debug.recentDocuments); - $(debug.controlButtonNode).effect('highlight', {color: '#3AA453'}, 600); - return false; - }) - .closest("li").addClass("disabled"); - - - $(this.startButtonNode).prop('disabled', true); - $(this.pauseButtonNode).prop('disabled', true); - $(this.stepButtonNode).prop('disabled', true); - - }, - - showLoadDialog: function() { - var debug = this; - - // do we already have a modal div? - $("body").children("div#loadFromURLModal").remove(); - - // load from URL form - modal window - this.loadFromURLModalNode = $('\ - <div class="modal fade" id="loadFromURLModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">\ - <div class="modal-dialog">\ - <form action="" id="loadFromURLModalForm">\ - <div class="modal-content">\ - <div class="modal-header">\ - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>\ - <h4 class="modal-title" id="myModalLabel">Load SCXML from URL</h4>\ - </div>\ - <div class="modal-body">\ - <div class="form-group">\ - <div class="input-group">\ - <span class="input-group-btn">\ - <button title="Recent Documents" type="button" class="btn dropdown-toggle" data-toggle="dropdown">\ - <span class="glyphicon glyphicon-list-alt"></span>\ - </button>\ - <ul class="recent-documents dropdown-menu" role="menu" />\ - </span>\ - <input id="loadFromURLModalInput" name="scxmlUrl" class="form-control" placeholder="URL of SCXML document">\ - </div>\ - </div>\ - </div>\ - <div class="modal-footer">\ - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\ - <button type="submit" class="btn btn-primary">Load</button>\ - </div>\ - </div>\ - </form>\ - </div>\ - </div>\ - '); - - this.recentDocumentsNode = $(this.loadFromURLModalNode).find("ul.recent-documents")[0]; - $(this.recentDocumentsNode).prev().attr('disabled', true); - - this.recentDocuments = {}; - if (localStorage.recentDocuments) { - this.recentDocuments = JSON.parse(localStorage.recentDocuments); - for (var key in this.recentDocuments) { - if ((key.substring(0, 4) != "http") && (key.substring(0, 4) != "file")) { - // no idea, but it's not a document - delete this.recentDocuments[key]; - continue; - } - var recentURL = key; // not sure, but key is not available in callback - // we found a document, enable "recent" button - $(this.recentDocumentsNode).prev().attr('disabled', false); - - var recentDocumentItem = $('\ - <li><a href="#"><!-- i class="glyphicon glyphicon-floppy-open" style="margin-right: 0.7em" / -->' + key + '<span class="recent-document-features"></span></a></li>\ - '); - var recentDocumentFeatures = $(recentDocumentItem).find("span.recent-document-features"); - $(recentDocumentItem).children("a").click(function() { - $(debug.loadFromURLModalNode).find("input#loadFromURLModalInput").val(recentURL); - $(debug.recentDocumentsNode).dropdown("toggle"); - return false; - }); - if ('breakpoints' in this.recentDocuments[key] && this.recentDocuments[key].breakpoints.length > 0) { - $(recentDocumentFeatures).append('<i title="Has Breakpoints" class="glyphicon glyphicon-th-list">'); - } - - $(this.recentDocumentsNode).append(recentDocumentItem); - } - } - - $("body").append(this.loadFromURLModalNode); - - var fromURLValidator = $(this.loadFromURLModalNode).find("form#loadFromURLModalForm").validate({ // initialize the plugin - rules: { scxmlUrl: { required: true, url2: true }}, - highlight: function(element) { - $(element).closest('.form-group').removeClass('has-success').addClass('has-error'); - }, - success: function(element) { - element.text('OK!').addClass('valid').closest('.input-group').removeClass('has-error').addClass('has-success'); - }, - submitHandler: function (form) { - $(debug.loadFromURLModalNode).modal("hide"); - return true; - } - }); - - $(this.loadFromURLModalNode).on('hide.bs.modal', function(e) { - if (!fromURLValidator.valid()) { - $(debug.loadFromURLModalNode).find(".form-group").removeClass('has-success').removeClass('has-error'); - $(debug.loadFromURLModalNode).find("input#loadFromURLModalInput").val(""); - } else { - var scxmlURL = $(debug.loadFromURLModalNode).find("input#loadFromURLModalInput").val(); - if (!(scxmlURL in debug.recentDocuments)) { - debug.recentDocuments[scxmlURL] = {}; - } - localStorage.recentDocuments = JSON.stringify(debug.recentDocuments); - debug.scxmlEditor.loadURL(scxmlURL); - } - fromURLValidator.resetForm(); - }); - - $(this.loadFromURLModalNode).modal(); - - }, - - initDataModel: function() { - var debug = this; - - $(this.clearDataModelLogButton).prop('disabled', true); - $(this.viewDataModelLogButton).prop('disabled', true); - - // add functionality to buttons - $(this.clearDataModelLogButton).mouseenter(function() { - $(this).addClass("btn-warning"); - }).mouseleave(function() { - $(this).removeClass("btn-warning"); - }).click(function() { - - return false; - }); - - this.dataModelListingNode = document.createElement('div'); - - this.dataModelEditor = ace.edit(this.dataModelListingNode, {}); - this.dataModelEditor.getSession().setUseWorker(false); - this.dataModelListingNode.style.fontSize='10px'; - this.dataModelEditor.setTheme("ace/theme/tomorrow"); - this.dataModelEditor.getSession().setMode("ace/mode/javascript"); - this.dataModelEditor.setReadOnly(true); - // this.dataModelEditor.getSession().setUseWrapMode(true); - this.dataModelEditor.setShowPrintMargin(false); - this.dataModelEditor.renderer.setShowGutter(false); - // this.dataModelEditor.getSession().setValue(vkbeautify.json(initialContent)); - $(this.dataModelListingNode).css("height", ((this.dataModelEditor.session.getLength() + 10) * 1.5) + "em"); - - $(this.dataModelNode).append(this.dataModelListingNode); - $(this.dataModelNode).append('\ - <div class="input-group input-group-sm">\ - <span class="input-group-btn">\ - <button title="Quick Command" type="button" class="datamodel-suggest btn dropdown-toggle" data-toggle="dropdown">\ - <span class="glyphicon glyphicon-list-alt"></span>\ - </button>\ - <ul class="suggested-commands dropdown-menu" role="menu">\ - <li><a href="#">_event</a></li>\ - <li><a href="#">_name</a></li>\ - <li><a href="#">_sessionid</a></li>\ - <li><a href="#">_invokers</a></li>\ - <li><a href="#">_ioprocessors</a></li>\ - <li><a href="#">_x</a></li>\ - </ul>\ - </span>\ - <input type="text" class="datamodel-eval form-control">\ - <div class="input-group-btn">\ - <button title="Evaluate as String" type="button" class="datamodel-eval btn btn-default"><span class="glyphicon glyphicon-play"></span></button>\ - </div>\ - </div>\ - '); - - this.dataModelInputNode = $(this.dataModelNode).find("input.datamodel-eval")[0]; - this.dataModelInputButton = $(this.dataModelNode).find("button.datamodel-eval")[0]; - this.dataModelSuggestButton = $(this.dataModelNode).find("button.datamodel-suggest")[0]; - - $(this.dataModelSuggestButton).prop('disabled', true); - - $(this.dataModelNode).find("ul.suggested-commands").find("li") - .unbind('click').click(function() { - var expression = $(this).children("a").text(); - $(debug.dataModelInputNode).val(expression); - debug.evalOnDataModel(expression); - $(this).closest("ul").dropdown('toggle'); - return false; - }); - - $(this.dataModelInputNode) - .prop('disabled', true) - .unbind('keypress').keypress(function(e) { - if (e.which == 13) - debug.evalOnDataModel($(this).val()); - }); - - $(this.dataModelInputButton) - .prop('disabled', true) - .unbind('click').click(function() { - debug.evalOnDataModel($(debug.dataModelInputNode).val()); - return false; - }); - - // $(this.dataModelListingNode).resizable({handles: "n, s"}); - // $(this.dataModelListingNode).resizable({grid: [100000, 1], alsoResize: $(this.node)}); - // $(this.dataModelListingNode).unbind('resize').on('resize', function() { - // debug.dataModelEditor.resize(); - // }); - }, - - initBreakpoints: function() { - var debug = this; - - $(this.deleteAllBreakpointsButton) - .unbind('mouseenter') - .unbind('mouseleave') - .unbind('click'); - $(this.deleteAllBreakpointsButton).mouseenter(function() { - $(this).addClass("btn-danger"); - }).mouseleave(function() { - $(this).removeClass("btn-danger"); - }).click(function() { - return false; - }); - - $(this.deleteAllBreakpointsButton).confirmation({ - singleton: true, - container: "body", - btnOkClass: "btn btn-danger", - btnOkLabel: "Delete All", - btnOkIcon: "glyphicon glyphicon-trash", - onConfirm: function() { - while (debug.breakpoints.length > 0) { - debug.removeBreakpoint(debug.breakpoints[0]); - } - } - }); - - $(this.disableBreakpointsButton).unbind('click'); - $(this.disableBreakpointsButton).click(function() { - $(this).toggleClass("btn-primary"); - if ($(this).hasClass("btn-primary")) { - debug.enableAllBreakpoints(); - } else { - debug.disableAllBreakpoints(); - } - return false; - }); - - $(this.addNewBreakpointsButton).unbind('click'); - $(this.addNewBreakpointsButton).click(function() { - debug.addBreakpoint(); - return false; - }); - - this.breakpointNode.innerHTML = '\ - <table class="table table-hover">\ - </table>\ - '; - - for (var index in this.breakpoints) { - $(this.breakpointNode).children("table").append(this.breakpoints[index].getNode()); - } - }, - - initCurrEvent: function() { - var debug = this; - - $(this.insertEventButton).prop('disabled', true); - $(this.editEventButton).prop('disabled', true); - $(this.viewEventButton).prop('disabled', true); - - var initialContent = ''; - - var editor = ace.edit(this.currEventNode, {}); - editor.getSession().setUseWorker(false); - this.currEventNode.style.fontSize='10px'; - editor.setTheme("ace/theme/tomorrow"); - editor.getSession().setMode("ace/mode/javascript"); - editor.setReadOnly(true); - editor.setShowPrintMargin(false); - editor.renderer.setShowGutter(false); - try { - editor.getSession().setValue(vkbeautify.json(initialContent)); - } catch(e) { - editor.getSession().setValue(initialContent); - } - $(this.currEventNode).css("height", (editor.session.getLength() * 1.5) + "em"); - - this.eventViewModal = $('\ - <div class="modal fade bs-example-modal-lg" id="eventViewModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">\ - <div class="modal-dialog modal-lg">\ - <form action="" id="eventViewModalForm">\ - <div class="modal-content">\ - <div class="modal-header">\ - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>\ - <h4 class="modal-title" id="myModalLabel">View / Edit Event</h4>\ - </div>\ - <div class="modal-body">\ - <div class="editor"></div>\ - </div>\ - <div class="modal-footer">\ - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\ - <button type="submit" class="btn btn-primary">Apply</button>\ - </div>\ - </div>\ - </form>\ - </div>\ - </div>\ - '); - - - $(this.eventViewModal).modal({ - show: false - }); - - // $(this.eventViewModal).find("div.modal-dialog").resizable(); - // $(this.eventViewModal).find("div.modal-dialog").draggable(); - - $("body").append(this.eventViewModal); - - // add functionality to buttons - $(this.viewEventButton).click(function() { - $(debug.eventViewModal).find(".editor"); - - var modalEditorNode = $(debug.eventViewModal).find(".editor")[0]; - - var modalEditor = ace.edit(modalEditorNode, {}); - modalEditorNode.style.fontSize='10px'; - // safari has the cursor somewhat off -// modalEditorNode.style.font='inherit!important'; - modalEditor.setTheme("ace/theme/tomorrow"); - modalEditor.getSession().setMode("ace/mode/javascript"); - modalEditor.setReadOnly(false); - modalEditor.setShowPrintMargin(false); - modalEditor.renderer.setShowGutter(true); - modalEditor.getSession().setValue(vkbeautify.json(initialContent)); - - $(modalEditorNode).css("min-height", (editor.session.getLength() * 1.5) + "em"); - //$(modalEditorNode).css("height", "80%"); - - $(debug.eventViewModal).modal("show"); - return false; - }); - - }, - - log: function(messages) { - var self = this; - - $(this.clearMessagesButton).prop('disabled', false); - - if (!self.messagesTextarea) { - console.log(messages); - return; - } - - function logSingleMsg(msg) { - // only show badge when when collapsed - if (!$(self.messagesNode).parent().hasClass("in")) { - var bagdeContent = parseInt($(self.messagesBadgeNode).html()) || 0; - $(self.messagesBadgeNode).html(bagdeContent + 1); - } - - if (typeof(msg) === 'string') { - self.messagesTextarea.value += msg.trim() + "\n"; - } else if (typeof(msg) === 'object') { - if ('formatted' in msg) { - self.messagesTextarea.value += msg.formatted.trim() + "\n"; - } else if('message' in msg) { - self.messagesTextarea.value += msg.message.trim() + "\n"; - } else { - try { - self.messagesTextarea.value += vkbeautify.json(msg) + "\n"; - } catch(e) { - self.messagesTextarea.value += JSON.stringify(msg).trim() + "\n"; - } - } - } else { - //not sure what to do here - self.messagesTextarea.value += msg; - } - } - - if (messages instanceof Array) { - for (var key in messages) { - logSingleMsg(messages[key]); - } - } else { - logSingleMsg(messages); - } - - // scroll to bottom - if (!$(self.messagesTextarea).hasClass("dont-scroll")) - self.messagesTextarea.scrollTop = self.messagesTextarea.scrollHeight; - }, - - // find a breakpoint by value and return its index - findBreakpoint: function(breakpoint) { - for (var index in this.breakpoints) { - var currBreakpoint = this.breakpoints[index]; - - // $("body").append("<pre>" + JSON.stringify(breakpoint.toWireFormat()) + "</pre><br />"); - // $("body").append("<pre>" + JSON.stringify(currBreakpoint.toWireFormat()) + "</pre><br />"); - if (Object.identical(breakpoint.toWireFormat(), currBreakpoint.toWireFormat())) { - return index; - } - } - return -1; - }, - - editBreakpoint: function(breakpoint) { - breakpoint.showEditDialog() - }, - - editedBreakpoint: function(breakpoint, oldData) { - // override to update your debugger - }, - - skipToBreakpoint: function(breakpoint) { - }, - - addBreakpoint: function(breakpoint) { - var debug = this; - if (breakpoint) { - breakpoint.scxmlEditor = this.scxmlEditor; - breakpoint.scxmlDebugger = this; - - if (this.findBreakpoint(breakpoint) < 0) { - // add as new breakpoint - this.breakpoints.push(breakpoint); - var breakpointNode = breakpoint.getNode(); - if (!debug.breakpointsEnabled) { - $(breakpointNode).find("button.enable").prop('disabled', true); - $(breakpointNode).find("button.skipto").prop('disabled', true); - } - $(this.breakpointNode).children("table").append(breakpointNode); - } - } else { - // show dialog to add a breakpoint - var newBreakpoint = new SCXMLEditor.Debugger.Breakpoint({ - scxmlEditor: this.scxmlEditor, - scxmlDebugger: this - }); - debug.editBreakpoint(newBreakpoint); - } - }, - - removeBreakpoint: function(breakpoint) { - var debug = this; - var breakPointIndex = this.findBreakpoint(breakpoint); - if (breakPointIndex >= 0) { - this.breakpoints.splice(breakPointIndex, 1); - $(this.breakpointNode).children("table").find("tr").slice(breakPointIndex, breakPointIndex + 1).detach(); - } - }, - - highlightBreakpoint: function(breakpoint) { - var breakPointIndex = this.findBreakpoint(breakpoint); - if (breakPointIndex < 0) - return; - - // open breakpoint collapsible - $(this.node).find("div.breakpoints").find("div.panel-collapse").addClass("in"); - - // highlight breakpoint - $(this.breakpointNode) - .children("table") - .find("tr").slice(breakPointIndex, breakPointIndex + 1) - .addClass("info"); - - }, - - unhighlightAllBreakpoints: function() { - $(this.breakpointNode) - .children("table") - .find("tr").removeClass("info"); - }, - - enableBreakpoint: function(breakpoint) { - var breakPointIndex = this.findBreakpoint(breakpoint); - if (breakPointIndex < 0) - return; - - $(this.breakpointNode) - .children("table") - .find("tr").slice(breakPointIndex, breakPointIndex + 1) - .find("button.enable").addClass('btn-primary'); - - $(this.breakpointNode) - .children("table") - .find("tr").slice(breakPointIndex, breakPointIndex + 1) - .find("button.skipto") - .prop('disabled', false); - - }, - - disableBreakpoint: function(breakpoint) { - var breakPointIndex = this.findBreakpoint(breakpoint); - if (breakPointIndex < 0) - return; - - $(this.breakpointNode) - .children("table") - .find("tr").slice(breakPointIndex, breakPointIndex + 1) - .find("button.enable").removeClass('btn-primary'); - - $(this.breakpointNode) - .children("table") - .find("tr").slice(breakPointIndex, breakPointIndex + 1) - .find("button.skipto") - .prop('disabled', true); - }, - - disableAllBreakpoints: function() { - this.breakpointsEnabled = false; - $(this.breakpointNode).find("button.enable").prop('disabled', true); - $(this.breakpointNode).find("button.skipto").prop('disabled', true); - }, - - enableAllBreakpoints: function() { - this.breakpointsEnabled = true; - - $(this.breakpointNode).find("button.enable").each(function() { - $(this).prop('disabled', false); - if ($(this).hasClass("btn-primary")) { - $(this).parent().children("button.skipto").prop('disabled', false); - } - }); - }, - - evalOnDataModel: function() { - }, - - attachDebug: function(sessionId) { - }, - - prepareDebug: function() { - this.scxmlText = SCXMLEditor.xmlToString(this.scxmlEditor.scxmlDOM); - }, - - startDebug: function() { - this.unhighlightAllBreakpoints(); - }, - - stopDebug: function() { - this.unhighlightAllBreakpoints(); - }, - - stepDebug: function() { - this.unhighlightAllBreakpoints(); - }, - - }); - - - SCXMLEditor.Debugger.Breakpoint = Base.extend({ - constructor: function(params) { - $.extend(this, params); - this.seqNr = SCXMLEditor.Debugger.Breakpoint.seqNr++; - }, - - data: {}, // all data describing this breakpoint - editNodes: {}, // html nodes of form-groups during editing - needed to retain input - TODO - - breakpointTypes: { - "categories": [ - { id: "state", label: "States" }, - { id: "event", label: "Events" }, - { id: "transition", label: "Transitions" }, - { id: "executable", label: "Executable Content" }, - { id: "invoke", label: "Invokers" }, - { id: "configuration", label: "Configuration" }, - ], - "types": [ - { id: "state-before-enter", - label: "Before Entering State", category: "state", - hint: "Stop execution <b>before</b> a given state is <b>entered</b>." - }, - { id: "state-after-enter", - label: "After Entering State", category: "state", - hint: "Stops execution <b>after</b> a given state is <b>entered</b>." - }, - { id: "state-before-exit", - label: "Before Exiting State", category: "state", - hint: "Stops execution <b>before</b> a given state was <b>exited</b>." - }, - { id: "state-after-exit", - label: "After Exiting State", category: "state", - hint: "Stops execution <b>after</b> a given state was <b>exited</b>." - }, - { id: "event-before", - label: "Before Processing Event", category: "event", - hint: "Stops execution <b>before</b> a given event is processed." - }, - { id: "transition-before", - label: "Before Taking Transition", category: "transition", - hint: "Stops execution <b>before</b> a given transition is taken." - }, - { id: "transition-after", - label: "After Taking Transition", category: "transition", - hint: "Stops execution <b>after</b> a given transition was taken." - }, - { id: "invoker-before-invoke", - label: "Before Starting Invoker", category: "invoke", - hint: "Stop execution <b>before</b> an invoker is <b>started</b>." - }, - { id: "invoker-after-invoke", - label: "After Starting Invoker", category: "invoke", - hint: "Stops execution <b>after</b> an invoker is <b>started</b>." - }, - { id: "invoker-before-cancel", - label: "Before Cancelling Invoker", category: "invoke", - hint: "Stop execution <b>before</b> an invoker is <b>cancelled</b>." - }, - { id: "invoker-after-cancel", - label: "After Cancelling Invoker", category: "invoke", - hint: "Stops execution <b>after</b> an invoker is <b>cancelled</b>." - }, - { id: "executable-before", - label: "Before Executing Content", category: "executable", - hint: "Stops <b>before</b> executing content." - }, - { id: "executable-after", - label: "After Executing Content", category: "executable", - hint: "Stops <b>after</b> executing content." - }, - { id: "microstep-before", - label: "Before Microstep", category: "configuration", - hint: "Stops execution <b>before</b> processing a microstep." - }, - { id: "microstep-after", - label: "After Microstep", category: "configuration", - hint: "Stops execution <b>after</b> after a microstep was processed." - }, - { id: "stable-on", - label: "On Stable Configuration", category: "configuration", - hint: "Stops execution when the interpreter reached a stable configuration and waits for events." - } - ] - }, - - isEnabled: function() { - return true; - }, - - toWireFormat: function() { - var jsonData = jQuery.extend(true, {}, this.data); - - if ('breakpointType' in this.data) { - var typeComponents = this.data.breakpointType.split("-"); - jsonData.subject = typeComponents[0]; - jsonData.when = typeComponents[1]; - if (typeComponents.length > 2) { - jsonData.action = typeComponents[2]; - } else { - delete jsonData.action; - } - } - delete jsonData.breakpointType; - - return jsonData; - }, - - showEditDialog: function() { - var breakpoint = this; - - // do we already have a modal div? - $("body").children("div#editBreakpointModal").remove(); - - this.editModalNode = $('\ - <div class="modal fade" id="editBreakpointModal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">\ - <div class="modal-dialog">\ - <form action="" class="form-horizontal" role="form">\ - <div class="modal-content">\ - <div class="modal-header">\ - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>\ - <h4 class="modal-title" id="myModalLabel"></h4>\ - </div>\ - <div class="modal-body">\ - <div class="form-group">\ - <label for="breakpointType" class="col-sm-2 control-label">Type</label>\ - <div class="col-sm-10 type-select"></div>\ - </div>\ - <div class="col-sm-2"></div><div class="col-sm-10 alert alert-info"></div>\ - </div>\ - <div class="modal-footer">\ - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\ - <button type="submit" class="btn btn-primary">Apply</button>\ - </div>\ - </div>\ - </form>\ - </div>\ - </div>\ - '); - - $(this.editModalNode).find("div.modal-body").find("div.type-select").append(this._typeSelectNode()); - $("body").append(this.editModalNode); - - this.editTypeInfoNode = $(this.editModalNode).find("div.alert-info")[0]; - this.editTypeNode = $(this.editModalNode).find("div.modal-body")[0]; - - var stateNames = this.scxmlEditor.getAllStateIds(); - - var editTypeSelectNode = $(this.editTypeNode).find("div.type-select").children("select"); - if ('breakpointType' in this.data) { - $(editTypeSelectNode).val(this.data.breakpointType); - $(this.editModalNode).find("h4.modal-title").text("Edit Breakpoint"); - } else { - $(this.editModalNode).find("h4.modal-title").text("Add Breakpoint"); - } - - $(this.editModalNode).find("form").removeData(); // important as closures persist with dom - $(this.editModalNode).find("form").validate({ - debug: true, - highlight: function(element) { - $(element).closest('.form-group').removeClass('has-success has-warning').addClass('has-error'); - }, - success: function(element) { - var state = element.closest('.form-group').find("input[name=stateId], input[name=toStateId], input[name=fromStateId]").val(); - if (state && $.inArray(state, stateNames) < 0) { - element.text('Warning: No such state!').addClass('valid').closest('.form-group').removeClass('has-success has-error').addClass('has-warning'); - return; - } - element.text('OK!').addClass('valid').closest('.form-group').removeClass('has-error has-warning').addClass('has-success'); - }, - submitHandler: function (form) { - $(breakpoint.editModalNode).modal("hide"); - - // reset - var oldData = jQuery.extend(true, {}, breakpoint.data); - breakpoint.data = {}; - - // copy over form fields - $(breakpoint.editTypeNode).find("textarea[name], input[name], select[name]").each(function() { - var name = $(this).attr("name"); - var value = $(this).val(); - if (name.length > 0 && value.length > 0) { - breakpoint.data[name] = value; - } - }) - console.log(breakpoint.data); - if (breakpoint.node) { - breakpoint._updateLabelNode(); - breakpoint._updateConditionNode(); - } - if (oldData.length > 0) { - breakpoint.scxmlDebugger.editedBreakpoint(breakpoint, oldData); - } else { - breakpoint.scxmlDebugger.addBreakpoint(breakpoint); - } - return true; - } - }); - - $(breakpoint.editTypeNode).children(".form-group").not(':first').remove(); - $(breakpoint.editTypeNode).children("input[type=hidden]").remove(); // hidden fields - - - $(editTypeSelectNode).change(function () { - $(breakpoint.editTypeNode).children(".form-group").not(':first').remove(); - $(breakpoint.editTypeNode).children("input[type=hidden]").remove(); // hidden fields - breakpoint._updateEditTypeDOM($(editTypeSelectNode).val()); - }); - this._updateEditTypeDOM($(editTypeSelectNode).val()); - - $(this.editModalNode).modal(); - }, - - _updateEditTypeDOM: function(typeId) { - var breakpoint = this; - var breakpointType = $.grep(this.breakpointTypes["types"], function(e){ return e.id == typeId; })[0]; - this.editTypeInfoNode.innerHTML = breakpointType.hint; - - // $(this.editTypeNode).append('\ - // <input type="hidden" name="label" value="' + breakpointType.label + '" />\ - // '); - - var stateNames = this.scxmlEditor.getAllStateIds(); - - switch(true) { - case /state-.*/.test(typeId): - var editTypeStateFormGroupNode = $('\ - <div class="form-group">\ - <label for="stateId" class="col-sm-2 control-label">State</label>\ - <div class="col-sm-10">\ - <input class="form-control" type="text" name="stateId" placeholder="The id of the state"/>\ - </div>\ - </div>\ - '); - $(this.editTypeNode).append(editTypeStateFormGroupNode); - $(editTypeStateFormGroupNode).find("input[name=stateId]") - .val('stateId' in breakpoint.data ? breakpoint.data.stateId : "") - .typeahead({local: stateNames}) - .rules('add', 'required'); - - break; - case /event-.*/.test(typeId): - var editTypeEventFormGroupNode = $('\ - <div class="form-group">\ - <label for="eventName" class="col-sm-2 control-label">Event</label>\ - <div class="col-sm-10">\ - <input class="form-control" type="text" name="eventName" placeholder="The name or prefix of the event"/>\ - </div>\ - </div>\ - '); - $(this.editTypeNode).append(editTypeEventFormGroupNode); - $(editTypeEventFormGroupNode).find("input[name=eventName]") - .val('eventName' in breakpoint.data ? breakpoint.data.eventName : "") - .rules('add', 'required'); - break; - case /transition-.*/.test(typeId): - var editTypeTransitionFormGroupNode = $('\ - <div class="form-group">\ - <label for="transSourceId" class="col-sm-2 control-label">From State</label>\ - <div class="col-sm-10">\ - <input class="form-control" type="text" name="transSourceId" placeholder="The id of the source state"/>\ - </div>\ - </div>\ - <div class="form-group">\ - <label for="transTargetId" class="col-sm-2 control-label">To State</label>\ - <div class="col-sm-10">\ - <input class="form-control" type="text" name="transTargetId" placeholder="The id of the destination state"/>\ - </div>\ - </div>\ - '); - $(this.editTypeNode).append(editTypeTransitionFormGroupNode); - $(editTypeTransitionFormGroupNode).find("input[name=transSourceId]") - .val('transSourceId' in breakpoint.data ? breakpoint.data.transSourceId : "") - .typeahead({local: stateNames}); - $(editTypeTransitionFormGroupNode).find("input[name=transTargetId]") - .val('transTargetId' in breakpoint.data ? breakpoint.data.transTargetId : "") - .typeahead({local: stateNames}); - break - case /invoker-.*/.test(typeId): - var editTypeInvokerFormGroupNode = $('\ - <div class="form-group">\ - <label for="invokeId" class="col-sm-2 control-label">Invoke ID</label>\ - <div class="col-sm-10">\ - <input class="form-control" type="text" name="invokeId" placeholder="The id of the invoker"/>\ - </div>\ - </div>\ - <div class="form-group">\ - <label for="invokeType" class="col-sm-2 control-label">Invoke Type</label>\ - <div class="col-sm-10">\ - <input class="form-control" type="text" name="invokeType" placeholder="The type of the invoker"/>\ - </div>\ - </div>\ - '); - $(this.editTypeNode).append(editTypeInvokerFormGroupNode); - $(editTypeInvokerFormGroupNode).find("input[name=invokeId]") - .val('invokeId' in breakpoint.data ? breakpoint.data.invokeId : ""); - $(editTypeInvokerFormGroupNode).find("input[name=invokeType]") - .val('invokeType' in breakpoint.data ? breakpoint.data.invokeType : ""); - break - - case /executable-.*/.test(typeId): - var editTypeExecutableFormGroupNode = $('\ - <div class="form-group">\ - <label for="executableName" class="col-sm-2 control-label">Element Name</label>\ - <div class="col-sm-10">\ - <input class="form-control" type="text" name="executableName" placeholder="The executable\'s element name"/>\ - </div>\ - </div>\ - <div class="form-group">\ - <label for="executableXPath" class="col-sm-2 control-label">Element XPath</label>\ - <div class="col-sm-10">\ - <input class="form-control" type="text" name="executableXPath" placeholder="The executable\'s XPath expression"/>\ - </div>\ - </div>\ - '); - $(this.editTypeNode).append(editTypeExecutableFormGroupNode); - $(editTypeExecutableFormGroupNode).find("input[name=executableName]") - .val('executableName' in breakpoint.data ? breakpoint.data.executableName : ""); - $(editTypeExecutableFormGroupNode).find("input[name=executableXPath]") - .val('executableXPath' in breakpoint.data ? breakpoint.data.executableXPath : ""); - break; - default: - break; - } - - var editTypeConditionFormGroupNode = $('\ - <div class="form-group">\ - <label for="condition" class="col-sm-2 control-label">Condition</label>\ - <div class="col-sm-10">\ - <textarea class="form-control" rows="4" style="resize:vertical;" name="condition" placeholder="An optional boolean expression evaluated on the datamodel. Breakpoint is only triggered if true." />\ - </div>\ - </div>\ - '); - $(editTypeConditionFormGroupNode).find("textarea[name=condition]") - .val('condition' in breakpoint.data ? breakpoint.data.condition : "") - - $(this.editTypeNode).append(editTypeConditionFormGroupNode); - }, - - getNode: function() { - var self = this; - this.node = $('\ - <tr>\ - <td>\ - <button title="Enable this Breakpoint" class="enable btn btn-default btn-xs btn-primary"><span class="glyphicon glyphicon-ok"></span></button><br />\ - <button title="Skip to this Breakpoint" class="skipto btn btn-default btn-xs"><span class="glyphicon glyphicon-fast-forward"></span></button>\ - </td>\ - <td width="100%">\ - <span class="breakpoint-label"></span>\ - <span class="breakpoint-condition"></span>\ - </td>\ - <td>\ - <button title="Edit this Breakpoint" class="edit btn btn-default btn-xs"><span class="glyphicon glyphicon-wrench"></span></button><br />\ - <button title="Remove this Breakpoint" class="delete btn btn-default btn-xs"><span class="glyphicon glyphicon-trash"></span></button>\ - </td>\ - </tr>\ - '); - - this.labelNode = $(this.node).find("span.breakpoint-label")[0]; - this.conditionNode = $(this.node).find("span.breakpoint-condition")[0]; - this.enableButtonNode = $(this.node).find("button.enable")[0]; - this.skipToButtonNode = $(this.node).find("button.skipto")[0]; - this.deleteButtonNode = $(this.node).find("button.delete")[0]; - this.editButtonNode = $(this.node).find("button.edit")[0]; - - $(this.enableButtonNode) - .unbind('click') - .click(function() { - if ($(this).hasClass("btn-primary")) { - self.scxmlDebugger.disableBreakpoint(self); - } else { - self.scxmlDebugger.enableBreakpoint(self); - } - return false; - }); - - $(this.deleteButtonNode) - .unbind('mouseenter') - .unbind('mouseleave') - .unbind('click') - .mouseenter(function() { - $(this).addClass("btn-danger"); - }) - .mouseleave(function() { - $(this).removeClass("btn-danger"); - }) - .click(function() { - self.scxmlDebugger.removeBreakpoint(self); - return false; - }); - - $(this.editButtonNode) - .unbind('click').click(function() { - self.showEditDialog() - return false; - }); - - $(this.skipToButtonNode) - .unbind('click').click(function() { - self.scxmlDebugger.skipToBreakpoint(self); - return false; - }); - - this._updateLabelNode(); - this._updateConditionNode(); - - return this.node; - }, - - toDescription: function() { - var wireFormat = this.toWireFormat(); - - var breakpointString = ''; - breakpointString += ('when' in wireFormat ? wireFormat.when + ' ' : ''); - breakpointString += ('action' in wireFormat ? wireFormat.action + ' ' : ''); - breakpointString += ('subject' in wireFormat ? wireFormat.subject + ' ' : ''); - - breakpointString += (wireFormat.subject === 'state' ? wireFormat.stateId + ' ' : ''); - breakpointString += (wireFormat.subject === 'event' ? wireFormat.eventName + ' ' : ''); - if (wireFormat.subject === 'transition') { - breakpointString += ('transSourceId' in wireFormat ? wireFormat.transSourceId + ' ' : '* '); - breakpointString += '⇒ '; - breakpointString += ('transTargetId' in wireFormat ? wireFormat.transTargetId + ' ' : '* '); - } - - return breakpointString; - }, - - _updateLabelNode: function() { - this.labelNode.innerHTML = 'Halt ' + this.toDescription(); - }, - - _updateConditionNode: function() { - if (this.data.condition) { - this.conditionNode.innerHTML = "<br/>But only when <code>" + this.data.condition + "</code>"; - } else { - this.conditionNode.innerHTML = ''; - } - }, - - _typeSelectNode: function() { - // establish optgroups for selecting the breakpoint type - var optGroups = {}; - for (var index in this.breakpointTypes.types) { - var bp = this.breakpointTypes.types[index]; - var optGroup = bp.category; - if (!(optGroup in optGroups)) optGroups[optGroup] = []; - optGroups[optGroup].push(bp); - } - - var breakpointTypeSelectNode = document.createElement('select'); - breakpointTypeSelectNode.className = 'form-control'; - $(breakpointTypeSelectNode).attr("name", "breakpointType"); - - for (var optGroup in this.breakpointTypes.categories) { - var cat = this.breakpointTypes.categories[optGroup]; - var optGroupNode = document.createElement('optgroup'); - $(optGroupNode).attr('label', cat.label); - - for(var type in optGroups[cat.id]) { - var breakpointType = optGroups[cat.id][type]; - var optionNode = document.createElement('option'); - $(optionNode).attr('value', breakpointType.id); - optionNode.innerHTML = breakpointType.label; - $(optionNode).appendTo(optGroupNode); - } - $(optGroupNode).appendTo(breakpointTypeSelectNode); - } - - return breakpointTypeSelectNode; - }, - - }); - SCXMLEditor.Debugger.Breakpoint.seqNr = 0; - - SCXMLEditor.Debugger.USCXML = SCXMLEditor.Debugger.extend({ - constructor: function(params) { - this.base(params); - - this.isConnected = false; // we have a connection to the uscxml server - this.isPrepared = false; // we uploaded a document - this.isRunning = false; // the interpreter on the server is running - this.isPaused = false; // the interpreter is running but paused - this.hasDOMLoaded = false; // the client has a DOM loaded - this.isAttached = false; // we are attached to a server session - this.isPolling = false; // we have a unreplied poll request standing - this.sessionId = ""; - }, - - _updateDebugControls: function() { - // all buttons are disabled per base class - $(this.startButtonNode).prop('disabled', true) - $(this.pauseButtonNode).prop('disabled', true); - $(this.stepButtonNode).prop('disabled', true); - - var status = ""; - status += (this.isConnected ? "CON " : "con "); - status += (this.isPolling ? "POL " : "pol "); - status += (this.isPrepared ? "PRP " : "prp "); - status += (this.isRunning ? "RUN " : "run "); - status += (this.isPaused ? "PAU " : "pau "); - status += (this.hasDOMLoaded ? "DOM " : "dom "); - status += (this.isAttached ? "ATC " : "atc "); - - $(this.statusIndicatorNode).html(status); - - // some sanity - if (!this.isConnected) { - $("body").find(".dom").text(""); - $(this.currentBreakpointNode).html(""); - this.isPaused = false; - this.isRunning = false; - this.isAttached = false; - this.isPrepared = false; - } - - if (!this.isRunning) { - this.isPaused = false; - $(this.currentBreakpointNode).html(""); - } - - // toggle button icons - if (this.isRunning) { // switch play and stop - $(this.startButtonNode).children("span.glyphicon").removeClass("glyphicon-play").addClass("glyphicon-stop"); - $(this.startButtonNode).prop('title', 'Stop Execution'); - } else { - $(this.startButtonNode).children("span.glyphicon").removeClass("glyphicon-stop").addClass("glyphicon-play"); - $(this.startButtonNode).prop('title', 'Start Execution'); - } - - if (!this.isPaused) { // switch pause and resume - $(this.pauseButtonNode).removeClass("active"); - $(this.pauseButtonNode).prop('title', 'Pause Execution'); - this.unhighlightAllBreakpoints(); - $(this.currentBreakpointNode).html(""); - } else { - $(this.pauseButtonNode).addClass("active"); - $(this.pauseButtonNode).prop('title', 'Resume Execution'); - } - - if (this.isConnected && (this.hasDOMLoaded || this.isAttached)) { - // are we connected, not running and have a DOM or are attached? - if (!this.isAttached) { - $(this.startButtonNode).prop('disabled', false); - } - if (this.isRunning) { - $(this.pauseButtonNode).prop('disabled', false); - $(this.stepButtonNode).prop('disabled', false); - } else { - $(this.startButtonNode).prop('disabled', false) - $(this.pauseButtonNode).prop('disabled', true); - $(this.stepButtonNode).prop('disabled', false); - } - return; - } else { - $("body").find(".dom").text(""); - } - }, - - loadDOM: function(scxmlDOM) { - this.hasDOMLoaded = true; - this._updateDebugControls(); - }, - - getNode: function() { - this.base(); - var debug = this; - - // a new menu item - $(this.controlDropdownNode).append('\ - <li role="presentation" class="divider"></li>\ - <li class="disabled"><a href="#"><i class="glyphicon glyphicon-resize-small"></i> Attach to Instance</a></li>\ - '); - - // the connect bar - $(this.node).find(".debug-header").after('\ - <div class="panel-body input-group input-group-sm">\ - <input type="text" class="form-control connect" placeholder="uSCMXL Interpreter URL">\ - <span class="input-group-btn">\ - <button title="Connect" class="btn btn-default ladda-button connect" data-spinner-color="#000" data-style="zoom-in">\ - <span class="ladda-label"><span class="ui-icon ui-icon-unlocked"></span></span></button>\ - </span>\ - </div>\ - '); - - this.connectInputNode = $(this.node).find("input.connect"); - this.connectButtonNode = $(this.connectInputNode).next().children("button.connect")[0]; - - if (this.debuggerURL) { - $(this.connectInputNode).val(this.debuggerURL); - } else { - $(this.connectInputNode).attr("placeholder", "URL of uscxml-debug"); - } - - $(this.connectInputNode).focus(function () { - $(debug.connectButtonNode) - .removeClass("btn-warning") - .find("span.ui-icon") - .removeClass("ui-icon-alert ui-icon-locked") - .addClass("ui-icon-unlocked"); - }); - - $(this.connectInputNode).unbind('keypress').keypress(function(e) { - if (e.which == 13) - $(debug.connectButtonNode).trigger('click'); - }); - - - $(this.connectButtonNode).unbind("click"); - $(this.connectButtonNode).click(function() { - debug.connectSpinner = Ladda.create(this); - debug.connectSpinner.start(); - if (debug.isConnected) { - debug.disconnect(); - } else { - debug.connect($(debug.connectInputNode).val()); - } - }); - - // debug controls - $(this.startButtonNode) - .unbind('click').click(function () { - $(this).tooltip("hide"); - if ($(this).children(".glyphicon").hasClass("glyphicon-play")) { - debug.startDebug(); - } else { - debug.stopDebug(); - } - }); - - $(this.pauseButtonNode) - .unbind('click').click(function() { - $(this).tooltip("hide"); - if (debug.isPaused) { - debug.resumeDebug(); - } else { - debug.pauseDebug(); - } - }); - - $(this.stepButtonNode) - .unbind('click').click(function() { - $(this).tooltip("hide"); - debug.stepDebug(); - }); - - this._updateDebugControls(); - - return this.node; - }, - - _indicateLockedConnection: function() { - $(this.connectButtonNode) - .removeClass("btn-warning") - .find("span.ui-icon") - .removeClass("ui-icon-alert ui-icon-unlocked") - .addClass("ui-icon-locked"); - $(this.connectInputNode).attr('disabled', true); - $(this.dataModelInputNode).prop('disabled', false); - $(this.dataModelInputButton).prop('disabled', false); - $(this.dataModelSuggestButton).prop('disabled', false); - }, - - _indicateFailedConnection: function() { - $(this.connectButtonNode) - .addClass("btn-warning") - .find("span.ui-icon") - .removeClass("ui-icon-locked ui-icon-unlocked") - .addClass("ui-icon-alert"); - }, - - _indicateUnlockedConnection: function() { - $(this.connectButtonNode) - .removeClass("btn-warning") - .find("span.ui-icon") - .removeClass("ui-icon-locked ui-icon-alert") - .addClass("ui-icon-unlocked"); - $(this.connectInputNode).attr('disabled', false); - $(this.dataModelInputNode).prop('disabled', true); - $(this.dataModelInputButton).prop('disabled', true); - $(this.dataModelSuggestButton).prop('disabled', true); - }, - - connect: function(debuggerURL) { - if (!debuggerURL || debuggerURL.length == 0) - return; - - this.debuggerURL = debuggerURL; - - var self = this; - - this.requestWithJSON('/debug/connect', { - onFailure: function(dataObj, statusString, xhrObj) { - self.isConnected = false; - self._indicateFailedConnection(); - }, - onSuccess: function(dataObj, statusString, xhrObj) { - self.isConnected = true; - self._indicateLockedConnection(); - - self.log("Client successfully connected to " + self.debuggerURL); - self.sessionId = dataObj.session; - // send all breakpoints when connected - if (self.breakpoints.length > 0) { - for (var index in self.breakpoints) { - self.addBreakpoint(self.breakpoints[index]); - } - } - // register disconnect handler - $(window).unload(function() { - self.disconnect(); - }); - // update list of sessions from server - self.updateServerSessions(); - // and start long-poller - self.pollServer(); - }, - onComplete: function(dataObj, statusString) { - self.connectSpinner.stop(); - } - }); - }, - - disconnect: function() { - if (!this.isConnected) - return; - var self = this; - - this.requestWithJSON('/debug/disconnect', { - async: false, - onComplete: function(dataObj, statusString) { - self.isConnected = false; - self.isPrepared = false; - self._indicateUnlockedConnection(); - self.connectSpinner.stop(); - - // remove all previous sessions - $(self.controlDropdownNode).children("li.server-session").remove(); - self.debuggerURL = ''; - } - }); - }, - - updateServerSessions: function() { - this.base(); - if (!this.isConnected) - return; - - var self = this; - - this.requestWithJSON('/debug/sessions', { - onSuccess: function(dataObj, statusString, xhrObj) { - $(self.controlButtonNode).effect('highlight', {color: '#4489CA'}, 600); - - // remove all previous sessions - $(self.controlDropdownNode).children("li.server-session").remove(); - for (var key in dataObj.sessions) { - $(self.controlDropdownNode).append('\ - <li class="server-session" \ - session-url="' + dataObj.sessions[key].source + '"\ - session-name="' + dataObj.sessions[key].name + '"\ - session-id="' + dataObj.sessions[key].id + '"\ - ><a href="#"><i class="glyphicon glyphicon-link"></i> ' + dataObj.sessions[key].source + '</a></li>\ - '); - } - $(self.controlDropdownNode).find("li").unbind('click').click(function() { - var session = { - sessionId: $(this).attr("session-id"), - sessionName: $(this).attr("session-name"), - sessionURL: $(this).attr("session-url"), - }; - self.attachDebug(session); - - $(self.controlDropdownNode).dropdown('toggle'); - return false; - }); - } - }); - }, - - - addBreakpoint: function(breakpoint) { - this.base(breakpoint); - if (!this.isConnected) - return; - - if (!breakpoint) // it's perfectly fine to call this without a breakpoint - will add a new one - return; - - this.requestWithJSON('/debug/breakpoint/add', { - data: breakpoint.toWireFormat() - }); - }, - - removeBreakpoint: function(breakpoint) { - this.base(breakpoint); - if (!this.isConnected) - return; - this.requestWithJSON('/debug/breakpoint/remove', { - data: breakpoint.toWireFormat() - }); - }, - - editedBreakpoint: function(breakpoint, oldData) { - this.base(breakpoint, oldData); - if (!this.isConnected) - return; - - var oldBreakpoint = new SCXMLEditor.Debugger.Breakpoint({ data : oldData }); - this.requestWithJSON('/debug/breakpoint/remove', { - data: oldBreakpoint.toWireFormat() - }); - this.requestWithJSONBlocking('/debug/breakpoint/add', { - data: breakpoint.toWireFormat() - }); - }, - - skipToBreakpoint: function(breakpoint) { - this.base(breakpoint); - if (!this.isConnected) - return; - - this.requestWithJSON('/debug/breakpoint/skipto', { - data: breakpoint.toWireFormat() - }); - - }, - - enableBreakpoint: function(breakpoint) { - this.base(breakpoint); - if (!this.isConnected) - return; - - this.requestWithJSON('/debug/breakpoint/enable', { - data: breakpoint.toWireFormat() - }); - }, - - disableBreakpoint: function(breakpoint) { - this.base(breakpoint); - if (!this.isConnected) - return; - - this.requestWithJSON('/debug/breakpoint/disable', { - data: breakpoint.toWireFormat() - }); - }, - - enableAllBreakpoints: function() { - this.base(); - if (!this.isConnected) - return; - - this.requestWithJSON('/debug/breakpoint/enable/all'); - }, - - disableAllBreakpoints: function() { - this.base(); - if (!this.isConnected) - return; - - this.requestWithJSON('/debug/breakpoint/disable/all'); - - }, - - - attachDebug: function(session) { - this.base(); - if (!this.isConnected) - return; - - var self = this; - - var data = { - attach: session.sessionId, - }; - - this.requestWithJSON('/debug/attach', { - data: data, - onSuccess: function(dataObj, statusString, xhrObj) { - self.isPrepared = true; - self.isRunning = true; - self.isAttached = true; - - if (self.scxmlEditor.xmlView) { - self.scxmlEditor.xmlView.setXML(dataObj.xml) - self.scxmlEditor.xmlView.prettyPrint(); - } - - // var domText = vkbeautify.xml(dataObj.xml); - // $("body").find("pre.dom").text(domText); - self.scxmlEditor.setDocumentNameFromURL(session.sessionURL); - self._updateDebugControls(); - } - }); - - }, - - prepareDebug: function() { - this.base(); - if (!this.isConnected) - return; - - if (this.isAttached) - return; - - var self = this; - - var data = { - url: this.scxmlEditor.scxmlURL, - xml: this.scxmlText - }; - - this.requestWithJSON('/debug/prepare', { - data: data, - onSuccess: function(dataObj, statusString, xhrObj) { - self.isPrepared = true; - } - }); - }, - - startDebug: function() { - this.base(); - if (!this.isConnected) - return; - - if (!this.isPrepared) - this.prepareDebug(); - - var self = this; - - this.requestWithJSON('/debug/start', { - onSuccess: function(dataObj, statusString, xhrObj) { - self.isRunning = true; - } - }); - }, - - stopDebug: function() { - this.base(); - if (!this.isConnected) - return; - - var self = this; - - this.requestWithJSON('/debug/stop', { - onSuccess: function(dataObj, statusString, xhrObj) { - self.isRunning = false; - self.isPrepared = false; - } - }); - }, - - pauseDebug: function() { - this.base(); - if (!this.isConnected) - return; - - var self = this; - - this.requestWithJSON('/debug/pause', { - onSuccess: function(dataObj, statusString, xhrObj) { - self.isPaused = true; - self._updateDebugControls(); - } - }); - }, - - resumeDebug: function() { - this.base(); - if (!this.isConnected) - return; - - var self = this; - - this.requestWithJSON('/debug/resume', { - onSuccess: function(dataObj, statusString, xhrObj) { - self.isPaused = false; - self._updateDebugControls(); - } - }); - }, - - stepDebug: function() { - this.base(); - if (!this.isConnected) - return; - - if (!this.isPrepared) - this.prepareDebug(); - - var self = this; - - this.requestWithJSON('/debug/step', { - onSuccess: function(dataObj, statusString, xhrObj) { - self.isRunning = true; - self.isPaused = true; - self._updateDebugControls(); - } - }); - }, - - evalOnDataModel: function(expression) { - this.base(); - if (!this.isConnected) - return; - - var self = this; - - var data = {}; - data.expression = expression; - - this.requestWithJSON('/debug/eval', { - data: data, - onSuccess: function(dataObj, statusString, xhrObj) { - var content = JSON.stringify(dataObj.eval); - self.dataModelEditor.getSession().setValue(vkbeautify.json(content)); - - }, - }); - - }, - - // server will return 'status' with JSON response, dispatch accordingly - requestWithJSON: function(url, params) { - var self = this; - if (!params) - params = {}; - - params.method = ('method' in params ? params.method : "POST"); - params.async = ('async' in params ? params.async : true); - params.onSuccess = ('onSuccess' in params ? params.onSuccess : function() {}); - params.onFailure = ('onFailure' in params ? params.onFailure : function(dataObj) { self.log(dataObj); }); - params.onComplete = ('onComplete' in params ? params.onComplete : function() {}); - params.onError = ('onError' in params ? params.onError : function() {}); - params.returnType = ('returnType' in params ? params.returnType : "json"); - params.sendType = ('sendType' in params ? params.sendType : "application/json; charset=utf-8"); - params.data = ('data' in params ? params.data : {}); - - if (params.sendType.match("^application/json")) { - if (this.sessionId.length > 0) // automatically add session - params.data.session = this.sessionId; - params.data = JSON.stringify(params.data); - } - - $.ajax({ - type: params.method, - dataType: params.returnType, - async: params.async, - data: params.data, - contentType: params.sendType, - url: this.debuggerURL + url, - success: function (dataObj, statusString, xhrObj) { - self.log("Received from " + url); - self.log(dataObj); - - if ("status" in dataObj && dataObj.status === 'success') { - params.onSuccess(dataObj, statusString, xhrObj); - } else { - params.onFailure(dataObj, statusString, xhrObj); - } - }, - error: function(xhrObj, statusString, errorString) { - self.log("Error from " + self.debuggerURL + url); - self.log(statusString + "\n\t" + errorString); - self.log(xhrObj); - - self.isConnected = false; - self._indicateFailedConnection(); - params.onError(errorString, statusString, xhrObj); - }, - complete: function(xhrObj, statusString) { - params.onComplete(xhrObj, statusString); - self._updateDebugControls(); - } - }); - }, - - handleBreakpointReturn: function(serverReturn) { - var updateViewer = false; - if ('qualified' in serverReturn) { - var qualifiedBreakpoint = new SCXMLEditor.Debugger.Breakpoint({ data : serverReturn.qualified }); - var breakpointString = 'Halted ' + qualifiedBreakpoint.toDescription(); - $(this.currentBreakpointNode).html(breakpointString); - - if ('xpath' in serverReturn.qualified) { - if (this.scxmlEditor.xmlView) { - this.scxmlEditor.xmlView.setElementXPath(serverReturn.qualified.xpath); - } - } else { - this.scxmlEditor.xmlView.setElementXPath(""); - } - } - - if ('basicStates' in serverReturn) { - if (this.scxmlEditor.xmlView) { - this.scxmlEditor.xmlView.setActiveStates(serverReturn['basicStates']); - } - } - - if (this.scxmlEditor.xmlView) { - this.scxmlEditor.xmlView.prettyPrint(); - } - - if ('breakpoint' in serverReturn) { - var breakpoint = new SCXMLEditor.Debugger.Breakpoint({ data : serverReturn.breakpoint }); - this.highlightBreakpoint(breakpoint); - } - - }, - - pollServer: function() { - this.isPolling = false; - this._updateDebugControls(); - - if (!this.isConnected) - return; - - if (this.sessionId.length == 0) - return; - - var self = this; - this.isPolling = true; - self._updateDebugControls(); - - $.ajax({ - type: "POST", - dataType: "json", - async: true, - timeout: 100000000, - data: JSON.stringify({session: this.sessionId}), - contentType: "application/json", - url: this.debuggerURL + '/debug/poll', - success: function (dataObj, statusString, xhrObj) { - try { - if ('status' in dataObj) { - if (dataObj.status !== 'success') { - self.log("Error from " + self.debuggerURL + "/debug/poll"); - self.log(dataObj); - return; - } - } - if ('replyType' in dataObj) { - //self.log("Received " + dataObj.replyType); - if (dataObj.replyType === "log") { - self.log(dataObj); - } else if (dataObj.replyType === "finished") { - self.isRunning = false; - self.isPrepared = false; - } else if (dataObj.replyType === "breakpoint") { - self.isPaused = true; - self.log(dataObj); - self.handleBreakpointReturn(dataObj); - } else { - self.log("Unhandled reply from /pollServer"); - self.log(dataObj); - } - } else { - self.log("Untyped reply from /pollServer"); - self.log(dataObj); - } - } catch(e) { - self.log("Exception when dispatching server push:"); - self.log(e); - } - // dispatch server push here - self.pollServer(); - }, - error: function(xhrObj, statusString, errorString) { - if (xhrObj.statusText === "timeout") { - self.pollServer(); // just repoll - return; - } - - self.log("Error from /pollServer"); - self.log(statusString + "\n\t" + errorString); - self.log(xhrObj); - - self.isConnected = false; - self._indicateFailedConnection(); - }, - complete: function(xhrObj, statusString) { - self._updateDebugControls(); - } - }); - - }, - - }); - - // see http://nealvs.wordpress.com/2010/07/12/how-to-compare-two-javascript-objects-for-equality/ - function deepEquals(x, y) { - for (var p in y) { - if (typeof(y[p]) !== typeof(x[p])) return false; - if ((y[p] === null) !== (x[p] === null)) return false; - switch (typeof(y[p])) { - case 'undefined': - if (typeof(x[p]) != 'undefined') return false; - break; - case 'object': - if (y[p] !== null && x[p] !== null && (y[p].constructor.toString() !== x[p].constructor.toString() || !y[p].equals(x[p]))) return false; - break; - case 'function': - if (p != 'equals' && y[p].toString() != x[p].toString()) return false; - break; - default: - if (y[p] !== x[p]) return false; - } - } - return true; - } - - $(document).ready(function() { - - - // see http://stackoverflow.com/questions/18754020/bootstrap-3-with-jquery-validation-plugin - $.validator.setDefaults({ - highlight: function(element) { - $(element).closest('.form-group').addClass('has-error'); - }, - unhighlight: function(element) { - $(element).closest('.form-group').removeClass('has-error'); - }, - errorElement: 'span', - errorClass: 'help-block', - errorPlacement: function(error, element) { - if(element.parent('.input-group').length) { - error.insertAfter(element.parent()); - } else { - error.insertAfter(element); - } - } - }); - - var scxmlEdit = new SCXMLEditor({ - containerNode: $("#scxml-editor")[0] - }); - - }); - - </script> -</head> -<body> - <div id="scxml-editor"></div> - <div class="messages"></div> - <div class="dom"></pre> -</body> -</html> diff --git a/apps/uscxml-dot.cpp b/apps/uscxml-dot.cpp deleted file mode 100644 index 0fcd548..0000000 --- a/apps/uscxml-dot.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "uscxml/config.h" -#include "uscxml/Interpreter.h" -#include "uscxml/dom/DOMUtils.h" -#include "uscxml/debug/SCXMLDotWriter.h" -#include <glog/logging.h> -#include "getopt.h" - -#include "uscxml/Factory.h" -#include <boost/algorithm/string.hpp> - - -using namespace uscxml; - -void printUsageAndExit(const char* progName) { - // remove path from program name - std::string progStr(progName); - if (progStr.find_last_of(PATH_SEPERATOR) != std::string::npos) { - progStr = progStr.substr(progStr.find_last_of(PATH_SEPERATOR) + 1, progStr.length() - (progStr.find_last_of(PATH_SEPERATOR) + 1)); - } - - printf("%s version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n", progStr.c_str()); - printf("Usage\n"); - printf("\t%s", progStr.c_str()); - printf(" [-eTYPE] [-dN] [-tN] URL"); - printf(" [[-dN] [-tN] [-eTYPE] state_id1] .. [[-dN] [-tN] [-eTYPE] state_idM]"); - printf("\n"); - printf("Options\n"); - printf("\tURL : URL of SCXML document\n"); - printf("\t-e TYPE : type of edges to use:\n"); - printf("\t 'target' - aggregate per target node (default)\n"); - printf("\t 'event' - aggregate per event name\n"); - printf("\t 'transition' no aggregation, display each transition\n"); - printf("\t-d : depth below anchor node (INF per default)\n"); - printf("\t-t : transition depth below anchor (INF per default)\n"); - printf("\tstate_id : anchor node state id (topmost scxml element per default)\n"); - printf("\n"); - exit(1); -} - -int currOpt = 1; - -int main(int argc, char** argv) { - - // setup logging - google::LogToStderr(); - google::InitGoogleLogging(argv[0]); - - - if (argc < 2) - printUsageAndExit(argv[0]); - - std::list<SCXMLDotWriter::StateAnchor> stateAnchors; - SCXMLDotWriter::StateAnchor rootAnchor; - SCXMLDotWriter::StateAnchor currAnchor; - - int option; - while ((option = getopt(argc, argv, "d:t:e:")) != -1) { - switch(option) { - case 'd': - rootAnchor.childDepth = strTo<int32_t>(optarg); - break; - case 't': - rootAnchor.transDepth = strTo<int32_t>(optarg); - break; - case 'e': { - std::string edgeType(optarg); - if (edgeType == "target") { - rootAnchor.type = SCXMLDotWriter::PORT_TARGET; - } else if (edgeType == "event") { - rootAnchor.type = SCXMLDotWriter::PORT_EVENT; - } else if (edgeType == "transition") { - rootAnchor.type = SCXMLDotWriter::PORT_TRANSITION; - } else { - printUsageAndExit(argv[0]); - } - break; - } - default: - break; - } - } - - if (rootAnchor) - stateAnchors.push_back(rootAnchor); - - try { - // current option has to be the interpreter's name - URL inputFile(argv[optind]); - Interpreter interpreter = Interpreter::fromURL(inputFile.asString()); - optind++; - - while(optind < argc) { - // are - while ((option = getopt(argc, argv, "d:t:")) != -1) { - switch(option) { - case 'd': - currAnchor.childDepth = strTo<int32_t>(optarg); - break; - case 't': - currAnchor.transDepth = strTo<int32_t>(optarg); - break; - default: - break; - } - } - if (argc > optind) { - std::string expr(argv[optind++]); - currAnchor.element = interpreter.getImpl()->getState(expr); - } else { - printUsageAndExit(argv[0]); - } - - if (currAnchor) { - currAnchor.type = rootAnchor.type; - stateAnchors.push_back(currAnchor); - } - - currAnchor = SCXMLDotWriter::StateAnchor(); - } - - std::string outName; - if (boost::starts_with("file", inputFile.scheme())) { - outName = inputFile.path() + ".dot"; - } else { - outName = inputFile.file() + ".dot"; - } - - SCXMLDotWriter::toDot(outName, interpreter, stateAnchors); - - } catch(Event e) { - std::cerr << e << std::cout; - } - - return EXIT_SUCCESS; -} diff --git a/apps/uscxml-transform.cpp b/apps/uscxml-transform.cpp index 2dc4d74..6fd1bf7 100644 --- a/apps/uscxml-transform.cpp +++ b/apps/uscxml-transform.cpp @@ -1,63 +1,24 @@ #include "uscxml/config.h" #include "uscxml/Interpreter.h" -#include "uscxml/transform/ChartToFlatSCXML.h" +#include "uscxml/util/String.h" #include "uscxml/transform/ChartToC.h" #include "uscxml/transform/ChartToVHDL.h" -#include "uscxml/transform/ChartToTex.h" -#include "uscxml/transform/ChartToMinimalSCXML.h" -#include "uscxml/transform/ChartToPromela.h" -#include "uscxml/dom/DOMUtils.h" -#include <glog/logging.h> #include <boost/algorithm/string.hpp> #include <fstream> #include <iostream> #include <map> -#include "uscxml/Factory.h" +#include "uscxml/plugins/Factory.h" #include "uscxml/server/HTTPServer.h" #include "getopt.h" -#ifdef HAS_SIGNAL_H -#include <signal.h> -#endif - -#ifdef HAS_EXECINFO_H -#include <execinfo.h> -#endif - -#ifdef HAS_DLFCN_H -#include <dlfcn.h> -#endif +#include <easylogging++.h> #define ANNOTATE(envKey, annotationParam) \ envVarIsTrue(envKey) || std::find(options.begin(), options.end(), annotationParam) != options.end() -class VerboseMonitor : public uscxml::InterpreterMonitor { - void onStableConfiguration(uscxml::Interpreter interpreter) { - printConfig(interpreter.getConfiguration()); - } - - void beforeProcessingEvent(uscxml::Interpreter interpreter, const uscxml::Event& event) { - std::cerr << "Event: " << event.name << std::endl; - } - - void beforeCompletion(uscxml::Interpreter interpreter) { - printConfig(interpreter.getConfiguration()); - } - - void printConfig(const Arabica::XPath::NodeSet<std::string>& config) { - std::string seperator; - std::cerr << "Config: {"; - for (size_t i = 0; i < config.size(); i++) { - std::cerr << seperator << ATTR_CAST(config[i], "id"); - seperator = ", "; - } - std::cerr << "}" << std::endl; - } -}; - void printUsageAndExit(const char* progName) { // remove path from program name std::string progStr(progName); @@ -119,10 +80,6 @@ int main(int argc, char** argv) { signal(SIGPIPE, SIG_IGN); #endif - // setup logging - google::LogToStderr(); - google::InitGoogleLogging(argv[0]); - optind = 0; opterr = 0; @@ -270,7 +227,7 @@ int main(int argc, char** argv) { ss << line; } URL tmp("anonymous.scxml"); - tmp.toAbsoluteCwd(); + tmp = URL::resolveWithCWD(tmp); interpreter = Interpreter::fromXML(ss.str(), tmp); } else { interpreter = Interpreter::fromURL(inputFile); @@ -283,18 +240,17 @@ int main(int argc, char** argv) { if (!interpreter) { URL tmp(inputFile); - tmp.toAbsoluteCwd(); - std::stringstream contentSS; - contentSS << tmp; + tmp = URL::resolveWithCWD(tmp); + std::string content = tmp.getInContent(); std::string inlineBeginMarker = "INLINE SCXML BEGIN\n"; std::string inlineEndMarker = "\nINLINE SCXML END"; - size_t inlineSCXMLBegin = contentSS.str().find(inlineBeginMarker); + size_t inlineSCXMLBegin = content.find(inlineBeginMarker); if (inlineSCXMLBegin != std::string::npos) { inlineSCXMLBegin += inlineBeginMarker.size(); - size_t inlineSCXMLEnd = contentSS.str().find(inlineEndMarker); - std::string inlineSCXMLContent = contentSS.str().substr(inlineSCXMLBegin, inlineSCXMLEnd - inlineSCXMLBegin); + size_t inlineSCXMLEnd = content.find(inlineEndMarker); + std::string inlineSCXMLContent = content.substr(inlineSCXMLBegin, inlineSCXMLEnd - inlineSCXMLBegin); try { interpreter = Interpreter::fromXML(inlineSCXMLContent, tmp); } catch (Event e) { @@ -335,68 +291,68 @@ int main(int argc, char** argv) { exit(EXIT_SUCCESS); } - if (outType == "vhdl") { - if (outputFile.size() == 0 || outputFile == "-") { - ChartToVHDL::transform(interpreter).writeTo(std::cout); - } else { - std::ofstream outStream; - outStream.open(outputFile.c_str()); - ChartToVHDL::transform(interpreter).writeTo(outStream); - outStream.close(); - } - exit(EXIT_SUCCESS); - } +// if (outType == "vhdl") { +// if (outputFile.size() == 0 || outputFile == "-") { +// ChartToVHDL::transform(interpreter).writeTo(std::cout); +// } else { +// std::ofstream outStream; +// outStream.open(outputFile.c_str()); +// ChartToVHDL::transform(interpreter).writeTo(outStream); +// outStream.close(); +// } +// exit(EXIT_SUCCESS); +// } - if (outType == "pml") { - if (outputFile.size() == 0 || outputFile == "-") { - ChartToPromela::transform(interpreter).writeTo(std::cout); - } else { - std::ofstream outStream; - outStream.open(outputFile.c_str()); - ChartToPromela::transform(interpreter).writeTo(outStream); - outStream.close(); - } - exit(EXIT_SUCCESS); - } +// if (outType == "pml") { +// if (outputFile.size() == 0 || outputFile == "-") { +// ChartToPromela::transform(interpreter).writeTo(std::cout); +// } else { +// std::ofstream outStream; +// outStream.open(outputFile.c_str()); +// ChartToPromela::transform(interpreter).writeTo(outStream); +// outStream.close(); +// } +// exit(EXIT_SUCCESS); +// } - if (outType == "tex") { - if (outputFile.size() == 0 || outputFile == "-") { - ChartToTex::transform(interpreter).writeTo(std::cout); - } else { - std::ofstream outStream; - outStream.open(outputFile.c_str()); - ChartToTex::transform(interpreter).writeTo(outStream); - outStream.close(); - } - exit(EXIT_SUCCESS); - } +// if (outType == "tex") { +// if (outputFile.size() == 0 || outputFile == "-") { +// ChartToTex::transform(interpreter).writeTo(std::cout); +// } else { +// std::ofstream outStream; +// outStream.open(outputFile.c_str()); +// ChartToTex::transform(interpreter).writeTo(outStream); +// outStream.close(); +// } +// exit(EXIT_SUCCESS); +// } - if (outType == "flat") { - if (outputFile.size() == 0 || outputFile == "-") { - ChartToFlatSCXML::transform(interpreter).writeTo(std::cout); - } else { - std::ofstream outStream; - outStream.open(outputFile.c_str()); - ChartToFlatSCXML::transform(interpreter).writeTo(outStream); - outStream.close(); - } - exit(EXIT_SUCCESS); - } +// if (outType == "flat") { +// if (outputFile.size() == 0 || outputFile == "-") { +// ChartToFlatSCXML::transform(interpreter).writeTo(std::cout); +// } else { +// std::ofstream outStream; +// outStream.open(outputFile.c_str()); +// ChartToFlatSCXML::transform(interpreter).writeTo(outStream); +// outStream.close(); +// } +// exit(EXIT_SUCCESS); +// } - if (outType == "min") { - if (outputFile.size() == 0 || outputFile == "-") { - ChartToMinimalSCXML::transform(interpreter).writeTo(std::cout); - } else { - std::ofstream outStream; - outStream.open(outputFile.c_str()); - ChartToMinimalSCXML::transform(interpreter).writeTo(outStream); - outStream.close(); - } - exit(EXIT_SUCCESS); - } +// if (outType == "min") { +// if (outputFile.size() == 0 || outputFile == "-") { +// ChartToMinimalSCXML::transform(interpreter).writeTo(std::cout); +// } else { +// std::ofstream outStream; +// outStream.open(outputFile.c_str()); +// ChartToMinimalSCXML::transform(interpreter).writeTo(outStream); +// outStream.close(); +// } +// exit(EXIT_SUCCESS); +// } -#if 1 +#if 0 if (options.size() > 0) { ChartToFSM annotater(interpreter); if (std::find(options.begin(), options.end(), "priority") != options.end()) diff --git a/apps/w3c-mmi/MMIEventServlet.cpp b/apps/w3c-mmi/MMIEventServlet.cpp deleted file mode 100644 index 2d88f1b..0000000 --- a/apps/w3c-mmi/MMIEventServlet.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include "MMIEventServlet.h" -#include <uscxml/NameSpacingParser.h> - -#ifdef _WIN32 -#define NOMINMAX -#include <winsock2.h> -#include <windows.h> -#endif - -#include "uscxml/Message.h" -#include <iostream> -#include <event2/dns.h> -#include <event2/buffer.h> -#include <event2/keyvalq_struct.h> - -#include <string.h> - -#include <io/uri.hpp> -#include <glog/logging.h> - -#ifndef _WIN32 -#include <netdb.h> -#include <arpa/inet.h> -#endif - -#define MMI_HTTP_EVENT_CASE(type) \ -else if (boost::iequals(mmiEvent.getLocalName(), #type)) { \ - monIter = _monitors.begin(); \ - while(monIter != _monitors.end()) { \ - (*monIter)->received(type::fromXML(mmiDoc)); \ - monIter++; \ - } \ -} - -namespace uscxml { - -using namespace Arabica::DOM; - -MMIEventServlet::MMIEventServlet(const std::string& path) : _path(path) { - // register at http server - bool success = HTTPServer::registerServlet(_path, this); - assert(success); -} - -MMIEventServlet::~MMIEventServlet() { - HTTPServer* httpServer = HTTPServer::getInstance(); - httpServer->unregisterServlet(this); -} - -void MMIEventServlet::send(const MMIEvent& mmiEvent) { - URL url(mmiEvent.target); - url.addMonitor(this); - - std::stringstream content; - content << mmiEvent.toXML(); - url.setOutContent(content.str()); - url.download(); - -} - -bool MMIEventServlet::httpRecvRequest(const HTTPServer::Request& req) { - - // is this a request from a HTML browser? - - - Document<std::string> mmiDoc = NameSpacingParser::fromXML(req.data.compound.at("content").atom).getDocument(); - if (!mmiDoc) { - evhttp_send_error(req.curlReq, 402, NULL); - return true; - } - -// std::cout << mmiDoc.getNamespaceURI() << std::endl; - Node<std::string> mmiEvent = mmiDoc.getFirstChild(); - // get the first element - while (mmiEvent && mmiEvent.getNodeType() != Node_base::ELEMENT_NODE) { - mmiEvent = mmiEvent.getNextSibling(); - } - // get the contained message - if (boost::iequals(mmiEvent.getLocalName(), "mmi")) { - mmiEvent = mmiEvent.getFirstChild(); - while (mmiEvent && mmiEvent.getNodeType() != Node_base::ELEMENT_NODE) { - mmiEvent = mmiEvent.getNextSibling(); - } - } -// std::cout << mmiEvent << std::endl; - - if (!mmiEvent) { - evhttp_send_error(req.curlReq, 402, NULL); - return true; - } - - std::set<MMIEventReceiver*>::iterator monIter; - if (false) {} - MMI_HTTP_EVENT_CASE(NewContextRequest) - MMI_HTTP_EVENT_CASE(NewContextResponse) - MMI_HTTP_EVENT_CASE(PrepareRequest) - MMI_HTTP_EVENT_CASE(PrepareResponse) - MMI_HTTP_EVENT_CASE(StartRequest) - MMI_HTTP_EVENT_CASE(StartResponse) - MMI_HTTP_EVENT_CASE(DoneNotification) - MMI_HTTP_EVENT_CASE(CancelRequest) - MMI_HTTP_EVENT_CASE(CancelResponse) - MMI_HTTP_EVENT_CASE(PauseRequest) - MMI_HTTP_EVENT_CASE(PauseResponse) - MMI_HTTP_EVENT_CASE(ResumeRequest) - MMI_HTTP_EVENT_CASE(ResumeResponse) - MMI_HTTP_EVENT_CASE(ExtensionNotification) - MMI_HTTP_EVENT_CASE(ClearContextRequest) - MMI_HTTP_EVENT_CASE(ClearContextResponse) - MMI_HTTP_EVENT_CASE(StatusRequest) - MMI_HTTP_EVENT_CASE(StatusResponse) - else { - LOG(ERROR) << "Unknown MMI Event"; - evhttp_send_error(req.curlReq, 402, NULL); - return true; - } - - evhttp_send_reply(req.curlReq, 204, NULL, NULL); - -#if 0 - Event reqEvent = req; - reqEvent.type = Event::EXTERNAL; - bool scxmlStructFound = false; - - if (reqEvent.data.compound["header"].compound.find("Content-Type") != reqEvent.data.compound["header"].compound.end() && - boost::iequals(reqEvent.data.compound["header"].compound["Content-Type"].atom, "application/x-www-form-urlencoded")) { - std::stringstream ss(reqEvent.data.compound["content"].atom); - std::string term; - while(std::getline(ss, term, '&')) { - size_t split = term.find_first_of("="); - if (split != std::string::npos) { - std::string key = evhttp_decode_uri(term.substr(0, split).c_str()); - std::string value = evhttp_decode_uri(term.substr(split + 1).c_str()); - if (boost::iequals(key, "_scxmleventname")) { - reqEvent.name = value; - } else if (boost::iequals(key, "content")) { - reqEvent.initContent(value); - } else { - reqEvent.data.compound[key] = value; - reqEvent.params.insert(std::make_pair(key, value)); - } - } else { - // this is most likely wrong - reqEvent.content = evhttp_decode_uri(term.c_str()); - } - } - } else { - if (reqEvent.data.compound["header"].compound.find("_scxmleventstruct") != reqEvent.data.compound["header"].compound.end()) { - // TODO: this looses all other information - reqEvent = Event::fromXML(evhttp_decode_uri(reqEvent.data.compound["header"].compound["_scxmleventstruct"].atom.c_str())); - scxmlStructFound = true; - } - if (reqEvent.data.compound["header"].compound.find("_scxmleventname") != reqEvent.data.compound["header"].compound.end()) { - reqEvent.name = evhttp_decode_uri(reqEvent.data.compound["header"].compound["_scxmleventname"].atom.c_str()); - } - } - std::map<std::string, Data>::iterator headerIter = reqEvent.data.compound["header"].compound.begin(); - while(headerIter != reqEvent.data.compound["header"].compound.end()) { - reqEvent.data.compound[headerIter->first] = Data(evhttp_decode_uri(headerIter->second.atom.c_str()), Data::VERBATIM); - headerIter++; - } - - - /// test532 - if (reqEvent.name.length() == 0) - reqEvent.name = "http." + req.data.compound.at("type").atom; - - if (!scxmlStructFound) { - // get content into event - reqEvent.data.compound["content"] = Data(req.content, Data::VERBATIM); - } - - evhttp_send_reply(req.curlReq, 200, "OK", NULL); -#endif - return true; -} - -void MMIEventServlet::downloadStarted(const URL& url) {} - -void MMIEventServlet::downloadCompleted(const URL& url) { - std::map<std::string, std::pair<URL, SendRequest> >::iterator reqIter = _sendRequests.begin(); - while(reqIter != _sendRequests.end()) { - if (reqIter->second.first == url) { - _sendRequests.erase(reqIter); - return; - } - reqIter++; - } - assert(false); -} - -void MMIEventServlet::downloadFailed(const URL& url, int errorCode) { - - std::map<std::string, std::pair<URL, SendRequest> >::iterator reqIter = _sendRequests.begin(); - while(reqIter != _sendRequests.end()) { - if (reqIter->second.first == url) { - Event failEvent; - failEvent.name = "error.communication"; -// returnEvent(failEvent); - - _sendRequests.erase(reqIter); - return; - } - reqIter++; - } - assert(false); - -} - - -}
\ No newline at end of file diff --git a/apps/w3c-mmi/MMIEventServlet.h b/apps/w3c-mmi/MMIEventServlet.h deleted file mode 100644 index d760149..0000000 --- a/apps/w3c-mmi/MMIEventServlet.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef MMIEVENTSERVLET_H_92WSR1SU -#define MMIEVENTSERVLET_H_92WSR1SU - - -#include "uscxml/concurrency/eventqueue/DelayedEventQueue.h" -#include "uscxml/server/HTTPServer.h" -#include "uscxml/Interpreter.h" -#include "uscxml/Factory.h" -#ifndef _WIN32 -#include <sys/time.h> -#endif - -#include <event2/http.h> -#include <event2/http_struct.h> - -#include <uscxml/plugins/ioprocessor/modality/MMIMessages.h> - -namespace uscxml { - - class MMIEventServlet : public HTTPServlet, public URLMonitor, public MMIEventSender { - public: - MMIEventServlet(const std::string& path); - virtual ~MMIEventServlet(); - - void addMonitor(MMIEventReceiver* mmiMonitor) { - _monitors.insert(mmiMonitor); - } - void removeMonitor(MMIEventReceiver* mmiMonitor) { - _monitors.erase(mmiMonitor); - } - - /// HTTPServlet - bool httpRecvRequest(const HTTPServer::Request& req); - void setURL(const std::string& url) { - _url = url; - } - std::string getURL() { return _url; } - - bool canAdaptPath() { - return false; - } - - // URLMonitor - void downloadStarted(const URL& url); - void downloadCompleted(const URL& url); - void downloadFailed(const URL& url, int errorCode); - - // MMIEventSender - virtual void send(const MMIEvent& mmiEvent); - - protected: - std::string _url; - std::string _path; - std::map<std::string, std::pair<URL, SendRequest> > _sendRequests; - std::set<MMIEventReceiver*> _monitors; - }; -} - -#endif /* end of include guard: MMIEVENTSERVLET_H_92WSR1SU */ diff --git a/apps/w3c-mmi/im/MMISessionManager.cpp b/apps/w3c-mmi/im/MMISessionManager.cpp deleted file mode 100644 index 2e68ff4..0000000 --- a/apps/w3c-mmi/im/MMISessionManager.cpp +++ /dev/null @@ -1,297 +0,0 @@ -#include "MMISessionManager.h" -#include <uscxml/NameSpacingParser.h> -#include <uscxml/concurrency/tinythread.h> -#include <uscxml/UUID.h> - -#include <io/uri.hpp> -#include <glog/logging.h> - -namespace uscxml { - -using namespace Arabica::DOM; - -MMISessionManager::MMISessionManager(Interpreter interpreter) : _protoInterpreter(interpreter) { - bool success = HTTPServer::registerServlet(interpreter.getName(), this); - assert(success); - _factory = new Factory(Factory::getInstance()); - _factory->registerIOProcessor(new MMIIOProcessor(this)); -} - -MMISessionManager::~MMISessionManager() { - HTTPServer* httpServer = HTTPServer::getInstance(); - httpServer->unregisterServlet(this); -} - -void MMISessionManager::setupHTMLClient(const HTTPServer::Request& req) { - // open template file - HTTPServer::Reply reply(req); - URL templateURL(_protoInterpreter.getBaseURI().asString() + "/templates/mc-html.html"); - templateURL.download(true); - std::string templateContent = templateURL.getInContent(); - boost::replace_all(templateContent, "${im.url}", _url); - reply.content = templateContent; - HTTPServer::reply(reply); -} - -bool MMISessionManager::httpRecvRequest(const HTTPServer::Request& req) { - // is this an initial request from an HTML MC? - if (!req.data["query"]["token"] && // no token in query - !req.data["query"]["context"] && // no context in query - boost::iequals(req.data["type"].atom, "get") && // request type is GET - boost::icontains(req.data["header"]["Accept"].atom, "text/html") && // accepts html - req.content.length() == 0) { // no content - setupHTMLClient(req); - return true; - } - - // is this a comet longpolling request? - if (boost::iequals(req.data["type"].atom, "get") && - (req.data["query"]["token"] || req.data["query"]["context"])) { - std::string token = req.data["query"]["token"].atom; - if (req.data["query"]["token"]) { - std::string token = req.data["query"]["token"].atom; - if (_tokens.find(token) != _tokens.end()) { - MMISessionManager::CometMMISession* comet = static_cast<MMISessionManager::CometMMISession*>(_tokens[token]); - comet->longPoll(req); - return true; - } else { - LOG(ERROR) << "No session for given token"; - } - } else if (req.data["query"]["context"]) { - std::string context = req.data["query"]["context"].atom; - if (_sessions.find(context) != _sessions.end()) { - MMISessionManager::CometMMISession* comet = static_cast<MMISessionManager::CometMMISession*>(_sessions[context]); - comet->longPoll(req); - return true; - } else { - LOG(ERROR) << "No session for given context"; - } - } - } - - // assume that there is an mmi event inside - Document<std::string> mmiDoc = NameSpacingParser::fromXML(req.data.compound.at("content").atom).getDocument(); - - if (!mmiDoc) { - evhttp_send_error(req.curlReq, 204, NULL); - return true; - } - - Node<std::string> mmiEvent = MMIEvent::getEventNode(mmiDoc); - if (!mmiEvent) { - evhttp_send_error(req.curlReq, 204, NULL); - return true; - } - - switch(MMIEvent::getType(mmiEvent)) { - case MMIEvent::NEWCONTEXTREQUEST: { - received(NewContextRequest::fromXML(mmiEvent), req.data["query"]["token"].atom); - evhttp_send_error(req.curlReq, 204, NULL); - break; - } - case MMIEvent::EXTENSIONNOTIFICATION: { - received(ExtensionNotification::fromXML(mmiEvent)); - evhttp_send_error(req.curlReq, 204, NULL); - break; - } - case MMIEvent::DONENOTIFICATION: { - received(DoneNotification::fromXML(mmiEvent)); - evhttp_send_error(req.curlReq, 204, NULL); - break; - } - case MMIEvent::STARTRESPONSE: { - evhttp_send_error(req.curlReq, 204, NULL); - break; - } - default: { - LOG(ERROR) << "Unknown MMI Event: " << ATTR(mmiEvent, "localName"); - evhttp_send_error(req.curlReq, 204, NULL); - break; - } - } - return true; -} - -void MMISessionManager::received(const ExtensionNotification& mmiEvent) { - if(_sessions.find(mmiEvent.context) != _sessions.end()) { - _sessions[mmiEvent.context]->_interpreter.receive(mmiEvent); - } else { - LOG(ERROR) << "No session for given context"; - } -} - -void MMISessionManager::received(const DoneNotification& mmiEvent) { - if(_sessions.find(mmiEvent.context) != _sessions.end()) { - _sessions[mmiEvent.context]->_interpreter.receive(mmiEvent); - } else { - LOG(ERROR) << "No session for given context"; - } -} - -void MMISessionManager::received(const NewContextRequest& mmiEvent, const std::string& token) { - - // copy DOM from prototype instance - Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation(); - Arabica::DOM::Document<std::string> newDOM = domFactory.createDocument("", "", 0); - newDOM.appendChild(newDOM.importNode(_protoInterpreter.getDocument().getDocumentElement(), true)); - - // instantiate new interpreter and name it after the context - std::string contextId = UUID::getUUID(); - Interpreter interpreter = Interpreter::fromDOM(newDOM); - interpreter.setFactory(_factory); - interpreter.setName(contextId); - interpreter.setNameSpaceInfo(_protoInterpreter.getNameSpaceInfo()); - interpreter.setBaseURI(_protoInterpreter.getBaseURI().asString()); - - MMISession* session; - - if (token.length() > 0) { - session = new MMISessionManager::CometMMISession(); - static_cast<MMISessionManager::CometMMISession*>(session)->_token = token; - _tokens[token] = session; - } else { - // todo handle other cases - session = new MMISessionManager::CometMMISession(); - } - session->_interpreter = interpreter; - - // save interpreter - _sessions[contextId] = session; - - interpreter.start(); - interpreter.receive(mmiEvent); - -} - -void MMISessionManager::received(const NewContextResponse& mmiEvent, const std::string& token) { - if (_tokens.find(token) != _tokens.end()) { - _tokens.erase(token); - } -} - -void MMISessionManager::send(const std::string& name, const SendRequest& req) { - assert(_sessions.find(name) != _sessions.end()); - _sessions[name]->send(req); -} - -void MMISessionManager::CometMMISession::send(const SendRequest& req) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - if (!_longPollingReq) { - _outQueue.push_back(req); - return; - } - - if (req.dom) { - std::stringstream ss; - Node<std::string> mmiEvent = MMIEvent::getEventNode(req.dom); - HTTPServer::Reply reply(_longPollingReq); - - switch (MMIEvent::getType(mmiEvent)) { - case MMIEvent::NEWCONTEXTRESPONSE: { - NewContextResponse response = NewContextResponse::fromXML(mmiEvent); - ss << response.toXML(); - reply.content = ss.str(); - break; - } - case MMIEvent::STARTREQUEST: { - StartRequest request = StartRequest::fromXML(mmiEvent); - ss << request.toXML(); - reply.content = ss.str(); - break; - } - default: - break; - } - reply.headers["Content-Type"] = "application/xml"; - HTTPServer::reply(reply); - _longPollingReq = HTTPServer::Request(); - } -} - -void MMISessionManager::CometMMISession::receive(const Arabica::DOM::Node<std::string>& msg) { - -} - -void MMISessionManager::CometMMISession::longPoll(const HTTPServer::Request& req) { - tthread::lock_guard<tthread::recursive_mutex> lock(_mutex); - if (_longPollingReq) - evhttp_send_error(_longPollingReq.curlReq, 204, NULL); - _longPollingReq = req; - if (!_outQueue.empty()) { - send(_outQueue.front()); - _outQueue.pop_front(); - } -} - -boost::shared_ptr<IOProcessorImpl> MMISessionManager::MMIIOProcessor::create(InterpreterImpl* interpreter) { - boost::shared_ptr<IOProcessorImpl> ioProc = boost::shared_ptr<IOProcessorImpl>(new MMISessionManager::MMIIOProcessor(_sessionManager)); - return ioProc; -} - -Data MMISessionManager::MMIIOProcessor::getDataModelVariables() { - Data data; - return data; -} - -void MMISessionManager::MMIIOProcessor::send(const SendRequest& req) { - SendRequest reqCopy(req); - - if (req.dom) { - Arabica::DOM::Node<std::string> mmiEvent = MMIEvent::getEventNode(req.dom); - if (!mmiEvent || !mmiEvent.getNodeType() == Node_base::ELEMENT_NODE) - return; - - Arabica::DOM::Element<std::string> mmiElem = Arabica::DOM::Element<std::string>(mmiEvent); - switch (MMIEvent::getType(mmiEvent)) { - case MMIEvent::STARTRESPONSE: - case MMIEvent::PREPARERESPONSE: - case MMIEvent::PAUSERESPONSE: - case MMIEvent::RESUMERESPONSE: - case MMIEvent::CANCELRESPONSE: - case MMIEvent::DONENOTIFICATION: - case MMIEvent::NEWCONTEXTRESPONSE: - case MMIEvent::CLEARCONTEXTRESPONSE: - case MMIEvent::STATUSRESPONSE: { - // all of the above have a status - if (!mmiElem.hasAttributeNS(MMIEvent::nameSpace, "Status")) { - mmiElem.setAttributeNS(MMIEvent::nameSpace, "Status", "Success"); - } - } - case MMIEvent::PAUSEREQUEST: - case MMIEvent::RESUMEREQUEST: - case MMIEvent::CANCELREQUEST: - case MMIEvent::CLEARCONTEXTREQUEST: - case MMIEvent::STATUSREQUEST: { - // all of the above have a context - if (!mmiElem.hasAttributeNS(MMIEvent::nameSpace, "Context")) { - mmiElem.setAttributeNS(MMIEvent::nameSpace, "Context", _interpreter->getName()); - } - } - default: { - if (!mmiElem.hasAttributeNS(MMIEvent::nameSpace, "Source")) { - mmiElem.setAttributeNS(MMIEvent::nameSpace, "Source", _sessionManager->getURL()); - } - if (!mmiElem.hasAttributeNS(MMIEvent::nameSpace, "Target")) { - if (boost::starts_with(_interpreter->getCurrentEvent().name, "mmi.")) { - mmiElem.setAttributeNS(MMIEvent::nameSpace, "Target", _interpreter->getCurrentEvent().origin); - } - } - if (!mmiElem.hasAttributeNS(MMIEvent::nameSpace, "RequestID")) { - if (boost::starts_with(_interpreter->getCurrentEvent().name, "mmi.")) { - mmiElem.setAttributeNS(MMIEvent::nameSpace, "RequestID", _interpreter->getCurrentEvent().sendid); - } - } - } - } - - if (MMIEvent::getType(mmiEvent) == MMIEvent::EXTENSIONNOTIFICATION && !mmiElem.hasAttribute("Name") && req.name.length() > 0) { - mmiElem.setAttribute("Name", req.name); - } - // use session mgr to dispatch to session - - _sessionManager->send(_interpreter->getName(), reqCopy); - } - -} - -}
\ No newline at end of file diff --git a/apps/w3c-mmi/im/MMISessionManager.h b/apps/w3c-mmi/im/MMISessionManager.h deleted file mode 100644 index 222bf34..0000000 --- a/apps/w3c-mmi/im/MMISessionManager.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef MMISESSIONMANAGER_H_IHDWUAKD -#define MMISESSIONMANAGER_H_IHDWUAKD - -#include <uscxml/Interpreter.h> -#include <deque> -#include "../MMIEventServlet.h" - -namespace uscxml { - class MMISessionManager : public HTTPServlet { - public: - MMISessionManager(Interpreter interpreter); - ~MMISessionManager(); - - class MMISession { - public: - Interpreter _interpreter; - tthread::recursive_mutex _mutex; - virtual void send(const SendRequest& req) = 0; - virtual void receive(const Arabica::DOM::Node<std::string>& msg) = 0; - }; - - class CometMMISession : public MMISession { - public: - std::deque<SendRequest> _outQueue; - HTTPServer::Request _longPollingReq; - std::string _token; - - void send(const SendRequest& req); - void receive(const Arabica::DOM::Node<std::string>& msg); - void longPoll(const HTTPServer::Request& req); - }; - - class MMIIOProcessor : public IOProcessorImpl { - public: - MMIIOProcessor(MMISessionManager* sessionManager) : _sessionManager(sessionManager) {} - - // IOProcessorImpl - virtual boost::shared_ptr<IOProcessorImpl> create(InterpreterImpl* interpreter); - virtual std::list<std::string> getNames() { - std::list<std::string> names; - names.push_back("mmi.event"); - return names; - } - virtual Data getDataModelVariables(); - virtual void send(const SendRequest& req); - protected: - MMISessionManager* _sessionManager; - }; - - void send(const std::string& name, const SendRequest& req); - - /// HTTPServlet - bool httpRecvRequest(const HTTPServer::Request& req); - void setURL(const std::string& url) { - _url = url; - } - std::string getURL() { return _url; } - - bool canAdaptPath() { - return false; - } - - protected: - void received(const NewContextRequest& mmiEvent, const std::string& token = ""); - void received(const NewContextResponse& mmiEvent, const std::string& token = ""); - void received(const ExtensionNotification& mmiEvent); - void received(const DoneNotification& mmiEvent); - - void setupHTMLClient(const HTTPServer::Request& req); - - Interpreter _protoInterpreter; - Factory* _factory; - DelayedEventQueue _eventQueue; - std::map<std::string, MMISession*> _sessions; - std::map<std::string, MMISession*> _tokens; - std::string _url; - }; -} - - -#endif /* end of include guard: MMISESSIONMANAGER_H_IHDWUAKD */ diff --git a/apps/w3c-mmi/im/uscxml-interaction-manager.cpp b/apps/w3c-mmi/im/uscxml-interaction-manager.cpp deleted file mode 100644 index b6b75f6..0000000 --- a/apps/w3c-mmi/im/uscxml-interaction-manager.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "uscxml/config.h" -#include "uscxml/Interpreter.h" -#include <glog/logging.h> -#include "uscxml/concurrency/tinythread.h" - -#include "MMISessionManager.h" - -#ifdef HAS_SIGNAL_H -#include <signal.h> -#endif - -#ifdef HAS_EXECINFO_H -#include <execinfo.h> -#endif - -#ifdef HAS_DLFCN_H -#include <dlfcn.h> -#endif - -#ifdef _WIN32 -#include "XGetopt.h" -#endif - -class VerboseMonitor : public uscxml::InterpreterMonitor { - void onStableConfiguration(uscxml::Interpreter interpreter) { - printConfig(interpreter.getConfiguration()); - } - - void beforeCompletion(uscxml::Interpreter interpreter) { - printConfig(interpreter.getConfiguration()); - } - - void printConfig(const Arabica::XPath::NodeSet<std::string>& config) { - std::string seperator; - std::cout << "Config: {"; - for (int i = 0; i < config.size(); i++) { - std::cout << seperator << ATTR(config[i], "id"); - seperator = ", "; - } - std::cout << "}" << std::endl; - } -}; - - -#ifdef HAS_EXECINFO_H -void printBacktrace(void** array, int size) { - char** messages = backtrace_symbols(array, size); - for (int i = 0; i < size && messages != NULL; ++i) { - std::cerr << "\t" << messages[i] << std::endl; - } - std::cerr << std::endl; - free(messages); -} - -#ifdef HAS_DLFCN_H -// see https://gist.github.com/nkuln/2020860 -typedef void (*cxa_throw_type)(void *, void *, void (*) (void *)); -cxa_throw_type orig_cxa_throw = 0; - -void load_orig_throw_code() { - orig_cxa_throw = (cxa_throw_type) dlsym(RTLD_NEXT, "__cxa_throw"); -} - -extern "C" -CXA_THROW_SIGNATURE { - std::cerr << __FUNCTION__ << " will throw exception from " << std::endl; - if (orig_cxa_throw == 0) - load_orig_throw_code(); - - void *array[50]; - size_t size = backtrace(array, 50); - printBacktrace(array, size); - orig_cxa_throw(thrown_exception, pvtinfo, dest); -} -#endif -#endif - - -// see http://stackoverflow.com/questions/2443135/how-do-i-find-where-an-exception-was-thrown-in-c -void customTerminate() { - static bool tried_throw = false; - try { - // try once to re-throw currently active exception - if (!tried_throw) { - throw; - tried_throw = true; - } else { - tried_throw = false; - }; - } catch (const std::exception &e) { - std::cerr << __FUNCTION__ << " caught unhandled exception. what(): " - << e.what() << std::endl; - } catch (const uscxml::Event &e) { - std::cerr << __FUNCTION__ << " caught unhandled exception. Event: " - << e << std::endl; - } catch (...) { - std::cerr << __FUNCTION__ << " caught unknown/unhandled exception." - << std::endl; - } - -#ifdef HAS_EXECINFO_H - void * array[50]; - int size = backtrace(array, 50); - - printBacktrace(array, size); -#endif - abort(); -} - -void printUsageAndExit() { - printf("uscxml-browser version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n"); - printf("Usage\n"); - printf("\tuscxml-browser"); -#ifdef BUILD_AS_PLUGINS - printf(" [-d pluginPath]"); -#endif - printf(" URL\n"); - printf("\n"); - printf("Options\n"); - printf("\t-v : be verbose\n"); - printf("\t-pN : port for HTTP server\n"); - printf("\n"); - exit(1); -} - -int main(int argc, char** argv) { - using namespace uscxml; - - std::set_terminate(customTerminate); - -#if defined(HAS_SIGNAL_H) && !defined(WIN32) - signal(SIGPIPE, SIG_IGN); -#endif - - if (argc < 2) { - printUsageAndExit(); - } - - bool verbose = false; - size_t port = 8080; - google::InitGoogleLogging(argv[0]); - google::LogToStderr(); - -#ifndef _WIN32 - opterr = 0; -#endif - int option; - while ((option = getopt(argc, argv, "vl:d:p:")) != -1) { - switch(option) { - case 'l': - google::InitGoogleLogging(optarg); - break; - case 'd': - uscxml::Factory::pluginPath = optarg; - break; - case 'p': - port = strTo<size_t>(optarg); - break; - case 'v': - verbose = true; - break; - case '?': - break; - default: - printUsageAndExit(); - break; - } - } - - (void)verbose; - // intialize http server on given port - HTTPServer::getInstance(port); - - LOG(INFO) << "Processing " << argv[optind]; - Interpreter protoInterpreter = Interpreter::fromURI(argv[optind]); - if (protoInterpreter) { - MMISessionManager mmiSessionManager(protoInterpreter); - while(true) - tthread::this_thread::sleep_for(tthread::chrono::milliseconds(1000)); - } - - return EXIT_SUCCESS; -}
\ No newline at end of file diff --git a/apps/w3c-mmi/mc/uscxml-modality-component.cpp b/apps/w3c-mmi/mc/uscxml-modality-component.cpp deleted file mode 100644 index 4901dbd..0000000 --- a/apps/w3c-mmi/mc/uscxml-modality-component.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "uscxml/config.h" -#include "uscxml/Interpreter.h" -#include <glog/logging.h> - -#ifdef HAS_SIGNAL_H -#include <signal.h> -#endif - -#ifdef HAS_EXECINFO_H -#include <execinfo.h> -#endif - -#ifdef HAS_DLFCN_H -#include <dlfcn.h> -#endif - -#ifdef _WIN32 -#include "XGetopt.h" -#endif - -class VerboseMonitor : public uscxml::InterpreterMonitor { - void onStableConfiguration(uscxml::Interpreter interpreter) { - printConfig(interpreter.getConfiguration()); - } - - void beforeCompletion(uscxml::Interpreter interpreter) { - printConfig(interpreter.getConfiguration()); - } - - void printConfig(const Arabica::XPath::NodeSet<std::string>& config) { - std::string seperator; - std::cout << "Config: {"; - for (int i = 0; i < config.size(); i++) { - std::cout << seperator << ATTR(config[i], "id"); - seperator = ", "; - } - std::cout << "}" << std::endl; - } -}; - - -#ifdef HAS_EXECINFO_H -void printBacktrace(void** array, int size) { - char** messages = backtrace_symbols(array, size); - for (int i = 0; i < size && messages != NULL; ++i) { - std::cerr << "\t" << messages[i] << std::endl; - } - std::cerr << std::endl; - free(messages); -} - -#ifdef HAS_DLFCN_H -// see https://gist.github.com/nkuln/2020860 -typedef void (*cxa_throw_type)(void *, void *, void (*) (void *)); -cxa_throw_type orig_cxa_throw = 0; - -void load_orig_throw_code() { - orig_cxa_throw = (cxa_throw_type) dlsym(RTLD_NEXT, "__cxa_throw"); -} - -extern "C" -CXA_THROW_SIGNATURE { - std::cerr << __FUNCTION__ << " will throw exception from " << std::endl; - if (orig_cxa_throw == 0) - load_orig_throw_code(); - - void *array[50]; - size_t size = backtrace(array, 50); - printBacktrace(array, size); - orig_cxa_throw(thrown_exception, pvtinfo, dest); -} -#endif -#endif - - -// see http://stackoverflow.com/questions/2443135/how-do-i-find-where-an-exception-was-thrown-in-c -void customTerminate() { - static bool tried_throw = false; - try { - // try once to re-throw currently active exception - if (!tried_throw) { - throw; - tried_throw = true; - } else { - tried_throw = false; - }; - } catch (const std::exception &e) { - std::cerr << __FUNCTION__ << " caught unhandled exception. what(): " - << e.what() << std::endl; - } catch (const uscxml::Event &e) { - std::cerr << __FUNCTION__ << " caught unhandled exception. Event: " - << e << std::endl; - } catch (...) { - std::cerr << __FUNCTION__ << " caught unknown/unhandled exception." - << std::endl; - } - -#ifdef HAS_EXECINFO_H - void * array[50]; - int size = backtrace(array, 50); - - printBacktrace(array, size); -#endif - abort(); -} - -void printUsageAndExit() { - printf("uscxml-browser version " USCXML_VERSION " (" CMAKE_BUILD_TYPE " build - " CMAKE_COMPILER_STRING ")\n"); - printf("Usage\n"); - printf("\tuscxml-browser"); -#ifdef BUILD_AS_PLUGINS - printf(" [-d pluginPath]"); -#endif - printf(" URL\n"); - printf("\n"); - printf("Options\n"); - printf("\t-v : be verbose\n"); - printf("\t-pN : port for HTTP server\n"); - printf("\n"); - exit(1); -} - -int main(int argc, char** argv) { - using namespace uscxml; - - std::set_terminate(customTerminate); - -#if defined(HAS_SIGNAL_H) && !defined(WIN32) - signal(SIGPIPE, SIG_IGN); -#endif - - if (argc < 2) { - printUsageAndExit(); - } - - bool verbose = false; - size_t port = 8080; - google::InitGoogleLogging(argv[0]); - google::LogToStderr(); - -#ifndef _WIN32 - opterr = 0; -#endif - int option; - while ((option = getopt(argc, argv, "vl:d:p:")) != -1) { - switch(option) { - case 'l': - google::InitGoogleLogging(optarg); - break; - case 'd': - uscxml::Factory::pluginPath = optarg; - break; - case 'p': - port = strTo<size_t>(optarg); - break; - case 'v': - verbose = true; - break; - case '?': - break; - default: - printUsageAndExit(); - break; - } - } - -// for (int i = 0; i < argc; i++) -// std::cout << argv[i] << std::endl; -// std::cout << optind << std::endl; - - // intialize http server on given port - HTTPServer::getInstance(port); - - LOG(INFO) << "Processing " << argv[optind]; - Interpreter interpreter = Interpreter::fromURI(argv[optind]); - if (interpreter) { -// interpreter.setCmdLineOptions(argc, argv); -// interpreter->setCapabilities(Interpreter::CAN_NOTHING); -// interpreter->setCapabilities(Interpreter::CAN_BASIC_HTTP | Interpreter::CAN_GENERIC_HTTP); - - if (verbose) { - VerboseMonitor* vm = new VerboseMonitor(); - interpreter.addMonitor(vm); - } - - interpreter.start(); - while(interpreter.runOnMainThread(25)); - } - - return EXIT_SUCCESS; -}
\ No newline at end of file |