lucywang000 / clj-statecharts

State Machine and StateCharts for Clojure(Script)
https://lucywang000.github.io/clj-statecharts/
Eclipse Public License 1.0
229 stars 15 forks source link

What signals does the machine accept given the current state? #13

Open ikitommi opened 2 years ago

ikitommi commented 2 years ago

XState has an api to ask which signals are allowed given the current state:

const { initialState } = lightMachine;

console.log(initialState.nextEvents);
// => ['TIMER', 'EMERGENCY']

This is really important as this information can be used to enable/disable & hide/show action buttons on uis based on their current availability.

I propose clj-statecharts to have a function of machine state -> State, e.g.

(def fsm
  (fsm/machine
   {:id :nested
    :initial :a
    :on {:top {:target :a
               :meta {:ui {:text "restart"}}}}
    :states {:a {:on {:a {:target :a
                          :meta {:ui {:text "nada"}}}
                      :b {:target :b
                          :meta {:ui {:text "goto b"}}}}}
             :b {:on {:c :c}}
             :c {:on {:c :c}}}}))

(fsm/next fsm (fsm/initialize fsm))
;{:top {:target :a
;       :meta {:ui {:text "restart"}}}
; :a {:target :a
;     :meta {:ui {:text "nada"}}}
; :b {:target :b
;     :meta {:ui {:text "goto b"}}}}
lucywang000 commented 2 years ago

I can see the rationale, but atm I myself doesn't have a use case for that. So patches welcome.

Some considerations:

  1. allowed transitions could be from either the leaf state itself, or any of its ancestors.
  2. for transitions withs guards, the guard is going to be evaluated, but I guess this is fine since guards are for most of the time are just pure functions of current state.
ikitommi commented 2 years ago

Thanks. I added this into my preprocessor for clj-statecharts, I can now enrich and precompute things I need, so not in an urgent need of this now at library level. If you want to close this, ok for me. Happy to do a PR at some point, when needs and impls have setteled. Cheers.

ikitommi commented 2 years ago

e.g. have a protocol to both hide the impl and add missing things. Not doing much yet and not sure where it evolves from here.

(defprotocol FSM
  (-id [this])
  (-initial [this])
  (-states [this])
  (-next [this state])
  (-form [this])