No description, website, or topics provided.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
README.md

README.md

Source mirror; https://github.com/g-pechorin/sstate.scala

Releases (tags) https://github.com/g-pechorin/sstate.scala/tags

	"com.peterlavalle" %% "sstate" % ???

	'com.peterlavalle:sstate_2.12:???'

SState

SState is a cute little pure-functional FSM class in Scala that I wrote after seeing JEasyStates. The only real advantage of mine is that it can (probably) be dropped into a Scala.JS project without any magic.

There's a unit test at the foot of this doc showing how I test it.

terminology

  • machine sort of the class or kind defining the nature of the FSM
  • ghost some value that's carried around by shell objects of the machine
    • ghost values can be changed when the shell reacts to an event
  • shell an instance of a machine which carries a ghost
    • yes; i'm proud of this naming
  • state a state which a shell can be in
    • I use case object in the demo, but, could use case class
  • event something that is/can be sent to the machine to trigger a change
    • I use case object in the demo, but, could use case class

Machines are immutable, so, when replacing a ghost durring a transition there's no way to directly[^indirectRaise] raise another event.

[^indirectRaise]: Various approaches which wrap this system are feasible, but, none are interesting to the author.

usage

  1. create a machine with appropriate generic parameters
  2. add some states with addState(...) so that they can be used in transitions
  3. define what to do on transitions onEvent(...) to define actions to take on transitions
  4. use .transition as a shorthand for situations where the ghost doesn't need to be changed
  5. keep adding events and handlers until you've captured the entirity of the FSM which you're creating
  6. create a shell with apply(...) giving it an initial state and an intial ghost
  7. do what you will with this thing

In theory this system would be super-fun to orchestrate through a DSL or to use as the endpoint of some fearsome threaded goddess.

			// start a new FSM
			Machine[Int, TEvent, TState]()

				// we can be in a state of LOCKED
				.addState(MachineTest.Locked)

				// we can be in a state of UNLOCKED
				.addState(MachineTest.UnLocked)

				// when we're LOCKED, if COIN then become UNLOCKED and modify our ghost
				.onEvent(MachineTest.Locked, MachineTest.Coin, MachineTest.UnLocked)(_ + 1)

				// when we're UNLOCKED, if PUSH, become LOCKED and don't do anything
				.transition(MachineTest.UnLocked, MachineTest.Push, MachineTest.Locked)

				// create an instance of the machine with a ghost=0
				// ... the machine
				.apply(MachineTest.Locked, 0)