Jean-Yves Didier

can now bundle things with webpack

......@@ -116,18 +116,18 @@ module.exports = function (grunt) {
concat: {
dist: {
src: [
'src/arcs.js',
'src/component.js',
'src/context.js',
'src/invocation.js',
'src/connection.js',
'src/arcs.js', *
'src/component.js', *
'src/context.js', *
'src/invocation.js', *
'src/connection.js', *
'src/sheet.js',
'src/eventlogicparser.js',
'src/tokenevent.js',
'src/transitionnetwork.js',
'src/statemachine.js',
'src/eventlogicparser.js', *
'src/tokenevent.js', *
'src/transitionnetwork.js', *
'src/statemachine.js', *
'src/application.js',
'src/exports.js'
'src/exports.js' *
],
dest: 'build/arcs.js'
},
......
// ARCS.js : 27/6/2014 16:00
// handling dependencies
//"use strict";
/**
* Main source: describes all the methods needed by the ARCS engine
* @file
*/
/**
* Defines all elements needed for Augmented Reality Component System
* @namespace
*/
var ARCS = ARCS || {};
/******************************************************************************
* Helper functions to determine environment
* ***************************************************************************/
/**
* @return {boolean} true if ARCS is run in a node.js environment
*/
ARCS.isInNode = function () {
return (typeof require === 'function' && require.resolve);
};
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ([
/* 0 */,
/* 1 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/******************************************************************************
* Component implementation
* ***************************************************************************/
......@@ -41,7 +19,7 @@ ARCS.isInNode = function () {
*
* @namespace
*/
ARCS.Component = {
var Component = {
/** Error message */
SourceIsNotComponent : {message : "Source is not a component"},
/** Error message */
......@@ -157,13 +135,13 @@ ARCS.Component = {
var orig, p;
// here we can perform various checks.
if (source.signals === undefined) {
throw ARCS.Component.SourceIsNotComponent;
throw Component.SourceIsNotComponent;
}
if (source.signals[signal] === undefined) {
throw ARCS.Component.UndefinedSignal;
throw Component.UndefinedSignal;
}
if (destination[slt] === undefined) {
throw ARCS.Component.UndefinedSlot;
throw Component.UndefinedSlot;
}
// we must also check if the signals dispose of their own implementation
if (!source.hasOwnProperty('signals')) {
......@@ -203,7 +181,7 @@ ARCS.Component = {
*/
invoke : function (destination, slt, value) {
if (destination[slt] === undefined) {
throw ARCS.Component.UndefinedSlot;
throw Component.UndefinedSlot;
}
......@@ -222,714 +200,304 @@ ARCS.Component = {
}
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ Component: Component});
/***/ }),
/* 2 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var _transitionnetwork_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
/* harmony import */ var _eventlogicparser_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
/******************************************************************************
* Statemachine implementation
* ***************************************************************************/
/**
* @class ARCS.Context
* @classdesc Class representing a context containing libraries and components
* used by different parts of the framework.
* @param ctx {object} an object representing data for the context.
* Describes a statemachine
* @param obj {object} an object describing a state machine. If obj is empty then the statemachine is empty
* @class
*/
ARCS.Context = function( ctx ) {
var components = {};
var constants = {};
var factories = {};
var libraries = [];
//var depLibPromises=[];
var self = this;
var loadLibraries;
var loadDataFile;
var promiseLibrary;
var instanciateComponents;
let Statemachine = new _component_js__WEBPACK_IMPORTED_MODULE_0__.default.create(function (obj) {
// dynamic construction: properties are initial state that have properties
// that are tokens and value that are the final state
var initial = "", final = "", transitions = {}, currentState = "", self= this;
var astTokens = {}; // it keeps AST from event logic expressions
var tokenEvents = {}; // it keeps promises for tokens.
var network = {};
factories.StateMachine = ARCS.Statemachine;
if (ctx !== undefined) {
libraries = ctx.libraries;
var p;
for (p in ctx.components) {
if (ctx.components.hasOwnProperty(p)) {
components[p] = ctx.components[p];
}
}
if (ctx.constants !== undefined) {
for (p in ctx.constants) {
if (ctx.constants.hasOwnProperty(p)) {
constants[p] = ctx.constants[p];
}
}
var addToken = function(t) {
if ( self.slots.indexOf(t) < 0 ) {
self.slots.push(t);
self[t] = function( s ) {
return function() {
self.setToken(s);
};
} (t);
}
}
var loadDataFile =async function(fileName) {
var dataPromise ;
};
/* this function aims at preparing transition networks for a given state*/
var setSheet = function(s) {
// we build promise trees using ast
var t;
if (ARCS.isInNode()) {
return new Promise(function (resolve, reject) {
var dep = require(fileName);
if (dep !== undefined) {
resolve(dep);
} else {
reject("[ARCS] File not found");
if (transitions.hasOwnProperty(s)) {
tokenEvents = {};
for (t in transitions[s]) {
if (transitions[s].hasOwnProperty(t)) {
network = _transitionnetwork_js__WEBPACK_IMPORTED_MODULE_1__.default.build(astTokens[t],tokenEvents).promise;
network.then(
function() {
var token;
// clean up remaining promises
for (token in tokenEvents) {
if (tokenEvents.hasOwnProperty(token)) tokenEvents[token].abort();
}
// then activate next sheet
setSheet(transitions[s][t]);
}
);
}
});
} else {
var client = await fetch(fileName);
return client.json();
}
}
};
var loadLibraries = function () {
var i;
// we will use different instances of require either the one of node
// or the one from require.js
ARCS.Context.currentContext = self;
var res=[];
for(i=0; i < libraries.length; i++) {
res.push(self.loadLibrary(libraries[i]));
currentState = s;
self.emit('requestSheet', currentState);
if (currentState === final) {
self.emit('requestTermination');
}
return Promise.all(res);
};
var instanciateComponents = function() {
var p, promises=[];
for (p in components) {
if (components.hasOwnProperty(p)) {
if (factories[components[p].type] === undefined) {
console.error("[ARCS] Factory " + components[p].type + " not found.");
console.error("[ARCS] Context dump follows: ", libraries, components, constants);
return ;
}
var factory = factories[components[p].type];
//console.log("instanciating ", p);
try {
if (components[p].value !== undefined || components[p].url !== undefined || components[p].ref !== undefined) {
if (components[p].value !== undefined) {
components[p].instance = new factory(components[p].value);
}
if (components[p].url !== undefined) {
// we need currying here !
var delayInstanciation = function(p,factory) {
return function(obj) {
console.log("instanciating from data file");
components[p].instance = new factory(obj);
return Promise.resolve();
}
};
console.log("loading data file", components[p].url);
promises.push(
loadDataFile(components[p].url).then(delayInstanciation(p,factory))
);
}
if (components[p].ref !== undefined) {
if (constants[components[p].ref] !== undefined) {
components[p].instance = new factory(constants[components[p].ref]);
}
}
} else {
components[p].instance = new factory();
}
} catch(e) { console.error("[ARCS] Component of type ", p, " not instanciated.", e);}
}
}
return Promise.all(promises);
};
/**
* loads a given library and, if necessary, launches a call back function
* when the library is loaded.
* @param libName {string} name of the library to load
* @param cbFunction {function} callback function to call when library is loaded
* Sets the initial state of the statemachine
* @param string {string} name of the initial state
*/
this.loadLibrary = function (libName, cbFunction) {
var libUrl = libName, libActualName = libName;
ARCS.Context.currentContext = self;
if (typeof libName !== "string") {
libActualName = libName.name;
libUrl = libName.url;
}
if (libraries.indexOf(libActualName) < 0) {
libraries.push(libActualName);
}
// TODO promisify call to cbFunction
return import(libUrl).then( function(module) {
// TODO insert here component factories
for (p in module.default) {
if (module.default.hasOwnProperty(p)) {
ARCS.Context.currentContext.setFactory(p,module.default[p]);
}
}
if (cbFunction !== undefined) {
cbFunction();
}
}).catch( function(msg) { console.error("[ARCS] Trouble loading '",libUrl,"' with reason -", msg) });
this.setInitialState = function (string) {
initial = string;
currentState = initial;
};
/**
* @return the component list stored inside context
*/
this.getComponentList = function () {
var list = Object.keys(components);
var i;
* Sets the final state of the statemachine
* @param string {string} name of the final state
*/
this.setFinalState = function (string) { final = string; };
/**
* Adds a transition to the state machine
* @param start {string} name of the state at the beginning of the transition
* @param token {string} name of the token triggering the transition
* @param end {string} name of the state reached at the end of the transition
*/
this.addTransition = function (start, token, end) {
var re = /([A-Za-z_]\w*)/g;
var t, tsd, ts, tsc;
try {
for (i = 0; i < list.length; i++) {
if ( ! components.hasOwnProperty(list[i])) {
list.splice(i--,1);
var tsd = ARCS.EventLogicParser.parse(token);
if (typeof tsd === "string") {
addToken(tsd);
} else {
while( (t = re.exec(token)) !== null) {
addToken(t[0]);
}
}
}
return list;
};
this.getConstant = function(cName) {
/*if (!constants.hasOwnProperty(cName)) {
return undefined;
}*/
return constants[cName];
};
// to determine if really needed
this.getComponentType = function(cName) {
/*if (!components.hasOwnProperty(cName))
return undefined;*/
if (components[cName] === undefined) return undefined;
return components[cName].type;
};
// to determine if really needed
this.getComponentValue = function(cName) {
/*if (!components.hasOwnProperty(cName))
return undefined;*/
if (components[cName] === undefined) return undefined;
return components[cName].value;
};
// to determine if really needed
this.getComponent = function (cName) {
/*if (!components.hasOwnProperty(cName))
return undefined;*/
if (components[cName] === undefined) return undefined;
return components[cName].instance;
};
// to determine if really needed
this.getComponentName = function (cmp) {
var i, keys;
keys = components.getComponentList();
for(i = 0; i < keys.length; i++) {
if (components[keys[i]].instance === cmp) {
return keys[i];
astTokens[token] = tsd;
if (transitions[start] === undefined) {
transitions[start] = {};
}
}
return undefined;
};
this.setFactory = function(key, factory ) {
factories[key] = factory;
transitions[start][token] = end;
} catch (e) { }
};
this.toJSON = function () {
var res = {}, p;
for (p in components) {
if (components.hasOwnProperty(p)) {
res[p] = { type: components[p].type, value: components[p].value };
}
/**
* Gives a token to the statemachine. According to its list of transitions
* and the current state, it may trigger a transition
* @param token {string} name of the token
*/
this.setToken = function (token) {
if (tokenEvents.hasOwnProperty(token)) {
tokenEvents[token].accept();
}
return res;
};
// functions used with editor
this.setComponentValue = function (cName, cValue) {
components[cName].value = cValue; // to modifiy
};
/**
* Sets transitions from a list of transitions
* @param obj {object[]} list of transitions
*/
this.setTransitions = function (obj) {
// this function is no longuer a simple affectation
// transitions = obj;
var p, t, i;
for (p in obj) {
if (obj.hasOwnProperty(p)) {
for (t in obj[p]) {
if (obj[p].hasOwnProperty(t)) {
this.addTransition(p, t, obj[p][t]);
}
}
}
}
this.addComponent = function (cName, cType, cValue) {
var component;
components[cName] = {};
components[cName].type = cType;
components[cName].value = cValue;
var factory = factories[cType];
if (factory !== undefined) {
component = new factory(cValue);
}
components[cName].instance = component;
// we will temporay dump properties in order to understand how the statemachine is built
/*
for (p in transitions) {
if (transitions.hasOwnProperty(p)) {
for (t in transitions[p]) {
if (transitions[p].hasOwnProperty(t)) {
console.log("\t" + p + "\t----\t" + t + "\t--->\t" + transitions[p][t]);
}
}
}
}*/
};
this.removeComponent = function (cName) {
delete components[cName];
/**
* Initialize and starts the statemachine, setting its current state to
* the initial state (by default, it is the departure of the first transition
*/
this.start = function () {
console.log("statemachine", this, initial,obj);
setSheet(initial);
};
// see if it is needed
this.getFactory = function (fName) {
return factories[fName];
};
// see if it is needed
this.getFactoryList = function() {
return Object.keys(factories);
};
// INIT CODE
if (obj !== undefined) {
initial = obj.initial;
final = obj.final;
this.setTransitions(obj.transitions);
currentState = "";
}
// this should return a promise !
this.instanciate = function () {
//! TODO
return loadLibraries().then(instanciateComponents)
.catch(function(msg) { console.error("[ARCS] Trouble instanciating context", msg); });
},
['setToken'],
['requestSheet', 'requestTermination']
);
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ StateMachine: StateMachine});
/***/ }),
/* 3 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _tokenevent_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
/* the aim of the transition network is to build a network of promises */
let TransitionNetwork = function() {
// object storing token events (that is to say references to promises)
this.promise = {};
this.and = function(tn) {
this.promise = Promise.all([this.promise, tn.promise]);
return this;
};
this.or = function(tn) {
this.promise = Promise.race([this.promise, tn.promise]);
return this;
};
};
TransitionNetwork.build = function(tree, tokenEvents) {
var res;
var tmpTN;
var rightTN;
if (typeof tree === "string") {
// here we have a terminal string i.e. a token event
var tokenEvent;
if (tokenEvents.hasOwnProperty(tree)) {
tokenEvent = tokenEvents[tree];
} else {
tokenEvents[tree] = tokenEvent = new _tokenevent_js__WEBPACK_IMPORTED_MODULE_0__.default();
}
var tn = new TransitionNetwork();
tn.promise = tokenEvent.promise;
return tn;
}
var chainPrototype = function (obj, proto) {
// this stunt seems better than using
// Object.setPrototypeOf or using [object].__proto__
// due to javascript engine optimizations
var newObj = Object.create(proto);
var p ;
for (p in obj) {
if (obj.hasOwnProperty(p)) {
newObj[p] = obj[p];
res = TransitionNetwork.build(tree[0],tokenEvents);
var i;
for (i=1; i < tree.length; i++) {
if (tree[i].hasOwnProperty('and')) {
rightTN = TransitionNetwork.build(tree[i]['and'], tokenEvents);
tmpTN = res.and(rightTN);
} else {
if (tree[i].hasOwnProperty('or')) {
rightTN = TransitionNetwork.build(tree[i]['or'], tokenEvents);
tmpTN = res.or(rightTN);
} else {
console.warn('[ARCS] Illegal tree');
}
}
return newObj;
};
this.chain = function (cmp,cst,fct) {
// cmp and cst are the children context elements
// we need to chain contexts properly.
return [ chainPrototype(cmp, components),
chainPrototype(cst, constants),
chainPrototype(fct, factories)
];
};
this.setParent = function (ctx) {
// chaining factories is also important if contexts are repeating
// the same things
if (ctx === undefined) return;
var v = ctx.chain(components, constants, factories);
components = v[0];
constants = v[1];
factories = v[2];
};
res = tmpTN;
}
return res;
};
/** pseudo-singleton to current context being used */
ARCS.Context.currentContext = null;
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({TransitionNetwork: TransitionNetwork});
/***/ }),
/* 4 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
// this class creates a promise that can be deferred as long as necessary.
// calls to accept or reject will solve the promise.
/******************************************************************************
* Invocation implementation
* ***************************************************************************/
/**
* Defines an invocation
* @param destination {object} component on which to perform invocation
* @param slot {string} name of the slot
* @param value {mixed} value passed to the invoked slot
* @constructor
*/
ARCS.Invocation = function (destination, slot, value) {
this.getDestination = function () {
return destination;
};
let TokenEvent = function() {
var refResolve;
var refReject;
this.getSlot = function () {
return slot;
};
this.promise = new Promise(function(resolve, reject) {
refResolve = resolve;
refReject = reject;
});
this.getValue = function () {
return value;
this.accept = function() {
refResolve();
};
this.invoke = function () {
var func = destination[slot];
if (func === undefined) {
console.error("Undefined slot %s of component %s", slot, destination);
return;
}
func.apply(destination, value);
};
};
/**
* Helper function that casts an invocation from a description
* @param obj {object} a raw description of the invocation
* @param context {object} the context in which this invocation takes place.
* @return an invocation
*/
ARCS.Invocation.cast = function (obj, context) {
if (obj.value !== undefined) {
var component = context.getComponent(obj.destination);
if (component === undefined) {
console.error("[ARCS] Destination ",obj.destination, " is undefined");
}
return new ARCS.Invocation(component, obj.slot, obj.value);
}
// this one looks odd, seems there is a failure in the logic.
if (obj.ref !== undefined) {
return new ARCS.Invocation(context.getComponent(obj.destination), obj.slot, context.getConstant(obj.ref));
}
};
/*ARCS.Invocation.revert = function(obj, context) {
return {
destination: context
};
};*/
ARCS.Invocation.PRE_CONNECTION = 0;
ARCS.Invocation.POST_CONNECTION = 1;
ARCS.Invocation.CLEAN_UP = 2;
/******************************************************************************
* Connection implementation
* ***************************************************************************/
/**
* Defines a connection between two components
* @param source {object} component at the source
* @param signal {string} name of the signal emitting data
* @param destination {object} component at the destination
* @param slot {string} name of the signal receiving data
* @class
*/
ARCS.Connection = function (source, signal, destination, slot) {
/**
* Connects two components as described in this object
* @function ARCS.Connection#connect
*/
this.connect = function () {
try {
ARCS.Component.connect(source, signal, destination, slot);
} catch(e) { console.log(e, source, signal, destination, slot); }
};
/**
* Disconnects a signal/slot connection between the two components
* described in this object.
*/
this.disconnect = function () {
ARCS.Component.disconnect(source, signal, destination, slot);
};
this.getSource = function() {
return source;
};
this.getDestination = function () {
return destination;
};
this.getSlot = function () {
return slot;
};
this.getSignal = function () {
return signal;
};
};
/**
* Helper function that casts a connection from a description
* @param obj {object} a raw description of the connection
* @param context {object} the context in which this connection takes place.
* @return a connection
*/
ARCS.Connection.cast = function (obj, context) {
return new ARCS.Connection(context.getComponent(obj.source)/*[obj.source].instance*/, obj.signal,
context.getComponent(obj.destination)/*[obj.destination].instance*/, obj.slot);
this.abort = function() {
refReject();
};
};
/******************************************************************************
* Sheet implementation
* ***************************************************************************/
/**
* Constructs a sheet
* @param context {object} a context object
* @class
* @classdesc A Sheet is an operationnal configuration in an application. It
* contains many things: multiple sets of {@link ARCS.Invocation}
* performed at different times
* and a set of {@link ARCS.Connection}. Sheets have two high level operations:
* activation and deactivation.
*/
ARCS.Sheet = function (ctx /*context*/) {
var context = new ARCS.Context();
var preconnections = [], postconnections = [], cleanups = [], connections = [],
invokePreconnections, invokePostconnections, invokeCleanups,
connect, disconnect, getComponentName,
preCount = 0, postCount = 0, cleanCount = 0, connCount = 0;
invokePreconnections = function () {
var i;
for (i = 0; i < preconnections.length; i++) {
preconnections[i].invoke();
}
};
invokePostconnections = function () {
var i;
for (i = 0; i < postconnections.length; i++) {
postconnections[i].invoke();
}
};
invokeCleanups = function () {
var i;
for (i = 0; i < cleanups.length; i++) {
cleanups[i].invoke();
}
};
connect = function () {
var i;
for (i = 0; i < connections.length; i++) {
connections[i].connect();
}
};
disconnect = function () {
var i;
for (i = 0; i < connections.length; i++) {
connections[i].disconnect();
}
};
this.setContext = function (ctx) {
context = ctx;
};
/**
* Activates this sheet. Pre-connection invocations are peformed, then
* connections are established and post-connection invocations are finally
* performed.
*/
this.activate = function () {
context.instanciate().then(function() {
invokePreconnections();
connect();
invokePostconnections();
});
};
/**
* Deactivates this sheet. Connections are removed and then cleanup invocations
* are performed.
*/
this.deactivate = function () {
disconnect();
invokeCleanups();
};
this.addPreConnection = function (obj) {
var pre = ARCS.Invocation.cast(obj, context);
pre.id = preCount++;
preconnections.push(pre);
return pre.id;
};
this.addPostConnection = function (obj) {
var post = ARCS.Invocation.cast(obj, context);
post.id = postCount++;
postconnections.push(post);
return post.id;
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({TokenEvent: TokenEvent});
this.addCleanup = function (obj) {
var cleanup = ARCS.Invocation.cast(obj, context);
cleanup.id = cleanCount++;
cleanups.push(cleanup);
return cleanup.id;
};
this.addConnection = function (obj) {
var connection = ARCS.Connection.cast(obj, context);
connection.id = connCount++;
connections.push(connection);
return connection.id;
};
var removeItem = function(id, tab) {
var i = tab.length;
while ( i-- && tab[i].id !== id );
if (i >= 0) {
tab.splice(i,1);
} else {
console.warn("Could not remove data with id", id);
}
};
this.removePreConnection = function (id) {
removeItem(id, preconnections);
};
this.removePostConnection = function (id) {
removeItem(id, postconnections);
};
this.removeCleanup = function (id) {
removeItem(id, cleanups);
};
var changeItem = function(id, value, tab) {
var i = tab.length;
while ( i-- && tab[i].id !== id );
if (i >= 0) {
tab[i].value = value;
}
};
this.changePreConnection = function (id, value) {
changeItem(id, value, preconnections);
};
this.changePostConnection = function (id, value) {
changeItem(id, value, postconnections);
};
this.changeCleanup = function (id, value) {
changeItem(id, value, cleanups);
};
this.removeConnection = function (id) {
removeItem(id, connections);
};
var swapItems = function (id1, id2, tab) {
var item;
var i = tab.length, j = tab.length;
while( i-- && tab[i].id !== id1 ) ;
while( j-- && tab[j].id !== id2 ) ;
if (i >= 0 && j >= 0) {
item = tab[i];
tab[i] = tab[j];
tab[j] = item;
tab[i].id = id1;
tab[j].id = id2;
}
};
this.swapConnections = function (id1, id2) {
swapItems(id1, id2, connections);
};
this.swapCleanups = function (id1, id2) {
swapItems(id1, id2, cleanups);
};
this.swapPreConnections = function (id1, id2) {
swapItems(id1, id2, preconnections);
};
this.swapPostConnections = function (id1, id2) {
swapItems(id1, id2, postconnections);
};
var cacheConnectionsInvocations = function(object) {
var i = 0, castInvocation = ARCS.Invocation.cast, castConnection = ARCS.Connection.cast;
for (i = 0; i < object.preconnections.length; i++) {
preconnections.push(castInvocation(object.preconnections[i], context));
}
for (i = 0; i < object.postconnections.length; i++) {
postconnections.push(castInvocation(object.postconnections[i], context));
}
for (i = 0; i < object.cleanups.length; i++) {
cleanups.push(castInvocation(object.cleanups[i], context));
}
for (i = 0; i < object.connections.length; i++) {
connections.push(castConnection(object.connections[i], context));
}
};
/**
* Imports a structure object describing the content of a sheet.
* @param object {object} structured object describing sheet's content.
*/
this.import = function (object) {
if (object.hasOwnProperty("context")) {
context = new ARCS.Context(object.context);
context.setParent(ctx);
}
// the caching system below should wait for the context to be proper initialized
// todo: there may be a flow here if the instanciation is too long.
context.instanciate().then( function() {
cacheConnectionsInvocations(object);
});
};
var revertInvocation = function (obj) {
return {
destination: context.getComponentName(obj.getDestination()),
slot: obj.getSlot(),
value: obj.getValue()
};
};
var revertConnection = function (obj) {
return {
source: context.getComponentName(obj.getSource()),
signal: obj.getSignal(),
destination: context.getComponentName(obj.getDestination()),
slot: obj.getSlot()
};
};
this.toJSON = function () {
var preconns = [];
var postconns = [];
var conns = [];
var cleans = [];
var i;
for (i = 0; i < connections.length; i++) {
conns.push(revertConnection(connections[i]))
}
for (i = 0; i < preconnections.length; i++) {
preconns.push(revertInvocation(preconnections[i]))
}
for (i = 0; i < postconnections.length; i++) {
postconns.push(revertInvocation(postconnections[i]))
}
for (i = 0; i < cleanups.length; i++) {
cleans.push(revertInvocation(cleanups[i]))
}
return {
preconnections : preconns,
postconnections : postconns,
connections: conns,
cleanups: cleans
};
};
//console.log("setting parent");
context.setParent(ctx);
};
/***/ }),
/* 5 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/****************************************************************************
* PEG.js grammar used to generate Parser
****************************************************************************
......@@ -968,7 +536,7 @@ WS = [ \r\n\t]*
******************************************************************************/
ARCS.EventLogicParser = (function() {
let EventLogicParser = (function() {
/*
* Generated by PEG.js 0.8.0.
*
......@@ -1593,253 +1161,836 @@ ARCS.EventLogicParser = (function() {
parse: parse
};
})();
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ EventLogicParser: EventLogicParser});
// this class creates a promise that can be deferred as long as necessary.
// calls to accept or reject will solve the promise.
ARCS.TokenEvent = function() {
var refResolve;
var refReject;
/***/ }),
/* 6 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ isInNode)
/* harmony export */ });
// ARCS.js : 27/6/2014 16:00
// handling dependencies
//"use strict";
/**
* Main source: describes all the methods needed by the ARCS engine
* @file
*/
/******************************************************************************
* Helper functions to determine environment
* ***************************************************************************/
/**
* @return {boolean} true if ARCS is run in a node.js environment
*/
function isInNode() {
return (typeof process !== 'undefined') &&
(process.release.name.search(/node|io.js/) !== -1);
this.promise = new Promise(function(resolve, reject) {
refResolve = resolve;
refReject = reject;
});
// return (typeof require === 'function' && require.resolve);
};
/***/ }),
/* 7 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _statemachine_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
/* harmony import */ var _arcs_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
/**
* @class ARCS.Context
* @classdesc Class representing a context containing libraries and components
* used by different parts of the framework.
* @param ctx {object} an object representing data for the context.
*/
let Context = function( ctx ) {
var components = {};
var constants = {};
var factories = {};
var libraries = [];
//var depLibPromises=[];
var self = this;
var loadLibraries;
var loadDataFile;
var promiseLibrary;
var instanciateComponents;
this.accept = function() {
refResolve();
factories.StateMachine = Statemachine;
if (ctx !== undefined) {
libraries = ctx.libraries;
var p;
for (p in ctx.components) {
if (ctx.components.hasOwnProperty(p)) {
components[p] = ctx.components[p];
}
}
if (ctx.constants !== undefined) {
for (p in ctx.constants) {
if (ctx.constants.hasOwnProperty(p)) {
constants[p] = ctx.constants[p];
}
}
}
}
var loadDataFile =async function(fileName) {
var dataPromise ;
if ((0,_arcs_js__WEBPACK_IMPORTED_MODULE_1__.default)()) {
return new Promise(function (resolve, reject) {
var dep = require(/* webpackIgnore: true */fileName);
if (dep !== undefined) {
resolve(dep);
} else {
reject("[ARCS] File not found");
}
});
} else {
var client = await fetch(fileName);
return client.json();
}
};
var loadLibraries = function () {
var i;
// we will use different instances of require either the one of node
// or the one from require.js
Context.currentContext = self;
var res=[];
for(i=0; i < libraries.length; i++) {
res.push(self.loadLibrary(libraries[i]));
}
return Promise.all(res);
};
var instanciateComponents = function() {
var p, promises=[];
for (p in components) {
if (components.hasOwnProperty(p)) {
if (factories[components[p].type] === undefined) {
console.error("[ARCS] Factory " + components[p].type + " not found.");
console.error("[ARCS] Context dump follows: ", libraries, components, constants);
return ;
}
var factory = factories[components[p].type];
//console.log("instanciating ", p);
try {
if (components[p].value !== undefined || components[p].url !== undefined || components[p].ref !== undefined) {
if (components[p].value !== undefined) {
components[p].instance = new factory(components[p].value);
}
if (components[p].url !== undefined) {
// we need currying here !
var delayInstanciation = function(p,factory) {
return function(obj) {
console.log("instanciating from data file");
components[p].instance = new factory(obj);
return Promise.resolve();
}
};
console.log("loading data file", components[p].url);
promises.push(
loadDataFile(components[p].url).then(delayInstanciation(p,factory))
);
}
if (components[p].ref !== undefined) {
if (constants[components[p].ref] !== undefined) {
components[p].instance = new factory(constants[components[p].ref]);
}
}
} else {
components[p].instance = new factory();
}
} catch(e) { console.error("[ARCS] Component of type ", p, " not instanciated.", e);}
}
}
return Promise.all(promises);
};
/**
* loads a given library and, if necessary, launches a call back function
* when the library is loaded.
* @param libName {string} name of the library to load
* @param cbFunction {function} callback function to call when library is loaded
*/
this.loadLibrary = function (libName, cbFunction) {
var libUrl = libName, libActualName = libName;
Context.currentContext = self;
if (typeof libName !== "string") {
libActualName = libName.name;
libUrl = libName.url;
}
if (libraries.indexOf(libActualName) < 0) {
libraries.push(libActualName);
}
// TODO promisify call to cbFunction
return import(/* webpackIgnore: true */libUrl).then( function(module) {
// TODO insert here component factories
for (p in module.default) {
if (module.default.hasOwnProperty(p)) {
Context.currentContext.setFactory(p,module.default[p]);
}
}
if (cbFunction !== undefined) {
cbFunction();
}
}).catch( function(msg) { console.error("[ARCS] Trouble loading '",libUrl,"' with reason -", msg) });
};
/**
* @return the component list stored inside context
*/
this.getComponentList = function () {
var list = Object.keys(components);
var i;
for (i = 0; i < list.length; i++) {
if ( ! components.hasOwnProperty(list[i])) {
list.splice(i--,1);
}
}
return list;
};
this.getConstant = function(cName) {
/*if (!constants.hasOwnProperty(cName)) {
return undefined;
}*/
return constants[cName];
};
// to determine if really needed
this.getComponentType = function(cName) {
/*if (!components.hasOwnProperty(cName))
return undefined;*/
if (components[cName] === undefined) return undefined;
return components[cName].type;
};
// to determine if really needed
this.getComponentValue = function(cName) {
/*if (!components.hasOwnProperty(cName))
return undefined;*/
if (components[cName] === undefined) return undefined;
return components[cName].value;
};
// to determine if really needed
this.getComponent = function (cName) {
/*if (!components.hasOwnProperty(cName))
return undefined;*/
if (components[cName] === undefined) return undefined;
return components[cName].instance;
};
// to determine if really needed
this.getComponentName = function (cmp) {
var i, keys;
keys = components.getComponentList();
for(i = 0; i < keys.length; i++) {
if (components[keys[i]].instance === cmp) {
return keys[i];
}
}
return undefined;
};
this.setFactory = function(key, factory ) {
factories[key] = factory;
};
this.toJSON = function () {
var res = {}, p;
for (p in components) {
if (components.hasOwnProperty(p)) {
res[p] = { type: components[p].type, value: components[p].value };
}
}
return res;
};
// functions used with editor
this.setComponentValue = function (cName, cValue) {
components[cName].value = cValue; // to modifiy
};
this.addComponent = function (cName, cType, cValue) {
var component;
components[cName] = {};
components[cName].type = cType;
components[cName].value = cValue;
var factory = factories[cType];
if (factory !== undefined) {
component = new factory(cValue);
}
components[cName].instance = component;
};
this.removeComponent = function (cName) {
delete components[cName];
};
// see if it is needed
this.getFactory = function (fName) {
return factories[fName];
};
// see if it is needed
this.getFactoryList = function() {
return Object.keys(factories);
};
// this should return a promise !
this.instanciate = function () {
//! TODO
return loadLibraries().then(instanciateComponents)
.catch(function(msg) { console.error("[ARCS] Trouble instanciating context", msg); });
};
var chainPrototype = function (obj, proto) {
// this stunt seems better than using
// Object.setPrototypeOf or using [object].__proto__
// due to javascript engine optimizations
var newObj = Object.create(proto);
var p ;
for (p in obj) {
if (obj.hasOwnProperty(p)) {
newObj[p] = obj[p];
}
}
return newObj;
};
this.chain = function (cmp,cst,fct) {
// cmp and cst are the children context elements
// we need to chain contexts properly.
return [ chainPrototype(cmp, components),
chainPrototype(cst, constants),
chainPrototype(fct, factories)
];
};
this.setParent = function (ctx) {
// chaining factories is also important if contexts are repeating
// the same things
if (ctx === undefined) return;
var v = ctx.chain(components, constants, factories);
components = v[0];
constants = v[1];
factories = v[2];
};
};
/** pseudo-singleton to current context being used */
Context.currentContext = null;
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({Context: Context});
/***/ }),
/* 8 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/******************************************************************************
* Invocation implementation
* ***************************************************************************/
/**
* Defines an invocation
* @param destination {object} component on which to perform invocation
* @param slot {string} name of the slot
* @param value {mixed} value passed to the invoked slot
* @constructor
*/
let Invocation = function (destination, slot, value) {
this.getDestination = function () {
return destination;
};
this.getSlot = function () {
return slot;
};
this.getValue = function () {
return value;
};
this.invoke = function () {
var func = destination[slot];
if (func === undefined) {
console.error("Undefined slot %s of component %s", slot, destination);
return;
}
func.apply(destination, value);
};
};
/**
* Helper function that casts an invocation from a description
* @param obj {object} a raw description of the invocation
* @param context {object} the context in which this invocation takes place.
* @return an invocation
*/
Invocation.cast = function (obj, context) {
if (obj.value !== undefined) {
var component = context.getComponent(obj.destination);
if (component === undefined) {
console.error("[ARCS] Destination ",obj.destination, " is undefined");
}
return new Invocation(component, obj.slot, obj.value);
}
this.abort = function() {
refReject();
};
// this one looks odd, seems there is a failure in the logic.
if (obj.ref !== undefined) {
return new Invocation(context.getComponent(obj.destination), obj.slot, context.getConstant(obj.ref));
}
};
/* the aim of the transition network is to build a network of promises */
ARCS.TransitionNetwork = function() {
// object storing token events (that is to say references to promises)
this.promise = {};
/*ARCS.Invocation.revert = function(obj, context) {
return {
destination: context
this.and = function(tn) {
this.promise = Promise.all([this.promise, tn.promise]);
return this;
};
this.or = function(tn) {
this.promise = Promise.race([this.promise, tn.promise]);
return this;
};
};*/
};
ARCS.TransitionNetwork.build = function(tree, tokenEvents) {
var res;
var tmpTN;
var rightTN;
Invocation.PRE_CONNECTION = 0;
Invocation.POST_CONNECTION = 1;
Invocation.CLEAN_UP = 2;
if (typeof tree === "string") {
// here we have a terminal string i.e. a token event
var tokenEvent;
if (tokenEvents.hasOwnProperty(tree)) {
tokenEvent = tokenEvents[tree];
} else {
tokenEvents[tree] = tokenEvent = new ARCS.TokenEvent();
}
var tn = new ARCS.TransitionNetwork();
tn.promise = tokenEvent.promise;
return tn;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ Invocation: Invocation});
/***/ }),
/* 9 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/******************************************************************************
* Connection implementation
* ***************************************************************************/
/**
* Defines a connection between two components
* @param source {object} component at the source
* @param signal {string} name of the signal emitting data
* @param destination {object} component at the destination
* @param slot {string} name of the signal receiving data
* @class
*/
let Connection = function (source, signal, destination, slot) {
/**
* Connects two components as described in this object
* @function ARCS.Connection#connect
*/
this.connect = function () {
try {
_component_js__WEBPACK_IMPORTED_MODULE_0__.default.connect(source, signal, destination, slot);
} catch(e) { console.log(e, source, signal, destination, slot); }
};
/**
* Disconnects a signal/slot connection between the two components
* described in this object.
*/
this.disconnect = function () {
_component_js__WEBPACK_IMPORTED_MODULE_0__.default.disconnect(source, signal, destination, slot);
};
res = ARCS.TransitionNetwork.build(tree[0],tokenEvents);
var i;
for (i=1; i < tree.length; i++) {
if (tree[i].hasOwnProperty('and')) {
rightTN = ARCS.TransitionNetwork.build(tree[i]['and'], tokenEvents);
tmpTN = res.and(rightTN);
} else {
if (tree[i].hasOwnProperty('or')) {
rightTN = ARCS.TransitionNetwork.build(tree[i]['or'], tokenEvents);
tmpTN = res.or(rightTN);
} else {
console.warn('[ARCS] Illegal tree');
}
}
res = tmpTN;
}
this.getSource = function() {
return source;
};
return res;
this.getDestination = function () {
return destination;
};
this.getSlot = function () {
return slot;
};
this.getSignal = function () {
return signal;
};
};
/**
* Helper function that casts a connection from a description
* @param obj {object} a raw description of the connection
* @param context {object} the context in which this connection takes place.
* @return a connection
*/
Connection.cast = function (obj, context) {
return new Connection(context.getComponent(obj.source)/*[obj.source].instance*/, obj.signal,
context.getComponent(obj.destination)/*[obj.destination].instance*/, obj.slot);
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ Connection: Connection});
/***/ }),
/* 10 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _context_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7);
/* harmony import */ var _invocation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
/* harmony import */ var _connection_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9);
/******************************************************************************
* Statemachine implementation
* Sheet implementation
* ***************************************************************************/
/**
* Describes a statemachine
* @param obj {object} an object describing a state machine. If obj is empty then the statemachine is empty
* Constructs a sheet
* @param context {object} a context object
* @class
* @classdesc A Sheet is an operationnal configuration in an application. It
* contains many things: multiple sets of {@link ARCS.Invocation}
* performed at different times
* and a set of {@link ARCS.Connection}. Sheets have two high level operations:
* activation and deactivation.
*/
ARCS.Statemachine = new ARCS.Component.create(function (obj) {
// dynamic construction: properties are initial state that have properties
// that are tokens and value that are the final state
var initial = "", final = "", transitions = {}, currentState = "", self= this;
var astTokens = {}; // it keeps AST from event logic expressions
var tokenEvents = {}; // it keeps promises for tokens.
var network = {};
let Sheet = function (ctx /*context*/) {
var context = new _context_js__WEBPACK_IMPORTED_MODULE_0__.default();
var preconnections = [], postconnections = [], cleanups = [], connections = [],
invokePreconnections, invokePostconnections, invokeCleanups,
connect, disconnect, getComponentName,
preCount = 0, postCount = 0, cleanCount = 0, connCount = 0;
invokePreconnections = function () {
var i;
for (i = 0; i < preconnections.length; i++) {
preconnections[i].invoke();
}
};
invokePostconnections = function () {
var i;
for (i = 0; i < postconnections.length; i++) {
postconnections[i].invoke();
}
};
invokeCleanups = function () {
var i;
for (i = 0; i < cleanups.length; i++) {
cleanups[i].invoke();
}
};
connect = function () {
var i;
for (i = 0; i < connections.length; i++) {
connections[i].connect();
}
};
disconnect = function () {
var i;
for (i = 0; i < connections.length; i++) {
connections[i].disconnect();
}
};
this.setContext = function (ctx) {
context = ctx;
};
/**
* Activates this sheet. Pre-connection invocations are peformed, then
* connections are established and post-connection invocations are finally
* performed.
*/
this.activate = function () {
context.instanciate().then(function() {
invokePreconnections();
connect();
invokePostconnections();
});
};
/**
* Deactivates this sheet. Connections are removed and then cleanup invocations
* are performed.
*/
this.deactivate = function () {
disconnect();
invokeCleanups();
};
this.addPreConnection = function (obj) {
var pre = _invocation_js__WEBPACK_IMPORTED_MODULE_1__.default.cast(obj, context);
pre.id = preCount++;
preconnections.push(pre);
return pre.id;
};
this.addPostConnection = function (obj) {
var post = _invocation_js__WEBPACK_IMPORTED_MODULE_1__.default.cast(obj, context);
post.id = postCount++;
postconnections.push(post);
return post.id;
};
var addToken = function(t) {
if ( self.slots.indexOf(t) < 0 ) {
self.slots.push(t);
self[t] = function( s ) {
return function() {
self.setToken(s);
};
} (t);
this.addCleanup = function (obj) {
var cleanup = _invocation_js__WEBPACK_IMPORTED_MODULE_1__.default.cast(obj, context);
cleanup.id = cleanCount++;
cleanups.push(cleanup);
return cleanup.id;
};
this.addConnection = function (obj) {
var connection = _connection_js__WEBPACK_IMPORTED_MODULE_2__.default.cast(obj, context);
connection.id = connCount++;
connections.push(connection);
return connection.id;
};
var removeItem = function(id, tab) {
var i = tab.length;
while ( i-- && tab[i].id !== id );
if (i >= 0) {
tab.splice(i,1);
} else {
console.warn("Could not remove data with id", id);
}
};
/* this function aims at preparing transition networks for a given state*/
var setSheet = function(s) {
// we build promise trees using ast
var t;
if (transitions.hasOwnProperty(s)) {
tokenEvents = {};
for (t in transitions[s]) {
if (transitions[s].hasOwnProperty(t)) {
network = ARCS.TransitionNetwork.build(astTokens[t],tokenEvents).promise;
network.then(
function() {
var token;
// clean up remaining promises
for (token in tokenEvents) {
if (tokenEvents.hasOwnProperty(token)) tokenEvents[token].abort();
}
// then activate next sheet
setSheet(transitions[s][t]);
}
);
}
}
this.removePreConnection = function (id) {
removeItem(id, preconnections);
};
this.removePostConnection = function (id) {
removeItem(id, postconnections);
};
this.removeCleanup = function (id) {
removeItem(id, cleanups);
};
var changeItem = function(id, value, tab) {
var i = tab.length;
while ( i-- && tab[i].id !== id );
if (i >= 0) {
tab[i].value = value;
}
};
this.changePreConnection = function (id, value) {
changeItem(id, value, preconnections);
};
this.changePostConnection = function (id, value) {
changeItem(id, value, postconnections);
};
this.changeCleanup = function (id, value) {
changeItem(id, value, cleanups);
};
this.removeConnection = function (id) {
removeItem(id, connections);
};
var swapItems = function (id1, id2, tab) {
var item;
currentState = s;
self.emit('requestSheet', currentState);
if (currentState === final) {
self.emit('requestTermination');
}
var i = tab.length, j = tab.length;
while( i-- && tab[i].id !== id1 ) ;
while( j-- && tab[j].id !== id2 ) ;
if (i >= 0 && j >= 0) {
item = tab[i];
tab[i] = tab[j];
tab[j] = item;
tab[i].id = id1;
tab[j].id = id2;
}
};
/**
* Sets the initial state of the statemachine
* @param string {string} name of the initial state
*/
this.setInitialState = function (string) {
initial = string;
currentState = initial;
this.swapConnections = function (id1, id2) {
swapItems(id1, id2, connections);
};
/**
* Sets the final state of the statemachine
* @param string {string} name of the final state
*/
this.setFinalState = function (string) { final = string; };
/**
* Adds a transition to the state machine
* @param start {string} name of the state at the beginning of the transition
* @param token {string} name of the token triggering the transition
* @param end {string} name of the state reached at the end of the transition
*/
this.addTransition = function (start, token, end) {
var re = /([A-Za-z_]\w*)/g;
var t, tsd, ts, tsc;
try {
var tsd = ARCS.EventLogicParser.parse(token);
if (typeof tsd === "string") {
addToken(tsd);
} else {
while( (t = re.exec(token)) !== null) {
addToken(t[0]);
}
}
astTokens[token] = tsd;
if (transitions[start] === undefined) {
transitions[start] = {};
}
transitions[start][token] = end;
} catch (e) { }
this.swapCleanups = function (id1, id2) {
swapItems(id1, id2, cleanups);
};
/**
* Gives a token to the statemachine. According to its list of transitions
* and the current state, it may trigger a transition
* @param token {string} name of the token
*/
this.setToken = function (token) {
if (tokenEvents.hasOwnProperty(token)) {
tokenEvents[token].accept();
this.swapPreConnections = function (id1, id2) {
swapItems(id1, id2, preconnections);
};
this.swapPostConnections = function (id1, id2) {
swapItems(id1, id2, postconnections);
};
var cacheConnectionsInvocations = function(object) {
var i = 0, castInvocation = _invocation_js__WEBPACK_IMPORTED_MODULE_1__.default.cast, castConnection = _connection_js__WEBPACK_IMPORTED_MODULE_2__.default.cast;
for (i = 0; i < object.preconnections.length; i++) {
preconnections.push(castInvocation(object.preconnections[i], context));
}
for (i = 0; i < object.postconnections.length; i++) {
postconnections.push(castInvocation(object.postconnections[i], context));
}
for (i = 0; i < object.cleanups.length; i++) {
cleanups.push(castInvocation(object.cleanups[i], context));
}
for (i = 0; i < object.connections.length; i++) {
connections.push(castConnection(object.connections[i], context));
}
};
/**
* Sets transitions from a list of transitions
* @param obj {object[]} list of transitions
* Imports a structure object describing the content of a sheet.
* @param object {object} structured object describing sheet's content.
*/
this.setTransitions = function (obj) {
// this function is no longuer a simple affectation
// transitions = obj;
var p, t, i;
for (p in obj) {
if (obj.hasOwnProperty(p)) {
for (t in obj[p]) {
if (obj[p].hasOwnProperty(t)) {
this.addTransition(p, t, obj[p][t]);
}
}
}
this.import = function (object) {
if (object.hasOwnProperty("context")) {
context = new _context_js__WEBPACK_IMPORTED_MODULE_0__.default(object.context);
context.setParent(ctx);
}
// we will temporay dump properties in order to understand how the statemachine is built
/*
for (p in transitions) {
if (transitions.hasOwnProperty(p)) {
for (t in transitions[p]) {
if (transitions[p].hasOwnProperty(t)) {
console.log("\t" + p + "\t----\t" + t + "\t--->\t" + transitions[p][t]);
}
}
}
}*/
// the caching system below should wait for the context to be proper initialized
// todo: there may be a flow here if the instanciation is too long.
context.instanciate().then( function() {
cacheConnectionsInvocations(object);
});
};
/**
* Initialize and starts the statemachine, setting its current state to
* the initial state (by default, it is the departure of the first transition
*/
this.start = function () {
console.log("statemachine", this, initial,obj);
setSheet(initial);
var revertInvocation = function (obj) {
return {
destination: context.getComponentName(obj.getDestination()),
slot: obj.getSlot(),
value: obj.getValue()
};
};
var revertConnection = function (obj) {
return {
source: context.getComponentName(obj.getSource()),
signal: obj.getSignal(),
destination: context.getComponentName(obj.getDestination()),
slot: obj.getSlot()
};
};
this.toJSON = function () {
var preconns = [];
var postconns = [];
var conns = [];
var cleans = [];
var i;
for (i = 0; i < connections.length; i++) {
conns.push(revertConnection(connections[i]))
}
for (i = 0; i < preconnections.length; i++) {
preconns.push(revertInvocation(preconnections[i]))
}
for (i = 0; i < postconnections.length; i++) {
postconns.push(revertInvocation(postconnections[i]))
}
for (i = 0; i < cleanups.length; i++) {
cleans.push(revertInvocation(cleanups[i]))
}
return {
preconnections : preconns,
postconnections : postconns,
connections: conns,
cleanups: cleans
};
};
//console.log("setting parent");
context.setParent(ctx);
};
// INIT CODE
if (obj !== undefined) {
initial = obj.initial;
final = obj.final;
this.setTransitions(obj.transitions);
currentState = "";
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({Sheet: Sheet});
},
['setToken'],
['requestSheet', 'requestTermination']
);
/***/ }),
/* 11 */
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _context_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7);
/* harmony import */ var _sheet_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
/* harmony import */ var _component_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1);
/******************************************************************************
* Application implementation
* ***************************************************************************/
/**
* Creates an application runnable by the ARCS engine.
* @class ARCS.Application
......@@ -1849,8 +2000,8 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
* to load all external scripts describing components, instanciate
* all components and then start the application
*/
ARCS.Application = function () {
var context = new ARCS.Context(),
let Application = function () {
var context = new _context_js__WEBPACK_IMPORTED_MODULE_0__.default(),
sheets = {},
controller = {},
dependencies = [],
......@@ -1906,13 +2057,13 @@ ARCS.Application = function () {
// then we should work on sheets
sheetList = Object.keys(sheets);
for (i = 0; i < sheetList.length; i++) {
temp = new ARCS.Sheet(context);
temp = new _sheet_js__WEBPACK_IMPORTED_MODULE_1__.default(context);
temp.import(sheets[sheetList[i]], context);
sheets[sheetList[i]] = temp;
}
ARCS.Component.connect(controller, "requestSheet", self, "setSheet");
ARCS.Component.connect(controller, "requestTermination", self, "finish");
_component_js__WEBPACK_IMPORTED_MODULE_2__.default.connect(controller, "requestSheet", self, "setSheet");
_component_js__WEBPACK_IMPORTED_MODULE_2__.default.connect(controller, "requestTermination", self, "finish");
controller.start();
};
......@@ -2011,7 +2162,7 @@ ARCS.Application = function () {
*
*/
this.import = function (object) {
context = new ARCS.Context(object.context/*.components*/);
context = new _context_js__WEBPACK_IMPORTED_MODULE_0__.default(object.context/*.components*/);
sheets = object.sheets;
controller = object.controller;
if (controller === undefined) {
......@@ -2042,17 +2193,114 @@ ARCS.Application = function () {
};
};
ARCS.Application.setDependency = function (app, key) {
Application.setDependency = function (app, key) {
app.setDependency(key);
};
ARCS.Component.create(ARCS.Application);
ARCS.Application.slot("setSheet");
ARCS.Application.slot("finish");
_component_js__WEBPACK_IMPORTED_MODULE_2__.default.create(Application);
Application.slot("setSheet");
Application.slot("finish");
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({Application: Application});
/***/ })
/******/ ]);
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _component_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var _statemachine_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
/* harmony import */ var _arcs_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6);
/* harmony import */ var _context_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7);
/* harmony import */ var _invocation_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8);
/* harmony import */ var _connection_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9);
/* harmony import */ var _sheet_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(10);
/* harmony import */ var _application_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(11);
// no longer needed with the use of imports
// no longer needed with the use of imports
export { ARCS as default};
\ No newline at end of file
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
Component: _component_js__WEBPACK_IMPORTED_MODULE_0__.default,
isInNode : _arcs_js__WEBPACK_IMPORTED_MODULE_2__.default,
StateMachine: _statemachine_js__WEBPACK_IMPORTED_MODULE_1__.default,
Context: _context_js__WEBPACK_IMPORTED_MODULE_3__.default,
Invocation: _invocation_js__WEBPACK_IMPORTED_MODULE_4__.default,
Connection: _connection_js__WEBPACK_IMPORTED_MODULE_5__.default,
Sheet: _sheet_js__WEBPACK_IMPORTED_MODULE_6__.default,
Application: _application_js__WEBPACK_IMPORTED_MODULE_7__.default
});
})();
/******/ })()
;
\ No newline at end of file
......
......@@ -12,6 +12,12 @@
],
"author": "Jean-Yves Didier",
"license": "GPL-3.0-or-later",
"dependencies": {
"tracking": ">=1.1.3",
"three": ">=0.131",
"js-aruco": ">=0.1",
"codemirror": ">=5.62"
},
"devDependencies": {
"bower": ">=1.3.9",
"grunt": ">=0.4.5",
......
/******************************************************************************
* Application implementation
* ***************************************************************************/
import Context from './context.js';
import Sheet from './sheet.js';
import Component from './component.js';
/**
* Creates an application runnable by the ARCS engine.
......@@ -11,8 +14,8 @@
* to load all external scripts describing components, instanciate
* all components and then start the application
*/
ARCS.Application = function () {
var context = new ARCS.Context(),
let Application = function () {
var context = new Context(),
sheets = {},
controller = {},
dependencies = [],
......@@ -68,13 +71,13 @@ ARCS.Application = function () {
// then we should work on sheets
sheetList = Object.keys(sheets);
for (i = 0; i < sheetList.length; i++) {
temp = new ARCS.Sheet(context);
temp = new Sheet(context);
temp.import(sheets[sheetList[i]], context);
sheets[sheetList[i]] = temp;
}
ARCS.Component.connect(controller, "requestSheet", self, "setSheet");
ARCS.Component.connect(controller, "requestTermination", self, "finish");
Component.connect(controller, "requestSheet", self, "setSheet");
Component.connect(controller, "requestTermination", self, "finish");
controller.start();
};
......@@ -173,7 +176,7 @@ ARCS.Application = function () {
*
*/
this.import = function (object) {
context = new ARCS.Context(object.context/*.components*/);
context = new Context(object.context/*.components*/);
sheets = object.sheets;
controller = object.controller;
if (controller === undefined) {
......@@ -204,13 +207,14 @@ ARCS.Application = function () {
};
};
ARCS.Application.setDependency = function (app, key) {
Application.setDependency = function (app, key) {
app.setDependency(key);
};
ARCS.Component.create(ARCS.Application);
ARCS.Application.slot("setSheet");
ARCS.Application.slot("finish");
Component.create(Application);
Application.slot("setSheet");
Application.slot("finish");
export default {Application: Application};
......
......@@ -5,18 +5,13 @@
//"use strict";
/**
* Main source: describes all the methods needed by the ARCS engine
* @file
*/
/**
* Defines all elements needed for Augmented Reality Component System
* @namespace
*/
var ARCS = ARCS || {};
/******************************************************************************
* Helper functions to determine environment
......@@ -24,9 +19,12 @@ var ARCS = ARCS || {};
/**
* @return {boolean} true if ARCS is run in a node.js environment
*/
ARCS.isInNode = function () {
return (typeof require === 'function' && require.resolve);
};
*/
export default function isInNode() {
return (typeof process !== 'undefined') &&
(process.release.name.search(/node|io.js/) !== -1);
// return (typeof require === 'function' && require.resolve);
};
......
......@@ -8,7 +8,7 @@
*
* @namespace
*/
ARCS.Component = {
var Component = {
/** Error message */
SourceIsNotComponent : {message : "Source is not a component"},
/** Error message */
......@@ -124,13 +124,13 @@ ARCS.Component = {
var orig, p;
// here we can perform various checks.
if (source.signals === undefined) {
throw ARCS.Component.SourceIsNotComponent;
throw Component.SourceIsNotComponent;
}
if (source.signals[signal] === undefined) {
throw ARCS.Component.UndefinedSignal;
throw Component.UndefinedSignal;
}
if (destination[slt] === undefined) {
throw ARCS.Component.UndefinedSlot;
throw Component.UndefinedSlot;
}
// we must also check if the signals dispose of their own implementation
if (!source.hasOwnProperty('signals')) {
......@@ -170,7 +170,7 @@ ARCS.Component = {
*/
invoke : function (destination, slt, value) {
if (destination[slt] === undefined) {
throw ARCS.Component.UndefinedSlot;
throw Component.UndefinedSlot;
}
......@@ -188,3 +188,5 @@ ARCS.Component = {
}
}
};
export default { Component: Component};
......
/******************************************************************************
* Connection implementation
* ***************************************************************************/
import Component from './component.js';
/**
* Defines a connection between two components
* @param source {object} component at the source
......@@ -9,14 +11,14 @@
* @param slot {string} name of the signal receiving data
* @class
*/
ARCS.Connection = function (source, signal, destination, slot) {
let Connection = function (source, signal, destination, slot) {
/**
* Connects two components as described in this object
* @function ARCS.Connection#connect
*/
this.connect = function () {
try {
ARCS.Component.connect(source, signal, destination, slot);
Component.connect(source, signal, destination, slot);
} catch(e) { console.log(e, source, signal, destination, slot); }
};
/**
......@@ -24,7 +26,7 @@ ARCS.Connection = function (source, signal, destination, slot) {
* described in this object.
*/
this.disconnect = function () {
ARCS.Component.disconnect(source, signal, destination, slot);
Component.disconnect(source, signal, destination, slot);
};
this.getSource = function() {
......@@ -49,7 +51,10 @@ ARCS.Connection = function (source, signal, destination, slot) {
* @param context {object} the context in which this connection takes place.
* @return a connection
*/
ARCS.Connection.cast = function (obj, context) {
return new ARCS.Connection(context.getComponent(obj.source)/*[obj.source].instance*/, obj.signal,
Connection.cast = function (obj, context) {
return new Connection(context.getComponent(obj.source)/*[obj.source].instance*/, obj.signal,
context.getComponent(obj.destination)/*[obj.destination].instance*/, obj.slot);
};
export default { Connection: Connection};
......
import StateMachine from './statemachine.js';
import isInNode from './arcs.js';
/**
* @class ARCS.Context
* @classdesc Class representing a context containing libraries and components
* used by different parts of the framework.
* @param ctx {object} an object representing data for the context.
*/
ARCS.Context = function( ctx ) {
let Context = function( ctx ) {
var components = {};
var constants = {};
var factories = {};
......@@ -17,7 +20,7 @@ ARCS.Context = function( ctx ) {
var instanciateComponents;
factories.StateMachine = ARCS.Statemachine;
factories.StateMachine = Statemachine;
if (ctx !== undefined) {
......@@ -43,9 +46,9 @@ ARCS.Context = function( ctx ) {
var loadDataFile =async function(fileName) {
var dataPromise ;
if (ARCS.isInNode()) {
if (isInNode()) {
return new Promise(function (resolve, reject) {
var dep = require(fileName);
var dep = require(/* webpackIgnore: true */fileName);
if (dep !== undefined) {
resolve(dep);
} else {
......@@ -62,7 +65,7 @@ ARCS.Context = function( ctx ) {
var i;
// we will use different instances of require either the one of node
// or the one from require.js
ARCS.Context.currentContext = self;
Context.currentContext = self;
var res=[];
for(i=0; i < libraries.length; i++) {
......@@ -125,7 +128,7 @@ ARCS.Context = function( ctx ) {
this.loadLibrary = function (libName, cbFunction) {
var libUrl = libName, libActualName = libName;
ARCS.Context.currentContext = self;
Context.currentContext = self;
if (typeof libName !== "string") {
libActualName = libName.name;
libUrl = libName.url;
......@@ -135,11 +138,11 @@ ARCS.Context = function( ctx ) {
libraries.push(libActualName);
}
// TODO promisify call to cbFunction
return import(libUrl).then( function(module) {
return import(/* webpackIgnore: true */libUrl).then( function(module) {
// TODO insert here component factories
for (p in module.default) {
if (module.default.hasOwnProperty(p)) {
ARCS.Context.currentContext.setFactory(p,module.default[p]);
Context.currentContext.setFactory(p,module.default[p]);
}
}
......@@ -309,7 +312,7 @@ ARCS.Context = function( ctx ) {
/** pseudo-singleton to current context being used */
ARCS.Context.currentContext = null;
Context.currentContext = null;
export default {Context: Context};
......
......@@ -36,7 +36,7 @@ WS = [ \r\n\t]*
******************************************************************************/
ARCS.EventLogicParser = (function() {
let EventLogicParser = (function() {
/*
* Generated by PEG.js 0.8.0.
*
......@@ -661,3 +661,5 @@ ARCS.EventLogicParser = (function() {
parse: parse
};
})();
export default { EventLogicParser: EventLogicParser};
......
// no longer needed with the use of imports
export { ARCS as default};
\ No newline at end of file
import Component from './component.js';
import StateMachine from './statemachine.js';
import isInNode from './arcs.js';
import Context from './context.js';
import Invocation from './invocation.js';
import Connection from './connection.js';
import Sheet from './sheet.js';
import Application from './application.js';
export default {
Component: Component,
isInNode : isInNode,
StateMachine: StateMachine,
Context: Context,
Invocation: Invocation,
Connection: Connection,
Sheet: Sheet,
Application: Application
};
......
......@@ -8,7 +8,8 @@
* @param value {mixed} value passed to the invoked slot
* @constructor
*/
ARCS.Invocation = function (destination, slot, value) {
let Invocation = function (destination, slot, value) {
this.getDestination = function () {
return destination;
};
......@@ -36,19 +37,19 @@ ARCS.Invocation = function (destination, slot, value) {
* @param context {object} the context in which this invocation takes place.
* @return an invocation
*/
ARCS.Invocation.cast = function (obj, context) {
Invocation.cast = function (obj, context) {
if (obj.value !== undefined) {
var component = context.getComponent(obj.destination);
if (component === undefined) {
console.error("[ARCS] Destination ",obj.destination, " is undefined");
}
return new ARCS.Invocation(component, obj.slot, obj.value);
return new Invocation(component, obj.slot, obj.value);
}
// this one looks odd, seems there is a failure in the logic.
if (obj.ref !== undefined) {
return new ARCS.Invocation(context.getComponent(obj.destination), obj.slot, context.getConstant(obj.ref));
return new Invocation(context.getComponent(obj.destination), obj.slot, context.getConstant(obj.ref));
}
};
......@@ -61,6 +62,8 @@ ARCS.Invocation.cast = function (obj, context) {
};*/
ARCS.Invocation.PRE_CONNECTION = 0;
ARCS.Invocation.POST_CONNECTION = 1;
ARCS.Invocation.CLEAN_UP = 2;
\ No newline at end of file
Invocation.PRE_CONNECTION = 0;
Invocation.POST_CONNECTION = 1;
Invocation.CLEAN_UP = 2;
export default { Invocation: Invocation};
......
/******************************************************************************
* Sheet implementation
* ***************************************************************************/
import Context from './context.js';
import Invocation from './invocation.js';
import Connection from './connection.js';
/**
* Constructs a sheet
* @param context {object} a context object
......@@ -11,8 +15,8 @@
* and a set of {@link ARCS.Connection}. Sheets have two high level operations:
* activation and deactivation.
*/
ARCS.Sheet = function (ctx /*context*/) {
var context = new ARCS.Context();
let Sheet = function (ctx /*context*/) {
var context = new Context();
var preconnections = [], postconnections = [], cleanups = [], connections = [],
invokePreconnections, invokePostconnections, invokeCleanups,
connect, disconnect, getComponentName,
......@@ -74,14 +78,14 @@ ARCS.Sheet = function (ctx /*context*/) {
};
this.addPreConnection = function (obj) {
var pre = ARCS.Invocation.cast(obj, context);
var pre = Invocation.cast(obj, context);
pre.id = preCount++;
preconnections.push(pre);
return pre.id;
};
this.addPostConnection = function (obj) {
var post = ARCS.Invocation.cast(obj, context);
var post = Invocation.cast(obj, context);
post.id = postCount++;
postconnections.push(post);
return post.id;
......@@ -89,14 +93,14 @@ ARCS.Sheet = function (ctx /*context*/) {
this.addCleanup = function (obj) {
var cleanup = ARCS.Invocation.cast(obj, context);
var cleanup = Invocation.cast(obj, context);
cleanup.id = cleanCount++;
cleanups.push(cleanup);
return cleanup.id;
};
this.addConnection = function (obj) {
var connection = ARCS.Connection.cast(obj, context);
var connection = Connection.cast(obj, context);
connection.id = connCount++;
connections.push(connection);
return connection.id;
......@@ -187,7 +191,7 @@ ARCS.Sheet = function (ctx /*context*/) {
var cacheConnectionsInvocations = function(object) {
var i = 0, castInvocation = ARCS.Invocation.cast, castConnection = ARCS.Connection.cast;
var i = 0, castInvocation = Invocation.cast, castConnection = Connection.cast;
for (i = 0; i < object.preconnections.length; i++) {
preconnections.push(castInvocation(object.preconnections[i], context));
}
......@@ -208,7 +212,7 @@ ARCS.Sheet = function (ctx /*context*/) {
*/
this.import = function (object) {
if (object.hasOwnProperty("context")) {
context = new ARCS.Context(object.context);
context = new Context(object.context);
context.setParent(ctx);
}
......@@ -267,3 +271,5 @@ ARCS.Sheet = function (ctx /*context*/) {
//console.log("setting parent");
context.setParent(ctx);
};
export default {Sheet: Sheet};
......
/******************************************************************************
* Statemachine implementation
* ***************************************************************************/
import Component from './component.js';
import TransitionNetwork from './transitionnetwork.js';
import EventLogicParser from './eventlogicparser.js';
/**
* Describes a statemachine
* @param obj {object} an object describing a state machine. If obj is empty then the statemachine is empty
* @class
*/
ARCS.Statemachine = new ARCS.Component.create(function (obj) {
let Statemachine = new Component.create(function (obj) {
// dynamic construction: properties are initial state that have properties
// that are tokens and value that are the final state
var initial = "", final = "", transitions = {}, currentState = "", self= this;
......@@ -35,7 +40,7 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
tokenEvents = {};
for (t in transitions[s]) {
if (transitions[s].hasOwnProperty(t)) {
network = ARCS.TransitionNetwork.build(astTokens[t],tokenEvents).promise;
network = TransitionNetwork.build(astTokens[t],tokenEvents).promise;
network.then(
function() {
var token;
......@@ -164,3 +169,4 @@ ARCS.Statemachine = new ARCS.Component.create(function (obj) {
['requestSheet', 'requestTermination']
);
export default { StateMachine: StateMachine};
......
// this class creates a promise that can be deferred as long as necessary.
// calls to accept or reject will solve the promise.
ARCS.TokenEvent = function() {
let TokenEvent = function() {
var refResolve;
var refReject;
......@@ -17,4 +17,6 @@ ARCS.TokenEvent = function() {
this.abort = function() {
refReject();
};
};
\ No newline at end of file
};
export default {TokenEvent: TokenEvent};
......
/* the aim of the transition network is to build a network of promises */
import TokenEvent from './tokenevent.js';
ARCS.TransitionNetwork = function() {
let TransitionNetwork = function() {
// object storing token events (that is to say references to promises)
this.promise = {};
......@@ -16,7 +18,7 @@ ARCS.TransitionNetwork = function() {
};
ARCS.TransitionNetwork.build = function(tree, tokenEvents) {
TransitionNetwork.build = function(tree, tokenEvents) {
var res;
var tmpTN;
var rightTN;
......@@ -27,22 +29,22 @@ ARCS.TransitionNetwork.build = function(tree, tokenEvents) {
if (tokenEvents.hasOwnProperty(tree)) {
tokenEvent = tokenEvents[tree];
} else {
tokenEvents[tree] = tokenEvent = new ARCS.TokenEvent();
tokenEvents[tree] = tokenEvent = new TokenEvent();
}
var tn = new ARCS.TransitionNetwork();
var tn = new TransitionNetwork();
tn.promise = tokenEvent.promise;
return tn;
}
res = ARCS.TransitionNetwork.build(tree[0],tokenEvents);
res = TransitionNetwork.build(tree[0],tokenEvents);
var i;
for (i=1; i < tree.length; i++) {
if (tree[i].hasOwnProperty('and')) {
rightTN = ARCS.TransitionNetwork.build(tree[i]['and'], tokenEvents);
rightTN = TransitionNetwork.build(tree[i]['and'], tokenEvents);
tmpTN = res.and(rightTN);
} else {
if (tree[i].hasOwnProperty('or')) {
rightTN = ARCS.TransitionNetwork.build(tree[i]['or'], tokenEvents);
rightTN = TransitionNetwork.build(tree[i]['or'], tokenEvents);
tmpTN = res.or(rightTN);
} else {
console.warn('[ARCS] Illegal tree');
......@@ -52,4 +54,6 @@ ARCS.TransitionNetwork.build = function(tree, tokenEvents) {
}
return res;
};
\ No newline at end of file
};
export default {TransitionNetwork: TransitionNetwork};
......
const path = require('path');
module.exports = {
entry: './src/exports.js',
mode: 'none',
output: {
filename: 'arcs.js',
path: path.resolve(__dirname, 'build'),
},
module: {
parser: {
javascript: {
commonjsMagicComments: true
}
}
}
};