Toggle navigation
Toggle navigation
This project
Loading...
Sign in
arcs
/
arcs.js
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
3
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Jean-Yves Didier
2021-08-23 23:52:09 +0200
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
00351ab9f0d43cd796ad35c982706a49c4ff7809
00351ab9
1 parent
cf5e737f
can now bundle things with webpack
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1307 additions
and
983 deletions
Gruntfile.js
build/arcs.js
package.json
src/application.js
src/arcs.js
src/component.js
src/connection.js
src/context.js
src/eventlogicparser.js
src/exports.js
src/invocation.js
src/sheet.js
src/statemachine.js
src/tokenevent.js
src/transitionnetwork.js
webpack.config.js
Gruntfile.js
View file @
00351ab
...
...
@@ -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'
},
...
...
build/arcs.js
View file @
00351ab
// 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
()
{
re
turn
value
;
this
.
accept
=
function
()
{
re
fResolve
()
;
};
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
);
/******************************************************************************
* S
tatemachine
implementation
* S
heet
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 obj
ect {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
.
Contex
t
(),
let
Application
=
function
()
{
var
context
=
new
_context_js__WEBPACK_IMPORTED_MODULE_0__
.
defaul
t
(),
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
.
Shee
t
(
context
);
temp
=
new
_sheet_js__WEBPACK_IMPORTED_MODULE_1__
.
defaul
t
(
context
);
temp
.
import
(
sheets
[
sheetList
[
i
]],
context
);
sheets
[
sheetList
[
i
]]
=
temp
;
}
ARCS
.
Componen
t
.
connect
(
controller
,
"requestSheet"
,
self
,
"setSheet"
);
ARCS
.
Componen
t
.
connect
(
controller
,
"requestTermination"
,
self
,
"finish"
);
_component_js__WEBPACK_IMPORTED_MODULE_2__
.
defaul
t
.
connect
(
controller
,
"requestSheet"
,
self
,
"setSheet"
);
_component_js__WEBPACK_IMPORTED_MODULE_2__
.
defaul
t
.
connect
(
controller
,
"requestTermination"
,
self
,
"finish"
);
controller
.
start
();
};
...
...
@@ -2011,7 +2162,7 @@ ARCS.Application = function () {
*
*/
this
.
import
=
function
(
object
)
{
context
=
new
ARCS
.
Contex
t
(
object
.
context
/*.components*/
);
context
=
new
_context_js__WEBPACK_IMPORTED_MODULE_0__
.
defaul
t
(
object
.
context
/*.components*/
);
sheets
=
object
.
sheets
;
controller
=
object
.
controller
;
if
(
controller
===
undefined
)
{
...
...
@@ -2042,17 +2193,114 @@ ARCS.Application = function () {
};
};
A
RCS
.
A
pplication
.
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
...
...
package.json
View file @
00351ab
...
...
@@ -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"
,
...
...
src/application.js
View file @
00351ab
/******************************************************************************
* 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 () {
};
};
A
RCS
.
A
pplication
.
setDependency
=
function
(
app
,
key
)
{
Application
.
setDependency
=
function
(
app
,
key
)
{
app
.
setDependency
(
key
);
};
ARCS
.
Component
.
create
(
ARCS
.
Application
);
A
RCS
.
A
pplication
.
slot
(
"setSheet"
);
A
RCS
.
A
pplication
.
slot
(
"finish"
);
Component
.
create
(
Application
);
Application
.
slot
(
"setSheet"
);
Application
.
slot
(
"finish"
);
export
default
{
Application
:
Application
};
...
...
src/arcs.js
View file @
00351ab
...
...
@@ -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);
};
...
...
src/component.js
View file @
00351ab
...
...
@@ -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
};
...
...
src/connection.js
View file @
00351ab
/******************************************************************************
* 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
};
...
...
src/context.js
View file @
00351ab
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
};
...
...
src/eventlogicparser.js
View file @
00351ab
...
...
@@ -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
};
...
...
src/exports.js
View file @
00351ab
// 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
};
...
...
src/invocation.js
View file @
00351ab
...
...
@@ -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
};
...
...
src/sheet.js
View file @
00351ab
/******************************************************************************
* 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
};
...
...
src/statemachine.js
View file @
00351ab
/******************************************************************************
* 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
};
...
...
src/tokenevent.js
View file @
00351ab
// 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
};
...
...
src/transitionnetwork.js
View file @
00351ab
/* 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
};
...
...
webpack.config.js
0 → 100644
View file @
00351ab
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
}
}
}
};
Please
register
or
login
to post a comment