Skip to content

Commit

Permalink
Active flag hooks, fixes StoneCypher/fsl#716
Browse files Browse the repository at this point in the history
  • Loading branch information
StoneCypher committed May 13, 2022
1 parent 0f1535b commit 9f3fa47
Show file tree
Hide file tree
Showing 16 changed files with 15,643 additions and 177 deletions.
14 changes: 7 additions & 7 deletions benchmark/results/general.chart.html
Expand Up @@ -28,7 +28,7 @@
</head>
<body>
<div class="container">
<canvas id="chart1652399505339" width="16" height="9"></canvas>
<canvas id="chart1652402030555" width="16" height="9"></canvas>
</div>
<script>
const format = (num) => {
Expand All @@ -51,18 +51,18 @@
chunked.map((chunk) => chunk.join('')).join(' ') + fractionStr
)
}
const ctx1652399505339 = document
.getElementById('chart1652399505339')
const ctx1652402030555 = document
.getElementById('chart1652402030555')
.getContext('2d')
const chart1652399505339 = new Chart(ctx1652399505339, {
const chart1652402030555 = new Chart(ctx1652402030555, {
type: 'bar',
data: {
labels: ["Blind cycle a traffic light 500 times by transition","Blind cycle a traffic light 500 times by action","Blind cycle a basic-hooked traffic light 500 times by transition","Blind cycle a named-hooked traffic light 500 times by transition","Blind cycle an any-transition traffic light 500 times by transition","Blind cycle an exit hooked traffic light 500 times by transition","Blind cycle an enter hooked traffic light 500 times by transition","Blind cycle a standard-transition hooked light by transition","Blind cycle a main-transition hooked light by transition","Blind cycle a force-transition hooked light by transition","Blind cycle a traffic light 500 times by action","Blind cycle a basic-hooked traffic light 500 times by action","Blind cycle a named-hooked traffic light 500 times by action","Blind cycle an any-action traffic light 500 times by action","Blind cycle a global-action traffic light 500 times by action","Blind cycle an exit hooked traffic light 500 times by action","Blind cycle an enter hooked traffic light 500 times by action","Blind cycle a standard transition tl 500 times by action","Blind cycle a main transition tl 500 times by action","Blind cycle a forced transition tl 500 times by action"],
datasets: [
{
data: [6018,12290,1207,1173,1267,1243,1246,1256,1259,24351,12645,796,750,819,815,822,824,60076,52154,57609],
backgroundColor: ["hsl(12.023999999999994, 85%, 55%)","hsl(24.551999999999992, 85%, 55%)","hsl(2.412000000000006, 85%, 55%)","hsl(2.3400000000000034, 85%, 55%)","hsl(2.531999999999999, 85%, 55%)","hsl(2.4839999999999915, 85%, 55%)","hsl(2.4839999999999915, 85%, 55%)","hsl(2.508000000000004, 85%, 55%)","hsl(2.519999999999993, 85%, 55%)","hsl(48.635999999999996, 85%, 55%)","hsl(25.259999999999994, 85%, 55%)","hsl(1.5839999999999919, 85%, 55%)","hsl(1.5, 85%, 55%)","hsl(1.6319999999999992, 85%, 55%)","hsl(1.6319999999999992, 85%, 55%)","hsl(1.6440000000000055, 85%, 55%)","hsl(1.6440000000000055, 85%, 55%)","hsl(120, 85%, 55%)","hsl(104.172, 85%, 55%)","hsl(115.068, 85%, 55%)"],
borderColor: ["hsl(12.023999999999994, 85%, 55%)","hsl(24.551999999999992, 85%, 55%)","hsl(2.412000000000006, 85%, 55%)","hsl(2.3400000000000034, 85%, 55%)","hsl(2.531999999999999, 85%, 55%)","hsl(2.4839999999999915, 85%, 55%)","hsl(2.4839999999999915, 85%, 55%)","hsl(2.508000000000004, 85%, 55%)","hsl(2.519999999999993, 85%, 55%)","hsl(48.635999999999996, 85%, 55%)","hsl(25.259999999999994, 85%, 55%)","hsl(1.5839999999999919, 85%, 55%)","hsl(1.5, 85%, 55%)","hsl(1.6319999999999992, 85%, 55%)","hsl(1.6319999999999992, 85%, 55%)","hsl(1.6440000000000055, 85%, 55%)","hsl(1.6440000000000055, 85%, 55%)","hsl(120, 85%, 55%)","hsl(104.172, 85%, 55%)","hsl(115.068, 85%, 55%)"],
data: [6307,13195,1324,5355,5663,5178,4977,5613,5666,19388,13282,1560,1416,10677,10097,9075,9455,72032,72078,72145],
backgroundColor: ["hsl(10.487999999999994, 85%, 55%)","hsl(21.948000000000008, 85%, 55%)","hsl(2.208000000000004, 85%, 55%)","hsl(8.904000000000002, 85%, 55%)","hsl(9.419999999999993, 85%, 55%)","hsl(8.616000000000009, 85%, 55%)","hsl(8.280000000000008, 85%, 55%)","hsl(9.336, 85%, 55%)","hsl(9.419999999999993, 85%, 55%)","hsl(32.24400000000001, 85%, 55%)","hsl(22.091999999999995, 85%, 55%)","hsl(2.591999999999996, 85%, 55%)","hsl(2.3519999999999923, 85%, 55%)","hsl(17.759999999999994, 85%, 55%)","hsl(16.8, 85%, 55%)","hsl(15.096, 85%, 55%)","hsl(15.732, 85%, 55%)","hsl(119.808, 85%, 55%)","hsl(119.892, 85%, 55%)","hsl(120, 85%, 55%)"],
borderColor: ["hsl(10.487999999999994, 85%, 55%)","hsl(21.948000000000008, 85%, 55%)","hsl(2.208000000000004, 85%, 55%)","hsl(8.904000000000002, 85%, 55%)","hsl(9.419999999999993, 85%, 55%)","hsl(8.616000000000009, 85%, 55%)","hsl(8.280000000000008, 85%, 55%)","hsl(9.336, 85%, 55%)","hsl(9.419999999999993, 85%, 55%)","hsl(32.24400000000001, 85%, 55%)","hsl(22.091999999999995, 85%, 55%)","hsl(2.591999999999996, 85%, 55%)","hsl(2.3519999999999923, 85%, 55%)","hsl(17.759999999999994, 85%, 55%)","hsl(16.8, 85%, 55%)","hsl(15.096, 85%, 55%)","hsl(15.732, 85%, 55%)","hsl(119.808, 85%, 55%)","hsl(119.892, 85%, 55%)","hsl(120, 85%, 55%)"],
borderWidth: 2,
},
],
Expand Down
130 changes: 65 additions & 65 deletions benchmark/results/general.json
@@ -1,135 +1,135 @@
{
"name": "General performance suite",
"date": "2022-05-12T23:51:45.339Z",
"date": "2022-05-13T00:33:50.555Z",
"version": "1.2.0",
"results": [
{
"name": "Blind cycle a traffic light 500 times by transition",
"ops": 6018,
"margin": 1.96,
"percentSlower": 89.98
"ops": 6307,
"margin": 2.74,
"percentSlower": 91.26
},
{
"name": "Blind cycle a traffic light 500 times by action",
"ops": 12290,
"margin": 2.53,
"percentSlower": 79.54
"ops": 13195,
"margin": 1.45,
"percentSlower": 81.71
},
{
"name": "Blind cycle a basic-hooked traffic light 500 times by transition",
"ops": 1207,
"margin": 4.7,
"percentSlower": 97.99
"ops": 1324,
"margin": 0.84,
"percentSlower": 98.16
},
{
"name": "Blind cycle a named-hooked traffic light 500 times by transition",
"ops": 1173,
"margin": 5.8,
"percentSlower": 98.05
"ops": 5355,
"margin": 8.69,
"percentSlower": 92.58
},
{
"name": "Blind cycle an any-transition traffic light 500 times by transition",
"ops": 1267,
"margin": 1.77,
"percentSlower": 97.89
"ops": 5663,
"margin": 1.68,
"percentSlower": 92.15
},
{
"name": "Blind cycle an exit hooked traffic light 500 times by transition",
"ops": 1243,
"margin": 2.17,
"percentSlower": 97.93
"ops": 5178,
"margin": 5.93,
"percentSlower": 92.82
},
{
"name": "Blind cycle an enter hooked traffic light 500 times by transition",
"ops": 1246,
"margin": 1.63,
"percentSlower": 97.93
"ops": 4977,
"margin": 6.41,
"percentSlower": 93.1
},
{
"name": "Blind cycle a standard-transition hooked light by transition",
"ops": 1256,
"margin": 1.56,
"percentSlower": 97.91
"ops": 5613,
"margin": 1.25,
"percentSlower": 92.22
},
{
"name": "Blind cycle a main-transition hooked light by transition",
"ops": 1259,
"margin": 1.59,
"percentSlower": 97.9
"ops": 5666,
"margin": 2.93,
"percentSlower": 92.15
},
{
"name": "Blind cycle a force-transition hooked light by transition",
"ops": 24351,
"margin": 1.65,
"percentSlower": 59.47
"ops": 19388,
"margin": 1.11,
"percentSlower": 73.13
},
{
"name": "Blind cycle a traffic light 500 times by action",
"ops": 12645,
"margin": 1.85,
"percentSlower": 78.95
"ops": 13282,
"margin": 1.11,
"percentSlower": 81.59
},
{
"name": "Blind cycle a basic-hooked traffic light 500 times by action",
"ops": 796,
"margin": 1.36,
"percentSlower": 98.68
"ops": 1560,
"margin": 1.65,
"percentSlower": 97.84
},
{
"name": "Blind cycle a named-hooked traffic light 500 times by action",
"ops": 750,
"margin": 6.79,
"percentSlower": 98.75
"ops": 1416,
"margin": 1.2,
"percentSlower": 98.04
},
{
"name": "Blind cycle an any-action traffic light 500 times by action",
"ops": 819,
"margin": 1.27,
"percentSlower": 98.64
"ops": 10677,
"margin": 1.26,
"percentSlower": 85.2
},
{
"name": "Blind cycle a global-action traffic light 500 times by action",
"ops": 815,
"margin": 1.92,
"percentSlower": 98.64
"ops": 10097,
"margin": 2.19,
"percentSlower": 86
},
{
"name": "Blind cycle an exit hooked traffic light 500 times by action",
"ops": 822,
"margin": 1,
"percentSlower": 98.63
"ops": 9075,
"margin": 1.23,
"percentSlower": 87.42
},
{
"name": "Blind cycle an enter hooked traffic light 500 times by action",
"ops": 824,
"margin": 0.68,
"percentSlower": 98.63
"ops": 9455,
"margin": 0.95,
"percentSlower": 86.89
},
{
"name": "Blind cycle a standard transition tl 500 times by action",
"ops": 60076,
"margin": 3.91,
"percentSlower": 0
"ops": 72032,
"margin": 1.3,
"percentSlower": 0.16
},
{
"name": "Blind cycle a main transition tl 500 times by action",
"ops": 52154,
"margin": 7.86,
"percentSlower": 13.19
"ops": 72078,
"margin": 1.14,
"percentSlower": 0.09
},
{
"name": "Blind cycle a forced transition tl 500 times by action",
"ops": 57609,
"margin": 2.65,
"percentSlower": 4.11
"ops": 72145,
"margin": 1.81,
"percentSlower": 0
}
],
"fastest": {
"name": "Blind cycle a standard transition tl 500 times by action",
"index": 17
"name": "Blind cycle a forced transition tl 500 times by action",
"index": 19
},
"slowest": {
"name": "Blind cycle a named-hooked traffic light 500 times by action",
"index": 12
"name": "Blind cycle a basic-hooked traffic light 500 times by transition",
"index": 2
}
}
15,333 changes: 15,332 additions & 1 deletion dist/es6/jssm-dot.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions dist/es6/jssm.d.ts
Expand Up @@ -42,6 +42,8 @@ declare class Machine<mDT> {
_has_named_hooks: boolean;
_has_entry_hooks: boolean;
_has_exit_hooks: boolean;
_has_global_action_hooks: boolean;
_has_transition_hooks: boolean;
_hooks: Map<string, Function>;
_named_hooks: Map<string, Function>;
_entry_hooks: Map<string, Function>;
Expand Down
56 changes: 38 additions & 18 deletions dist/es6/jssm.js
Expand Up @@ -350,6 +350,8 @@ class Machine {
this._has_named_hooks = false;
this._has_entry_hooks = false;
this._has_exit_hooks = false;
this._has_global_action_hooks = false;
this._has_transition_hooks = true;
// no need for a boolean has any transition hook, as it's one or nothing, so just test that for undefinedness
this._hooks = new Map();
this._named_hooks = new Map();
Expand Down Expand Up @@ -719,29 +721,35 @@ class Machine {
case 'hook':
this._hooks.set(hook_name(HookDesc.from, HookDesc.to), HookDesc.handler);
this._has_hooks = true;
this._has_basic_hooks = true;
break;
case 'named':
this._named_hooks.set(named_hook_name(HookDesc.from, HookDesc.to, HookDesc.action), HookDesc.handler);
this._has_hooks = true;
this._has_named_hooks = true;
break;
case 'global action':
this._global_action_hooks.set(HookDesc.action, HookDesc.handler);
this._has_hooks = true;
this._has_global_action_hooks = true;
break;
case 'any action':
this._any_action_hook = HookDesc.handler;
this._has_hooks = true;
break;
case 'standard transition':
this._standard_transition_hook = HookDesc.handler;
this._has_transition_hooks = true;
this._has_hooks = true;
break;
case 'main transition':
this._main_transition_hook = HookDesc.handler;
this._has_transition_hooks = true;
this._has_hooks = true;
break;
case 'forced transition':
this._forced_transition_hook = HookDesc.handler;
this._has_transition_hooks = true;
this._has_hooks = true;
break;
case 'any transition':
Expand All @@ -751,10 +759,12 @@ class Machine {
case 'entry':
this._entry_hooks.set(HookDesc.to, HookDesc.handler);
this._has_hooks = true;
this._has_entry_hooks = true;
break;
case 'exit':
this._exit_hooks.set(HookDesc.from, HookDesc.handler);
this._has_hooks = true;
this._has_exit_hooks = true;
break;
default:
console.log(`Unknown hook type ${HookDesc.kind}, should be impossible`);
Expand Down Expand Up @@ -838,8 +848,10 @@ class Machine {
}
else {
if (this.valid_transition(newStateOrAction, newData)) {
if (this._has_transition_hooks) {
trans_type = this.edges_between(this._state, newStateOrAction)[0].kind; // TODO this won't do the right thing if various edges have different types
}
valid = true;
trans_type = this.edges_between(this._state, newStateOrAction)[0].kind; // TODO this won't do the right thing if various edges have different types
newState = newStateOrAction;
}
}
Expand Down Expand Up @@ -869,26 +881,32 @@ class Machine {
}
}
// 4. exit hook
const maybe_ex_hook = this._exit_hooks.get(this._state);
if (maybe_ex_hook !== undefined) {
if (maybe_ex_hook({ from: this._state, forced: wasForced }) === false) {
return false;
if (this._has_exit_hooks) {
const maybe_ex_hook = this._exit_hooks.get(this._state);
if (maybe_ex_hook !== undefined) {
if (maybe_ex_hook({ from: this._state, forced: wasForced }) === false) {
return false;
}
}
}
// 5. named transition / action hook
if (wasAction) {
const nhn = named_hook_name(this._state, newState, newStateOrAction), n_maybe_hook = this._named_hooks.get(nhn);
if (n_maybe_hook !== undefined) {
if (n_maybe_hook({ from: this._state, to: newState, action: newStateOrAction }) === false) {
return false;
if (this._has_named_hooks) {
if (wasAction) {
const nhn = named_hook_name(this._state, newState, newStateOrAction), n_maybe_hook = this._named_hooks.get(nhn);
if (n_maybe_hook !== undefined) {
if (n_maybe_hook({ from: this._state, to: newState, action: newStateOrAction }) === false) {
return false;
}
}
}
}
// 6. regular hook
const hn = hook_name(this._state, newState), maybe_hook = this._hooks.get(hn);
if (maybe_hook !== undefined) {
if (maybe_hook({ from: this._state, to: newState, forced: wasForced, action: wasAction ? newStateOrAction : undefined }) === false) {
return false;
if (this._has_basic_hooks) {
const hn = hook_name(this._state, newState), maybe_hook = this._hooks.get(hn);
if (maybe_hook !== undefined) {
if (maybe_hook({ from: this._state, to: newState, forced: wasForced, action: wasAction ? newStateOrAction : undefined }) === false) {
return false;
}
}
}
// 7. edge type hook
Expand Down Expand Up @@ -923,10 +941,12 @@ class Machine {
}
}
// 8. entry hook
const maybe_en_hook = this._entry_hooks.get(newState);
if (maybe_en_hook !== undefined) {
if (maybe_en_hook({ to: newState, forced: wasForced }) === false) {
return false;
if (this._has_entry_hooks) {
const maybe_en_hook = this._entry_hooks.get(newState);
if (maybe_en_hook !== undefined) {
if (maybe_en_hook({ to: newState, forced: wasForced }) === false) {
return false;
}
}
}
this._state = newState;
Expand Down
2 changes: 1 addition & 1 deletion dist/jssm.es5.cjs.js

Large diffs are not rendered by default.

0 comments on commit 9f3fa47

Please sign in to comment.