A small design study to show how to implement state specific behavior in nx via per-object mixins ====== # # Implementing state specific behavior via per-object mixins # package require nx package require nx::test # # Class: StateMachine # # Define a minimalistic state machine that will always be initially in # a state named "initial". The states are defined as classes for easy # switching behavior and they are aggregated into the application # class for locality. # nx::Class create StateMachine { :public method current_state {} {:info object mixin classes} :method transition {newState} {:object mixin [:info class]::$newState} :method init {} {:object mixin [:info class]::initial} } # # MetaClass: State # # The meta class provides means for generic state handling (e.g. via # "info instances") and for better describing the intended semantics # of these classes. # nx::Class create State -superclass nx::Class # # Application Class: conference # nx::Class create conference -superclass StateMachine { State create [self]::initial { :public method apply_program_committee {} {return ok} :public method submit_paper {} {return not-yet} :public method publish-cfp {} {:transition cfp-open} } State create [self]::cfp-open { :public method apply_program_committee {} {return too-late} :public method submit_paper {} {return ok} } } conference create tcl2014 ? {tcl2014 current_state} "::conference::initial" ? {tcl2014 apply_program_committee} "ok" ? {tcl2014 submit_paper} "not-yet" tcl2014 publish-cfp ? {tcl2014 current_state} "::conference::cfp-open" ? {tcl2014 apply_program_committee} "too-late" ? {tcl2014 submit_paper} "ok" ====== <> next-scripting