Skip to content

Commit

Permalink
Merge pull request #456 from StoneCypher/ApiEntryHooks
Browse files Browse the repository at this point in the history
Api entry hooks
  • Loading branch information
StoneCypher committed May 9, 2022
2 parents 63736ef + 8e20d05 commit c6438ab
Show file tree
Hide file tree
Showing 17 changed files with 232 additions and 126 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="chart1652046365363" width="16" height="9"></canvas>
<canvas id="chart1652112065483" width="16" height="9"></canvas>
</div>
<script>
const format = (num) => {
Expand All @@ -51,18 +51,18 @@
chunked.map((chunk) => chunk.join('')).join(' ') + fractionStr
)
}
const ctx1652046365363 = document
.getElementById('chart1652046365363')
const ctx1652112065483 = document
.getElementById('chart1652112065483')
.getContext('2d')
const chart1652046365363 = new Chart(ctx1652046365363, {
const chart1652112065483 = new Chart(ctx1652112065483, {
type: 'bar',
data: {
labels: ["Blind cycle a traffic light 500 times by transition","Blind cycle a hooked traffic light 500 times by transition","Blind cycle a traffic light 500 times by action","Blind cycle a hooked traffic light 500 times by action"],
datasets: [
{
data: [20030,1707,13722,828],
backgroundColor: ["hsl(120, 85%, 55%)","hsl(10.223999999999995, 85%, 55%)","hsl(82.212, 85%, 55%)","hsl(4.955999999999994, 85%, 55%)"],
borderColor: ["hsl(120, 85%, 55%)","hsl(10.223999999999995, 85%, 55%)","hsl(82.212, 85%, 55%)","hsl(4.955999999999994, 85%, 55%)"],
data: [18713,1726,14874,819],
backgroundColor: ["hsl(120, 85%, 55%)","hsl(11.063999999999998, 85%, 55%)","hsl(95.376, 85%, 55%)","hsl(5.255999999999995, 85%, 55%)"],
borderColor: ["hsl(120, 85%, 55%)","hsl(11.063999999999998, 85%, 55%)","hsl(95.376, 85%, 55%)","hsl(5.255999999999995, 85%, 55%)"],
borderWidth: 2,
},
],
Expand Down
24 changes: 12 additions & 12 deletions benchmark/results/general.json
@@ -1,31 +1,31 @@
{
"name": "General performance suite",
"date": "2022-05-08T21:46:05.363Z",
"date": "2022-05-09T16:01:05.483Z",
"version": "1.1.0",
"results": [
{
"name": "Blind cycle a traffic light 500 times by transition",
"ops": 20030,
"margin": 2.06,
"ops": 18713,
"margin": 1.21,
"percentSlower": 0
},
{
"name": "Blind cycle a hooked traffic light 500 times by transition",
"ops": 1707,
"margin": 0.83,
"percentSlower": 91.48
"ops": 1726,
"margin": 0.59,
"percentSlower": 90.78
},
{
"name": "Blind cycle a traffic light 500 times by action",
"ops": 13722,
"margin": 1.78,
"percentSlower": 31.49
"ops": 14874,
"margin": 0.46,
"percentSlower": 20.52
},
{
"name": "Blind cycle a hooked traffic light 500 times by action",
"ops": 828,
"margin": 2.04,
"percentSlower": 95.87
"ops": 819,
"margin": 3.29,
"percentSlower": 95.62
}
],
"fastest": {
Expand Down
2 changes: 2 additions & 0 deletions dist/es6/jssm.d.ts
Expand Up @@ -40,8 +40,10 @@ declare class Machine<mDT> {
_has_hooks: boolean;
_has_basic_hooks: boolean;
_has_named_hooks: boolean;
_has_entry_hooks: boolean;
_hooks: Map<string, Function>;
_named_hooks: Map<string, Function>;
_entry_hooks: Map<string, Function>;
_any_transition_hook: HookHandler | undefined;
constructor({ start_states, complete, transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, state_declaration, fsl_version, dot_preamble, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout }: JssmGenericConfig<mDT>);
_new_state(state_config: JssmGenericState): StateType;
Expand Down
57 changes: 34 additions & 23 deletions dist/es6/jssm.js
Expand Up @@ -348,8 +348,11 @@ class Machine {
this._has_hooks = false;
this._has_basic_hooks = false;
this._has_named_hooks = false;
this._has_entry_hooks = false;
// 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();
this._entry_hooks = new Map();
this._any_transition_hook = undefined;
if (state_declaration) {
state_declaration.map((state_decl) => {
Expand Down Expand Up @@ -717,9 +720,10 @@ class Machine {
this._any_transition_hook = HookDesc.handler;
this._has_hooks = true;
break;
// case 'entry':
// console.log('TODO: Should add entry hook here');
// throw 'TODO: Should add entry hook here';
case 'entry':
this._entry_hooks.set(HookDesc.to, HookDesc.handler);
this._has_hooks = true;
break;
// case 'exit':
// console.log('TODO: Should add exit hook here');
// throw 'TODO: Should add exit hook here';
Expand Down Expand Up @@ -771,43 +775,50 @@ class Machine {
// todo major incomplete whargarbl comeback
if (valid) {
if (this._has_hooks) {
let hook_permits = undefined;
// 1. any action hook
// not yet implemented
// 2. any transition hook
if (this._any_transition_hook !== undefined) {
if (this._any_transition_hook() === false) {
return false;
}
}
// 3. exit hook
// not yet implemented
// 4. 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) {
hook_permits = true;
}
else {
hook_permits = n_maybe_hook({ from: this._state, to: newState, action: newStateOrAction });
}
if (!(hook_permits)) {
return false;
if (n_maybe_hook !== undefined) {
if (n_maybe_hook({ from: this._state, to: newState, action: newStateOrAction }) === false) {
return false;
}
}
}
// 5. regular hook
const hn = hook_name(this._state, newState), maybe_hook = this._hooks.get(hn);
if (maybe_hook === undefined) {
hook_permits = true;
}
else {
hook_permits = maybe_hook({ from: this._state, to: newState, forced: wasForced, action: wasAction ? newStateOrAction : undefined });
}
if (hook_permits !== false) {
this._state = newState;
return true;
if (maybe_hook !== undefined) {
if (maybe_hook({ from: this._state, to: newState, forced: wasForced, action: wasAction ? newStateOrAction : undefined }) === false) {
return false;
}
}
else {
return false;
// 6. edge type hook
// not yet implemented
// 7. 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;
}
}
this._state = newState;
return true;
// or without hooks
}
else {
this._state = newState;
return true;
}
// not valid
}
else {
return false;
Expand Down
2 changes: 1 addition & 1 deletion dist/es6/version.js
@@ -1,2 +1,2 @@
const version = "5.55.0";
const version = "5.56.0";
export { version };
2 changes: 1 addition & 1 deletion dist/jssm.es5.cjs.js

Large diffs are not rendered by default.

59 changes: 35 additions & 24 deletions dist/jssm.es5.cjs.nonmin.js
Expand Up @@ -15886,7 +15886,7 @@ function peg$parse(input, options) {
}
}

const version = "5.55.0";
const version = "5.56.0";

// whargarbl lots of these return arrays could/should be sets
/* eslint-disable complexity */
Expand Down Expand Up @@ -16234,8 +16234,11 @@ class Machine {
this._has_hooks = false;
this._has_basic_hooks = false;
this._has_named_hooks = false;
this._has_entry_hooks = false;
// 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();
this._entry_hooks = new Map();
this._any_transition_hook = undefined;
if (state_declaration) {
state_declaration.map((state_decl) => {
Expand Down Expand Up @@ -16603,9 +16606,10 @@ class Machine {
this._any_transition_hook = HookDesc.handler;
this._has_hooks = true;
break;
// case 'entry':
// console.log('TODO: Should add entry hook here');
// throw 'TODO: Should add entry hook here';
case 'entry':
this._entry_hooks.set(HookDesc.to, HookDesc.handler);
this._has_hooks = true;
break;
// case 'exit':
// console.log('TODO: Should add exit hook here');
// throw 'TODO: Should add exit hook here';
Expand Down Expand Up @@ -16657,43 +16661,50 @@ class Machine {
// todo major incomplete whargarbl comeback
if (valid) {
if (this._has_hooks) {
let hook_permits = undefined;
// 1. any action hook
// not yet implemented
// 2. any transition hook
if (this._any_transition_hook !== undefined) {
if (this._any_transition_hook() === false) {
return false;
}
}
// 3. exit hook
// not yet implemented
// 4. 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) {
hook_permits = true;
}
else {
hook_permits = n_maybe_hook({ from: this._state, to: newState, action: newStateOrAction });
}
if (!(hook_permits)) {
return false;
if (n_maybe_hook !== undefined) {
if (n_maybe_hook({ from: this._state, to: newState, action: newStateOrAction }) === false) {
return false;
}
}
}
// 5. regular hook
const hn = hook_name(this._state, newState), maybe_hook = this._hooks.get(hn);
if (maybe_hook === undefined) {
hook_permits = true;
}
else {
hook_permits = maybe_hook({ from: this._state, to: newState, forced: wasForced, action: wasAction ? newStateOrAction : undefined });
}
if (hook_permits !== false) {
this._state = newState;
return true;
if (maybe_hook !== undefined) {
if (maybe_hook({ from: this._state, to: newState, forced: wasForced, action: wasAction ? newStateOrAction : undefined }) === false) {
return false;
}
}
else {
return false;
// 6. edge type hook
// not yet implemented
// 7. 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;
}
}
this._state = newState;
return true;
// or without hooks
}
else {
this._state = newState;
return true;
}
// not valid
}
else {
return false;
Expand Down
2 changes: 1 addition & 1 deletion dist/jssm.es5.iife.js

Large diffs are not rendered by default.

0 comments on commit c6438ab

Please sign in to comment.