A Cascaded SAM Implementation by Steve Pritchard
The SAM (State-Action-Model) pattern proposed by Jean-Jacques Dubray is explained at sam.js.org
The advance to Jean-Jacques Dubray's SAM pattern presented here is the added notion of cascading the SAM complexes such that they can have a parent/child relationship.
A working Rocket example using this implemenation can be seen at Rocket Example.
The Pause option was added because it added more complexity and permutations to the state machine.
A working cascaded example using the Rocket model as a component can be seen at Missiles Example.
The zipped source code is at download
The github source samcas src
This implementation has the following characteristics:
- The SAM pattern is implemented using 4 classes. SamModel, SamState, SamActions and SamView. When the 4 are linked together they are referred to as
the "Model complex" or "SAM complex" internally and in this document.
- SamState, SamActions and SamView (called the "mold" internally) are readonly classes that are defined using tabular structures with no logic. As such for the most part they
are a templated structure that is filled in with actions, states and the view HTML.
The exception to this tabular design are the functions that may be included in the SamActions class.
Since the mold components are readonly a single instance of each can be shared by multiple instances
of the SamModel class.
- The SamModel instance contains the volatile information. In addition it contains pointers to the associated SamActions, SamState and SamView instances.
If the SamModel is a child it will have a parent pointer.
If a SamModel is a parent it will have a list of child SamModel instances.
- The state of the model is stored in the string strState. This is a deviation from the functional idea expressed by Jean-Jacques Dubray. Using a string means
the current state can be easily shown and tested. In addition, both compile time and runtime validation can more easily be performed.
- A parent communicates via the present method of the child model. A child communicates with the parent using the signal method which results in a present
method call to the parent model.
- The present implementation varies in a few respects from the basic implementation found in the Rocket launcher example.
- It adds a parameter where the caller specifies what state the model is expected to be in. If this is not the case it is rejected as a concurrency error. This was found to be
very useful in rooting out state cominations and actions that were not considered or implemented.
- The step process may or may not change the model state. It will possibly update model variable values. It can also indicate whether the next 3 processes should run with a render=true,nap=true or signal=true flag.
- The render process is only called if the model state changes or the render flag is true.
- The nextAction (nap) process is only called if it exists in the state definition and when the model state changes or the nap flag is true.
- The signal process is only called if it exists in the state definition and when the model state changes or the signal flag is true.
- Strings are used extensively in the implementation to represent state, actions, function references. Futhermore, each string has a 2 byte prefix indication what
type of string it is.
Internal names use a '-' as the 3rd character such as ss-virgin (which is the initial state of a model until the SamModel.activate() method is called).
This prevents name clashes.
- ss - SAM state such as ssActive
- sg - SAM state such as sgClosed
- sa - SAM action such as saDecrement
- fn - SAM function name implementing an action.
- The use of prefixed strings in this way means an editor can easily be used to locate dependencies between various pieces of code.
- The table driven design of the classes would lend itself to being created by a GUI engine (future).
- The support code validates the transitions
- The 'factory' used to build the Model complex validates the complex for inconsistencies such as missing states that are referenced in action codes.
- The HTML is generated from templates in the SamView using a slightly enhanced copy of mustache.js. This enhanced mustache.js code allows for the following.
- Form components to be easily generated that have standard action behavoirs that are easily routed to the right SAM component.
- This design allows for bi-directional modeling between the SamModel value and the form component.
- Parameter validation is performed to root out inconsistencies such as an action name that is not implemented.
- A single HTML template can be varied based on the current model state or can have a comletely dirrent view.
- The CSS can be tightly bound to the view without incurring global intrusions (unless wanted).
- As the model runs it is conceivable to capture and replay the 'events' at the presentation layer. This gives a simple way to test and retest such SAM complexes.