diff --git a/benchmark/results/general.chart.html b/benchmark/results/general.chart.html index 5b527362..845ef976 100644 --- a/benchmark/results/general.chart.html +++ b/benchmark/results/general.chart.html @@ -28,7 +28,7 @@
- +
Options
All
  • Public
  • Public/Protected
  • All
Menu

Class Machine<mDT>

Type parameters

  • mDT

Hierarchy

  • Machine

Index

Constructors

Properties

Methods

Constructors

  • new Machine<mDT>(__namedParameters: JssmGenericConfig<mDT>): Machine<mDT>
  • Type parameters

    • mDT

    Parameters

    • __namedParameters: JssmGenericConfig<mDT>

    Returns Machine<mDT>

Properties

_actions: Map<string, Map<string, number>>
_any_action_hook: Function
_any_transition_hook: Function
_arrange_declaration: string[][]
_arrange_end_declaration: string[][]
_arrange_start_declaration: string[][]
_dot_preamble: string
_edge_map: Map<string, Map<string, number>>
_edges: JssmTransition<mDT>[]
_entry_hooks: Map<string, Function>
_exit_hooks: Map<string, Function>
_flow: FslDirection
_forced_transition_hook: Function
_fsl_version?: string
_global_action_hooks: Map<string, Function>
_graph_layout: JssmLayout
_has_basic_hooks: boolean
_has_entry_hooks: boolean
_has_exit_hooks: boolean
_has_global_action_hooks: boolean
_has_hooks: boolean
_has_named_hooks: boolean
_has_transition_hooks: boolean
_hooks: Map<string, Function>
_instance_name: string
_machine_author?: string[]
_machine_comment?: string
_machine_contributor?: string[]
_machine_definition?: string
_machine_language?: string
_machine_license?: string
_machine_name?: string
_machine_version?: string
_main_transition_hook: Function
_named_hooks: Map<string, Function>
_named_transitions: Map<string, number>
_raw_state_declaration?: Object[]
_reverse_action_targets: Map<string, Map<string, number>>
_reverse_actions: Map<string, Map<string, number>>
_standard_transition_hook: Function
_state: string
_state_declarations: Map<string, JssmStateDeclaration>
_states: Map<string, JssmGenericState>
_theme: FslTheme

Methods

  • _new_state(state_config: JssmGenericState): string
  • theme(): FslTheme
  • transition(newState: string, newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional newData: mDT

    Returns boolean

  • transition_impl(newStateOrAction: string, newData: mDT, wasForced: boolean, wasAction: boolean): boolean
  • Parameters

    • newStateOrAction: string
    • newData: mDT
    • wasForced: boolean
    • wasAction: boolean

    Returns boolean

  • valid_action(action: string, _newData?: mDT): boolean
  • Parameters

    • action: string
    • Optional _newData: mDT

    Returns boolean

  • valid_force_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

  • valid_transition(newState: string, _newData?: mDT): boolean
  • Parameters

    • newState: string
    • Optional _newData: mDT

    Returns boolean

Generated using TypeDoc

\ No newline at end of file diff --git a/docs/docs/modules.html b/docs/docs/modules.html index 6bc29fc5..d0c700fa 100644 --- a/docs/docs/modules.html +++ b/docs/docs/modules.html @@ -1,21 +1,21 @@ -jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

jssm

Index

Variables

gviz_shapes: string[] = ...
histograph: Function = ...
+jssm
Options
All
  • Public
  • Public/Protected
  • All
Menu

jssm

Index

Variables

gviz_shapes: string[] = ...
histograph: Function = ...

Returns the histograph of an array as a Map. Makes no attempt to cope with deep equality; will fail for complex contents, as such.

import { histograph } from './jssm';

histograph( [0, 0, 1, 1, 2, 2, 1] ); // Map()
-
named_colors: string[] = ...
shapes: string[] = gviz_shapes
version: string = "5.65.10"
weighted_histo_key: Function = ...
weighted_rand_select: Function = ...
weighted_sample_select: Function = ...

Functions

  • arrow_direction(arrow: JssmArrow): JssmArrowDirection
named_colors: string[] = ...
shapes: string[] = gviz_shapes
version: string = "5.65.11"
weighted_histo_key: Function = ...
weighted_rand_select: Function = ...
weighted_sample_select: Function = ...

Functions

  • arrow_direction(arrow: JssmArrow): JssmArrowDirection
  • Return the direction of an arrow - right, left, or both.

    import { arrow_direction } from 'jssm';

    arrow_direction('->'); // 'right'
    arrow_direction('<~=>'); // 'both'
    -

    Parameters

    • arrow: JssmArrow

    Returns JssmArrowDirection

  • arrow_left_kind(arrow: JssmArrow): JssmArrowKind
  • +

    Parameters

    • arrow: JssmArrow

    Returns JssmArrowDirection

  • arrow_left_kind(arrow: JssmArrow): JssmArrowKind
  • Return the direction of an arrow - right, left, or both.

    import { arrow_left_kind } from 'jssm';

    arrow_left_kind('<-'); // 'legal'
    arrow_left_kind('<='); // 'main'
    arrow_left_kind('<~'); // 'forced'
    arrow_left_kind('<->'); // 'legal'
    arrow_left_kind('->'); // 'none'
    -

    Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • arrow_right_kind(arrow: JssmArrow): JssmArrowKind
  • +

    Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • arrow_right_kind(arrow: JssmArrow): JssmArrowKind
  • Return the direction of an arrow - right, left, or both.

    import { arrow_left_kind } from 'jssm';

    arrow_left_kind('->'); // 'legal'
    arrow_left_kind('=>'); // 'main'
    arrow_left_kind('~>'); // 'forced'
    arrow_left_kind('<->'); // 'legal'
    arrow_left_kind('<-'); // 'none'
    -

    Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT>
  • +

    Parameters

    • arrow: JssmArrow

    Returns JssmArrowKind

  • compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT>
  • Compile a machine's JSON intermediate representation to a config object. If you're using this (probably don't,) you're probably also using parse to get the IR, and the object constructor @@ -38,7 +38,7 @@

    Hey!

    Method {@link from}:

    import * as jssm from 'jssm';

    const toggle = jssm.from('up <=> down;');
    -

    Type parameters

    • mDT

    Parameters

    • tree: JssmParseTree

    Returns JssmGenericConfig<mDT>

  • from<mDT>(MachineAsString: string, ExtraConstructorFields?: Partial<JssmGenericConfig<mDT>>): Machine<mDT>
  • +

    Type parameters

    • mDT

    Parameters

    • tree: JssmParseTree

    Returns JssmGenericConfig<mDT>

  • from<mDT>(MachineAsString: string, ExtraConstructorFields?: Partial<JssmGenericConfig<mDT>>): Machine<mDT>
  • Create a state machine from an implementation string. This is one of the two main paths for working with JSSM, alongside sm.

    Use this method when you want to conveniently pull a state machine from a @@ -46,11 +46,11 @@

    Hey!

    template expression.

    import * as jssm from 'jssm';

    const switch = jssm.from('on <=> off;');
    -

    Type parameters

    • mDT

    Parameters

    • MachineAsString: string
    • Optional ExtraConstructorFields: Partial<JssmGenericConfig<mDT>>

    Returns Machine<mDT>

  • make<mDT>(plan: string): JssmGenericConfig<mDT>
  • +

    Type parameters

    • mDT

    Parameters

    • MachineAsString: string
    • Optional ExtraConstructorFields: Partial<JssmGenericConfig<mDT>>

    Returns Machine<mDT>

  • make<mDT>(plan: string): JssmGenericConfig<mDT>
  • An internal convenience wrapper for parsing then compiling a machine string. Not generally meant for external use. Please see compile or sm.

    -

    Type parameters

    • mDT

    Parameters

    • plan: string

    Returns JssmGenericConfig<mDT>

  • parse(input: string, options?: Object): any
  • +

    Type parameters

    • mDT

    Parameters

    • plan: string

    Returns JssmGenericConfig<mDT>

  • parse(input: string, options?: Object): any
  • This method wraps the parser call that comes from the peg grammar, parse. Generally neither this nor that should be used directly unless you mean to develop plugins or extensions for the machine.

    @@ -77,11 +77,11 @@

    Hey!

    wrap_parse itself is an internal convenience method for alting out an object as the options call. Not generally meant for external use.

    -

    Parameters

    • input: string
    • Optional options: Object

    Returns any

  • seq(n: number): number[]
  • +

    Parameters

    • input: string
    • Optional options: Object

    Returns any

  • seq(n: number): number[]
  • Returns, for a non-negative integer argument n, the series [0 .. n].

    import { seq } from './jssm';

    seq(5); // [0, 1, 2, 3, 4]
    seq(0); // []
    -

    Parameters

    • n: number

    Returns number[]

  • sm<mDT>(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • +

    Parameters

    • n: number

    Returns number[]

  • sm<mDT>(template_strings: TemplateStringsArray, ...remainder: any[]): Machine<mDT>
  • Create a state machine from a template string. This is one of the two main paths for working with JSSM, alongside {@link from}.

    Use this method when you want to work directly and conveniently with a @@ -89,7 +89,7 @@

    Hey!

    dynamic strings.

    import * as jssm from 'jssm';

    const switch = jssm.from('on <=> off;');
    -

    Type parameters

    • mDT

    Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateDeclaration
  • +

    Type parameters

    • mDT

    Parameters

    • template_strings: TemplateStringsArray
    • Rest ...remainder: any[]

    Returns Machine<mDT>

  • transfer_state_properties(state_decl: JssmStateDeclaration): JssmStateDeclaration
  • An internal method meant to take a series of declarations and fold them into a single multi-faceted declaration, in the process of building a state. Not generally meant for external use.

    diff --git a/jssm.d.ts b/jssm.d.ts index 13cb0502..1d206f6a 100644 --- a/jssm.d.ts +++ b/jssm.d.ts @@ -313,6 +313,35 @@ declare class Machine { * */ has_state(whichState: StateType): boolean; + /********* + * + * Lists all edges of a machine. + * + * ```typescript + * const lswitch = sm`on 'toggle' <=> 'toggle' off;`; + * + * lswitch.list_edges(); + * [ + * { + * from: 'on', + * to: 'off', + * kind: 'main', + * forced_only: false, + * main_path: true, + * action: 'toggle' + * }, + * { + * from: 'off', + * to: 'on', + * kind: 'main', + * forced_only: false, + * main_path: true, + * action: 'toggle' + * } + * ] + * ``` + * + */ list_edges(): Array>; list_named_transitions(): Map; list_actions(): Array; @@ -320,8 +349,45 @@ declare class Machine { flow(): FslDirection; get_transition_by_state_names(from: StateType, to: StateType): number; lookup_transition_for(from: StateType, to: StateType): JssmTransition; + /******** + * + * List all transitions attached to the current state, sorted by entrance and + * exit. The order of each sublist is not defined. A node could appear in + * both lists. + * + * const lswitch = sm`on 'toggle' <=> 'toggle' off;`; + * const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`; + * + * light.state(); // 'red' + * light.list_transitions(); // { entrances: [ 'yellow', 'off' ], exits: [ 'green', 'off' ] } + * + */ list_transitions(whichState?: StateType): JssmTransitionList; + /******** + * + * List all entrances attached to the current state. Please note that the + * order of the list is not defined. + * + * const lswitch = sm`on 'toggle' <=> 'toggle' off;`; + * const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`; + * + * light.state(); // 'red' + * light.list_entrances(); // [ 'yellow', 'off' ] + * + */ list_entrances(whichState?: StateType): Array; + /******** + * + * List all exits attached to the current state. Please note that the order + * of the list is not defined. + * + * const lswitch = sm`on 'toggle' <=> 'toggle' off;`; + * const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`; + * + * light.state(); // 'red' + * light.list_exits(); // [ 'green', 'off' ] + * + */ list_exits(whichState?: StateType): Array; probable_exits_for(whichState: StateType): Array>; probabilistic_transition(): boolean; diff --git a/package.json b/package.json index 7b9a1368..8ba67995 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jssm", - "version": "5.65.10", + "version": "5.65.11", "engines": { "node": ">=10.0.0" }, diff --git a/src/buildjs/benchmark.js b/src/buildjs/benchmark.js index 7742fa21..1265a994 100644 --- a/src/buildjs/benchmark.js +++ b/src/buildjs/benchmark.js @@ -9,9 +9,9 @@ const b = require('benny'), const Tl4 = sm`red => green => yellow => red; [red yellow green] ~> off -> red;`; -function TransitionCycleTL500Times() { +function TransitionCycleTL100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4.transition('green'); Tl4.transition('yellow'); Tl4.transition('red'); @@ -25,9 +25,9 @@ function TransitionCycleTL500Times() { const Tl4A = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; -function ActionCycleTL500Times() { +function ActionCycleTL100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4A.action('next'); Tl4A.action('next'); Tl4A.action('next'); @@ -42,9 +42,9 @@ function ActionCycleTL500Times() { const Tl4WH = sm`red => green => yellow => red; [red yellow green] ~> off -> red;`; Tl4WH.set_hook({ from: 'red', to: 'green', handler: () => true, kind: 'hook' }); -function TransitionCycleTLWithHooks500Times() { +function TransitionCycleTLWithHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4WH.transition('green'); Tl4WH.transition('yellow'); Tl4WH.transition('red'); @@ -59,9 +59,9 @@ function TransitionCycleTLWithHooks500Times() { const Tl4WAHA = sm`red 'foo' => green => yellow => red; [red yellow green] ~> off -> red;`; Tl4WAHA.set_hook({ from: 'red', to: 'green', name: 'foo', handler: () => true, kind: 'named' }); -function TransitionCycleTLWithNamedHooks500Times() { +function TransitionCycleTLWithNamedHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4WAHA.transition('green'); Tl4WAHA.transition('yellow'); Tl4WAHA.transition('red'); @@ -76,9 +76,9 @@ function TransitionCycleTLWithNamedHooks500Times() { const Tl4AT = sm`red 'foo' => green => yellow => red; [red yellow green] ~> off -> red;`; Tl4AT.set_hook({ handler: () => true, kind: 'any transition' }); -function TransitionCycleTLWithAnyTransitionHooks500Times() { +function TransitionCycleTLWithAnyTransitionHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4AT.transition('green'); Tl4AT.transition('yellow'); Tl4AT.transition('red'); @@ -93,9 +93,9 @@ function TransitionCycleTLWithAnyTransitionHooks500Times() { const Tl4EX = sm`red 'foo' => green => yellow => red; [red yellow green] ~> off -> red;`; Tl4EX.set_hook({ handler: () => true, from: 'red', kind: 'exit' }); -function TransitionCycleTLWithExitHooks500Times() { +function TransitionCycleTLWithExitHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4EX.transition('green'); Tl4EX.transition('yellow'); Tl4EX.transition('red'); @@ -110,9 +110,9 @@ function TransitionCycleTLWithExitHooks500Times() { const Tl4EN = sm`red 'foo' => green => yellow => red; [red yellow green] ~> off -> red;`; Tl4EN.set_hook({ handler: () => true, to: 'red', kind: 'entry' }); -function TransitionCycleTLWithEnterHooks500Times() { +function TransitionCycleTLWithEnterHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4EN.transition('green'); Tl4EN.transition('yellow'); Tl4EN.transition('red'); @@ -127,9 +127,9 @@ function TransitionCycleTLWithEnterHooks500Times() { const Tl4ST = sm`red 'foo' -> green -> yellow -> red; [red yellow green] ~> off -> red;`; Tl4ST.set_hook({ handler: () => true, to: 'red', kind: 'standard transition' }); -function TransitionCycleTLWithSTHooks500Times() { +function TransitionCycleTLWithSTHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4ST.transition('green'); Tl4ST.transition('yellow'); Tl4ST.transition('red'); @@ -144,9 +144,9 @@ function TransitionCycleTLWithSTHooks500Times() { const Tl4MT = sm`red 'foo' => green => yellow => red; [red yellow green] ~> off -> red;`; Tl4MT.set_hook({ handler: () => true, to: 'red', kind: 'main transition' }); -function TransitionCycleTLWithMTHooks500Times() { +function TransitionCycleTLWithMTHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4MT.transition('green'); Tl4MT.transition('yellow'); Tl4MT.transition('red'); @@ -161,9 +161,9 @@ function TransitionCycleTLWithMTHooks500Times() { const Tl4FT = sm`red 'foo' ~> green ~> yellow ~> red; [red yellow green] ~> off -> red;`; Tl4FT.set_hook({ handler: () => true, to: 'red', kind: 'forced transition' }); -function TransitionCycleTLWithFTHooks500Times() { +function TransitionCycleTLWithFTHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4FT.transition('green'); Tl4FT.transition('yellow'); Tl4FT.transition('red'); @@ -177,9 +177,9 @@ function TransitionCycleTLWithFTHooks500Times() { const Tl4WA = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; -function ActionCycleTL500Times() { +function ActionCycleTL100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4WA.action('next'); // to green Tl4WA.action('next'); // to yellow Tl4WA.action('next'); // to red @@ -195,9 +195,9 @@ function ActionCycleTL500Times() { const Tl4WAWH = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; Tl4WAWH.set_hook({ from: 'red', to: 'green', handler: () => true, kind: 'hook' }); -function ActionCycleTLWithHooks500Times() { +function ActionCycleTLWithHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4WAWH.action('next'); // to green Tl4WAWH.action('next'); // to yellow Tl4WAWH.action('next'); // to red @@ -213,9 +213,9 @@ function ActionCycleTLWithHooks500Times() { const Tl4WAWHA = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; Tl4WAWHA.set_hook({ from: 'red', to: 'green', name: 'next', handler: () => true, kind: 'named' }); -function ActionCycleTLWithNamedHooks500Times() { +function ActionCycleTLWithNamedHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4WAWHA.action('next'); // to green Tl4WAWHA.action('next'); // to yellow Tl4WAWHA.action('next'); // to red @@ -231,9 +231,9 @@ function ActionCycleTLWithNamedHooks500Times() { const Tl4AA = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; Tl4AA.set_hook({ handler: () => true, kind: 'any action' }); -function AnyActionCycleTLWithNamedHooks500Times() { +function AnyActionCycleTLWithNamedHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4AA.action('next'); // to green Tl4AA.action('next'); // to yellow Tl4AA.action('next'); // to red @@ -249,9 +249,9 @@ function AnyActionCycleTLWithNamedHooks500Times() { const Tl4TAA = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; Tl4TAA.set_hook({ handler: () => true, kind: 'any transition' }); -function ActionCycleTLWithAnyTransitionHooks500Times() { +function ActionCycleTLWithAnyTransitionHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4TAA.action('next'); // to green Tl4TAA.action('next'); // to yellow Tl4TAA.action('next'); // to red @@ -266,9 +266,9 @@ function ActionCycleTLWithAnyTransitionHooks500Times() { const Tl4EXA = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; Tl4EXA.set_hook({ handler: () => true, from: 'red', kind: 'exit' }); -function ActionCycleTLWithExitHooks500Times() { +function ActionCycleTLWithExitHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4EXA.action('next'); // to green Tl4EXA.action('next'); // to yellow Tl4EXA.action('next'); // to red @@ -283,9 +283,9 @@ function ActionCycleTLWithExitHooks500Times() { const Tl4ENA = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; Tl4ENA.set_hook({ handler: () => true, to: 'red', kind: 'entry' }); -function ActionCycleTLWithEnterHooks500Times() { +function ActionCycleTLWithEnterHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4ENA.action('next'); // to green Tl4ENA.action('next'); // to yellow Tl4ENA.action('next'); // to red @@ -300,9 +300,9 @@ function ActionCycleTLWithEnterHooks500Times() { const Tl4STA = sm`red -> green -> yellow -> red; [red yellow green] ~> off -> red;`; Tl4STA.set_hook({ handler: () => true, kind: 'standard transition' }); -function ActionCycleTLWithSTHooks500Times() { +function ActionCycleTLWithSTHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4STA.action('next'); // to green Tl4STA.action('next'); // to yellow Tl4STA.action('next'); // to red @@ -318,9 +318,9 @@ function ActionCycleTLWithSTHooks500Times() { const Tl4MTA = sm`red => green => yellow => red; [red yellow green] ~> off -> red;`; Tl4MTA.set_hook({ handler: () => true, kind: 'main transition' }); -function ActionCycleTLWithMTHooks500Times() { +function ActionCycleTLWithMTHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4MTA.action('next'); // to green Tl4MTA.action('next'); // to yellow Tl4MTA.action('next'); // to red @@ -336,9 +336,9 @@ function ActionCycleTLWithMTHooks500Times() { const Tl4FTA = sm`red ~> green ~> yellow ~> red; [red yellow green] ~> off -> red;`; Tl4FTA.set_hook({ handler: () => true, kind: 'forced transition' }); -function ActionCycleTLWithFTHooks500Times() { +function ActionCycleTLWithFTHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4FTA.action('next'); // to green Tl4FTA.action('next'); // to yellow Tl4FTA.action('next'); // to red @@ -354,9 +354,9 @@ function ActionCycleTLWithFTHooks500Times() { const Tl4GA = sm`red 'next' => green 'next' => yellow 'next' => red; [red yellow green] ~> off -> red;`; Tl4GA.set_hook({ handler: () => true, kind: 'global action' }); -function GlobalActionCycleTLWithNamedHooks500Times() { +function GlobalActionCycleTLWithNamedHooks100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4GA.action('next'); // to green Tl4GA.action('next'); // to yellow Tl4GA.action('next'); // to red @@ -387,9 +387,9 @@ Tl4KS.set_hook({ handler: () => true, to: 'red', kind: 'standard transition' }); Tl4KS.set_hook({ handler: () => true, to: 'red', kind: 'main transition' }); Tl4KS.set_hook({ handler: () => true, to: 'red', kind: 'forced transition' }); -function KitchenSink500Times() { +function KitchenSink100Times() { - for (let i=0; i<500; ++i) { + for (let i=0; i<100; ++i) { Tl4GA.transition('green'); Tl4GA.action('next'); // to yellow Tl4GA.force_transition('red'); @@ -403,27 +403,27 @@ function KitchenSink500Times() { b.suite('General performance suite', - b.add('Blind cycle a traffic light 500 times by transition', TransitionCycleTL500Times ), - b.add('Blind cycle a traffic light 500 times by action', ActionCycleTL500Times ), - b.add('Blind cycle a basic-hooked traffic light 500 times by transition', TransitionCycleTLWithHooks500Times ), - b.add('Blind cycle a named-hooked traffic light 500 times by transition', TransitionCycleTLWithNamedHooks500Times ), - b.add('Blind cycle an any-transition traffic light 500 times by transition', TransitionCycleTLWithAnyTransitionHooks500Times ), - b.add('Blind cycle an exit hooked traffic light 500 times by transition', TransitionCycleTLWithExitHooks500Times ), - b.add('Blind cycle an enter hooked traffic light 500 times by transition', TransitionCycleTLWithEnterHooks500Times ), - b.add('Blind cycle a standard-transition hooked light by transition', TransitionCycleTLWithSTHooks500Times ), - b.add('Blind cycle a main-transition hooked light by transition', TransitionCycleTLWithMTHooks500Times ), - b.add('Blind cycle a force-transition hooked light by transition', TransitionCycleTLWithFTHooks500Times ), - b.add('Blind cycle a traffic light 500 times by action', ActionCycleTL500Times ), - b.add('Blind cycle a basic-hooked traffic light 500 times by action', ActionCycleTLWithHooks500Times ), - b.add('Blind cycle a named-hooked traffic light 500 times by action', ActionCycleTLWithNamedHooks500Times ), - b.add('Blind cycle an any-action traffic light 500 times by action', AnyActionCycleTLWithNamedHooks500Times ), - b.add('Blind cycle a global-action traffic light 500 times by action', GlobalActionCycleTLWithNamedHooks500Times ), - b.add('Blind cycle an exit hooked traffic light 500 times by action', ActionCycleTLWithExitHooks500Times ), - b.add('Blind cycle an enter hooked traffic light 500 times by action', ActionCycleTLWithEnterHooks500Times ), - b.add('Blind cycle a standard transition tl 500 times by action', ActionCycleTLWithSTHooks500Times ), - b.add('Blind cycle a main transition tl 500 times by action', ActionCycleTLWithMTHooks500Times ), - b.add('Blind cycle a forced transition tl 500 times by action', ActionCycleTLWithFTHooks500Times ), - b.add('Kitchen Sink 500 times', KitchenSink500Times ), + b.add('Blind cycle a traffic light 100 times by transition', TransitionCycleTL100Times ), + b.add('Blind cycle a traffic light 100 times by action', ActionCycleTL100Times ), + b.add('Blind cycle a basic-hooked traffic light 100 times by transition', TransitionCycleTLWithHooks100Times ), + b.add('Blind cycle a named-hooked traffic light 100 times by transition', TransitionCycleTLWithNamedHooks100Times ), + b.add('Blind cycle an any-transition traffic light 100 times by transition', TransitionCycleTLWithAnyTransitionHooks100Times ), + b.add('Blind cycle an exit hooked traffic light 100 times by transition', TransitionCycleTLWithExitHooks100Times ), + b.add('Blind cycle an enter hooked traffic light 100 times by transition', TransitionCycleTLWithEnterHooks100Times ), + b.add('Blind cycle a standard-transition hooked light by transition', TransitionCycleTLWithSTHooks100Times ), + b.add('Blind cycle a main-transition hooked light by transition', TransitionCycleTLWithMTHooks100Times ), + b.add('Blind cycle a force-transition hooked light by transition', TransitionCycleTLWithFTHooks100Times ), + b.add('Blind cycle a traffic light 100 times by action', ActionCycleTL100Times ), + b.add('Blind cycle a basic-hooked traffic light 100 times by action', ActionCycleTLWithHooks100Times ), + b.add('Blind cycle a named-hooked traffic light 100 times by action', ActionCycleTLWithNamedHooks100Times ), + b.add('Blind cycle an any-action traffic light 100 times by action', AnyActionCycleTLWithNamedHooks100Times ), + b.add('Blind cycle a global-action traffic light 100 times by action', GlobalActionCycleTLWithNamedHooks100Times ), + b.add('Blind cycle an exit hooked traffic light 100 times by action', ActionCycleTLWithExitHooks100Times ), + b.add('Blind cycle an enter hooked traffic light 100 times by action', ActionCycleTLWithEnterHooks100Times ), + b.add('Blind cycle a standard transition tl 100 times by action', ActionCycleTLWithSTHooks100Times ), + b.add('Blind cycle a main transition tl 100 times by action', ActionCycleTLWithMTHooks100Times ), + b.add('Blind cycle a forced transition tl 100 times by action', ActionCycleTLWithFTHooks100Times ), + b.add('Kitchen Sink 100 times', KitchenSink100Times ), b.cycle(), b.complete(), diff --git a/src/ts/jssm.ts b/src/ts/jssm.ts index 59cbc5a6..4c894500 100644 --- a/src/ts/jssm.ts +++ b/src/ts/jssm.ts @@ -1151,6 +1151,38 @@ class Machine { + + + /********* + * + * Lists all edges of a machine. + * + * ```typescript + * const lswitch = sm`on 'toggle' <=> 'toggle' off;`; + * + * lswitch.list_edges(); + * [ + * { + * from: 'on', + * to: 'off', + * kind: 'main', + * forced_only: false, + * main_path: true, + * action: 'toggle' + * }, + * { + * from: 'off', + * to: 'on', + * kind: 'main', + * forced_only: false, + * main_path: true, + * action: 'toggle' + * } + * ] + * ``` + * + */ + list_edges(): Array> { return this._edges; } @@ -1196,16 +1228,66 @@ class Machine { + + + /******** + * + * List all transitions attached to the current state, sorted by entrance and + * exit. The order of each sublist is not defined. A node could appear in + * both lists. + * + * const lswitch = sm`on 'toggle' <=> 'toggle' off;`; + * const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`; + * + * light.state(); // 'red' + * light.list_transitions(); // { entrances: [ 'yellow', 'off' ], exits: [ 'green', 'off' ] } + * + */ + list_transitions(whichState: StateType = this.state()): JssmTransitionList { return { entrances: this.list_entrances(whichState), exits: this.list_exits(whichState) }; } + + + + + /******** + * + * List all entrances attached to the current state. Please note that the + * order of the list is not defined. + * + * const lswitch = sm`on 'toggle' <=> 'toggle' off;`; + * const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`; + * + * light.state(); // 'red' + * light.list_entrances(); // [ 'yellow', 'off' ] + * + */ + list_entrances(whichState: StateType = this.state()): Array { return (this._states.get(whichState) || { from: undefined }).from || []; } + + + + + /******** + * + * List all exits attached to the current state. Please note that the order + * of the list is not defined. + * + * const lswitch = sm`on 'toggle' <=> 'toggle' off;`; + * const light = sm`red 'next' -> green 'next' -> yellow 'next' -> red; [red yellow green] 'shutdown' ~> off 'start' -> red;`; + * + * light.state(); // 'red' + * light.list_exits(); // [ 'green', 'off' ] + * + */ + list_exits(whichState: StateType = this.state()): Array { return (this._states.get(whichState) || { to: undefined }).to @@ -1214,6 +1296,8 @@ class Machine { + + probable_exits_for(whichState: StateType): Array> { const wstate: JssmGenericState = this._states.get(whichState); diff --git a/src/ts/version.ts b/src/ts/version.ts index 32bf1156..f35d565b 100644 --- a/src/ts/version.ts +++ b/src/ts/version.ts @@ -1,3 +1,3 @@ -const version: string = "5.65.10"; +const version: string = "5.65.11"; export { version };