Skip to content

Commit

Permalink
Updated deferUntilTransition to support passing either the string nam…
Browse files Browse the repository at this point in the history
…e of a single target state, or an array of target state names.

Removed bower and component files
  • Loading branch information
ifandelse committed Mar 18, 2018
1 parent 97e24ae commit 79c896d
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 70 deletions.
3 changes: 0 additions & 3 deletions .bowerrc

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# machina v2.0.0-1
# machina v3.0.0

## What is it?
Machina.js is a JavaScript framework for highly customizable finite state machines (FSMs). Many of the ideas for machina have been *loosely* inspired by the Erlang/OTP FSM behaviors.
Expand Down
29 changes: 0 additions & 29 deletions bower.json

This file was deleted.

11 changes: 11 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
### v3.0.0

* Updated `deferUntilTransition` to support passing the string value of a single state OR an array of target states.
* Removed bower.json & component.json files.


### v2.0.2

* Fix broken formatting in README.md
* Fixed issue where `this` gets lost on processQueue by changing binding approach - #147

### v2.0.1

* Fixed issue where the transitioned event was only firing if the state had handlers. (Fixes #137)
Expand Down
11 changes: 0 additions & 11 deletions component.json

This file was deleted.

16 changes: 11 additions & 5 deletions lib/machina.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/machina.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/machina.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "machina",
"description": "A library for creating powerful and flexible finite state machines. Loosely inspired by Erlang/OTP's gen_fsm behavior.",
"version": "2.0.2",
"version": "3.0.0",
"homepage": "http://machina-js.org/",
"repository": {
"type": "git",
Expand Down
153 changes: 145 additions & 8 deletions spec/BehavioralFsm.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
}
],
type: "transition",
untilState: "ready"
untilState: [ "ready" ]
},
client: client,
namespace: fsm.namespace
Expand Down Expand Up @@ -411,6 +411,143 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
}
} ] );
} );
it( "should handle deferred-until-transition input properly (with multiple target states)", function() {
var fsm = fsmFactory.instanceWithOptions( {
states: {
uninitialized: {
letsDoThis: function( client ) {
this.deferUntilTransition( client, [ "done", "notQuiteDone" ] );
}
},
notQuiteDone: {
letsDoThis: function() {
this.emit( "weAlreadyDidThat" );
}
},
done: {
letsDoThis: function() {
this.emit( "weAlreadyDidThat" );
}
}
}
} );
var events = [];
fsm.on( "*", function( evnt, data ) {
events.push( { eventName: evnt, data: data } );
} );
var client = { name: "Dijkstra" };
fsm.handle( client, "letsDoThis" );
fsm.transition( client, "done" );
events.should.eql( [
{
eventName: "transition",
data: {
action: "",
fromState: undefined,
toState: "uninitialized",
client: client,
namespace: fsm.namespace
}
},
{
eventName: "transitioned",
data: {
action: "",
fromState: undefined,
toState: "uninitialized",
client: client,
namespace: fsm.namespace
}
},
{
eventName: "handling",
data: {
client: client,
inputType: "letsDoThis",
delegated: false,
ticket: undefined,
namespace: fsm.namespace
}
},
{
eventName: "deferred",
data: {
state: "uninitialized",
queuedArgs: {
type: "transition",
untilState: [ "done", "notQuiteDone" ],
args: [
{
inputType: "letsDoThis",
delegated: false,
ticket: undefined
}
]
},
client: client,
namespace: fsm.namespace
}
},
{
eventName: "handled",
data: {
client: client,
inputType: "letsDoThis",
delegated: false,
ticket: undefined,
namespace: fsm.namespace
}
},
{
eventName: "transition",
data: {
fromState: "uninitialized",
action: "",
toState: "done",
client: client,
namespace: fsm.namespace
}
},
{
eventName: "done-OnEnterFiring",
data: undefined
},
{
data: {
action: "",
client: client,
fromState: "uninitialized",
namespace: "specialSauceNamespace",
toState: "done"
},
eventName: "transitioned"
},
{
eventName: "handling",
data: {
client: client,
inputType: "letsDoThis",
delegated: false,
ticket: undefined,
namespace: fsm.namespace
}
},
{
eventName: "weAlreadyDidThat",
data: undefined
},
{
eventName: "handled",
data: {
client: client,
inputType: "letsDoThis",
delegated: false,
ticket: undefined,
namespace: fsm.namespace
}
}
] );
} );
it( "should handle deferred-until-transition input properly (with NO target state)", function() {
var fsm = fsmFactory.instanceWithOptions( {
states: {
Expand Down Expand Up @@ -597,7 +734,7 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
state: "uninitialized",
queuedArgs: {
type: "transition",
untilState: "ready",
untilState: [ "ready" ],
args: [
{
inputType: "letsDoThis",
Expand Down Expand Up @@ -733,7 +870,7 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
client.__machina__[ fsm.namespace ].inputQueue.should.eql( [
{
type: "transition",
untilState: "ready",
untilState: [ "ready" ],
args: [
{
inputType: "letsDoThis",
Expand Down Expand Up @@ -789,7 +926,7 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
}
],
type: "transition",
untilState: "ready"
untilState: [ "ready" ]
},
client: client,
namespace: fsm.namespace
Expand Down Expand Up @@ -879,7 +1016,7 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
this.deferUntilTransition( client, "done" );
},
deferMeUntilNotQuiteDone: function( client ) {
this.deferUntilTransition( client, "notQuiteDone" );
this.deferUntilTransition( client, [ "notQuiteDone", "done" ] );
}
}
}
Expand All @@ -894,7 +1031,7 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
client.__machina__[ fsm.namespace ].inputQueue.should.eql( [
{
type: "transition",
untilState: "done",
untilState: [ "done" ],
args: [
{
inputType: "deferMeUntilDone",
Expand All @@ -905,7 +1042,7 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
},
{
type: "transition",
untilState: "notQuiteDone",
untilState: [ "notQuiteDone", "done" ],
args: [
{
inputType: "deferMeUntilNotQuiteDone",
Expand All @@ -919,7 +1056,7 @@ function runBehavioralFsmSpec( description, fsmFactory ) {
client.__machina__[ fsm.namespace ].inputQueue.should.eql( [
{
type: "transition",
untilState: "notQuiteDone",
untilState: [ "notQuiteDone" ],
args: [
{
inputType: "deferMeUntilNotQuiteDone",
Expand Down
14 changes: 7 additions & 7 deletions spec/MachinaFsm.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ function runMachinaFsmSpec( description, fsmFactory ) {
}
],
type: "transition",
untilState: "ready"
untilState: [ "ready" ]
},
namespace: fsm.namespace
}
Expand Down Expand Up @@ -439,7 +439,7 @@ function runMachinaFsmSpec( description, fsmFactory ) {
state: "uninitialized",
queuedArgs: {
type: "transition",
untilState: "ready",
untilState: [ "ready" ],
args: [
{
inputType: "letsDoThis",
Expand Down Expand Up @@ -565,7 +565,7 @@ function runMachinaFsmSpec( description, fsmFactory ) {
fsm.inputQueue.should.eql( [
{
type: "transition",
untilState: "ready",
untilState: [ "ready" ],
args: [
{
inputType: "letsDoThis",
Expand Down Expand Up @@ -593,7 +593,7 @@ function runMachinaFsmSpec( description, fsmFactory ) {
state: "uninitialized",
queuedArgs: {
type: "transition",
untilState: "ready",
untilState: [ "ready" ],
args: [
{
inputType: "letsDoThis",
Expand Down Expand Up @@ -698,7 +698,7 @@ function runMachinaFsmSpec( description, fsmFactory ) {
fsm.inputQueue.should.eql( [
{
type: "transition",
untilState: "done",
untilState: [ "done" ],
args: [
{
inputType: "deferMeUntilDone",
Expand All @@ -709,7 +709,7 @@ function runMachinaFsmSpec( description, fsmFactory ) {
},
{
type: "transition",
untilState: "notQuiteDone",
untilState: [ "notQuiteDone" ],
args: [
{
inputType: "deferMeUntilNotQuiteDone",
Expand All @@ -723,7 +723,7 @@ function runMachinaFsmSpec( description, fsmFactory ) {
fsm.inputQueue.should.eql( [
{
type: "transition",
untilState: "notQuiteDone",
untilState: [ "notQuiteDone" ],
args: [
{
inputType: "deferMeUntilNotQuiteDone",
Expand Down
12 changes: 9 additions & 3 deletions src/BehavioralFsm.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,11 @@ _.extend( BehavioralFsm.prototype, {

deferUntilTransition: function( client, stateName ) {
var clientMeta = this.ensureClientMeta( client );
var stateList = _.isArray( stateName ) ? stateName : ( stateName ? [ stateName ] : undefined );
if ( clientMeta.currentActionArgs ) {
var queued = {
type: events.NEXT_TRANSITION,
untilState: stateName,
untilState: stateList,
args: clientMeta.currentActionArgs
};
clientMeta.inputQueue.push( queued );
Expand All @@ -216,7 +217,7 @@ _.extend( BehavioralFsm.prototype, {
processQueue: function( client ) {
var clientMeta = this.ensureClientMeta( client );
var filterFn = function( item ) {
return ( ( !item.untilState ) || ( item.untilState === clientMeta.state ) );
return ( ( !item.untilState ) || ( _.includes( item.untilState, clientMeta.state ) ) );
};
var toProcess = _.filter( clientMeta.inputQueue, filterFn );
clientMeta.inputQueue = _.difference( clientMeta.inputQueue, toProcess );
Expand All @@ -230,8 +231,13 @@ _.extend( BehavioralFsm.prototype, {
if ( !name ) {
clientMeta.inputQueue = [];
} else {
// first pass we remove the target state from any `untilState` array
_.each( clientMeta.inputQueue, function( item ) {
item.untilState = _.without( item.untilState, name );
} );
// second pass we clear out deferred events with empty untilState arrays
var filter = function( evnt ) {
return ( name ? evnt.untilState !== name : true );
return evnt.untilState.length !== 0;
};
clientMeta.inputQueue = _.filter( clientMeta.inputQueue, filter );
}
Expand Down

0 comments on commit 79c896d

Please sign in to comment.