https://github.com/danpersa/edge-state-machine
https://github.com/danpersa/edge-state-machine
Last synced: 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/danpersa/edge-state-machine
- Owner: danpersa
- Created: 2011-11-22T22:45:58.000Z (over 13 years ago)
- Default Branch: master
- Last Pushed: 2013-10-11T15:32:07.000Z (over 11 years ago)
- Last Synced: 2025-02-21T20:43:47.300Z (3 months ago)
- Language: Ruby
- Homepage:
- Size: 176 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.rdoc
Awesome Lists containing this project
README
= Edge State Machine
Edge State Machine is a complete state machine solution.
It offers support for ActiveRecord, Mongoid and MongoMapper for persistence.{
}[http://travis-ci.org/danpersa/edge-state-machine]
== Supported Features
* Multiple state machines per class each of them acting independently
* Find errors in state machine definitions as early as possible
* Transition guards
* Multiple actions executed on transitions
* Multiple actions executed on entering and exiting a state
* No other dependencies for non-persistent state machines
* Minimal dependencies for persistent ones== Installation
If you're using Rails + ActiveRecord + Bundler
# in your Gemfile
gem "edge-state-machine", :require => ["edge-state-machine", "active_record/edge-state-machine"]# in your AR models that will use the state machine
include ::EdgeStateMachine
include ActiveRecord::EdgeStateMachinestate_machine do
state :available # first one is initial state
state :out_of_stock
state :discontinueevent :discontinue do
transitions :to => :discontinue, :from => [:available, :out_of_stock], :on_transition => :do_discontinue
end
event :out_of_stock do
transitions :to => :out_of_stock, :from => [:available, :discontinue]
end
event :available do
transitions :to => :available, :from => [:out_of_stock], :on_transition => :send_alerts
end
endIf you're using Rails + Mongoid + Bundler
# in your Gemfile
gem "edge-state-machine", :require => ["edge-state-machine", "mongoid/edge-state-machine"]# in your AR models that will use the state machine
include ::EdgeStateMachine
include Mongoid::EdgeStateMachinestate_machine do
state :available # first one is initial state
state :out_of_stock
state :discontinueevent :discontinue do
transitions :to => :discontinue, :from => [:available, :out_of_stock], :on_transition => :do_discontinue
end
event :out_of_stock do
transitions :to => :out_of_stock, :from => [:available, :discontinue]
end
event :available do
transitions :to => :available, :from => [:out_of_stock], :on_transition => :send_alerts
end
endIf you're using Rails + MongoMapper + Bundler
# in your Gemfile
gem "edge-state-machine", :require => ["edge-state-machine", "mongo_mapper/edge-state-machine"]# in your models that will use the state machine
include ::EdgeStateMachine
include MongoMapper::EdgeStateMachinestate_machine do
state :available # first one is initial state
state :out_of_stock
state :discontinueevent :discontinue do
transitions :to => :discontinue, :from => [:available, :out_of_stock], :on_transition => :do_discontinue
end
event :out_of_stock do
transitions :to => :out_of_stock, :from => [:available, :discontinue]
end
event :available do
transitions :to => :available, :from => [:out_of_stock], :on_transition => :send_alerts
end
end== State Machine Examples
=== Microwave State Machine
class Microwave
state_machine :microwave do # name should be optional, if the name is not present, it should have a default name
# we give state machines names, so we can pun many machines inside a class
initial_state :unplugged # initial state should be optional, if the initial state is not present, the initial state will be the first defined statestate :unplugged
state :plugged
state :door_opened do
enter :light_on # enter should be executed on entering the state
exit :light_off # exit method should be executed on exiting the state
endstate :door_closed
state :started_in_grill_mode do
enter lambda { |t| p "Entering hate" } # should have support for Procs
exit :grill_off
endstate :started do
enter :microwaves_on
exit :microwaves_off
endevent :plug_in do
transition :from => :unplugged, :to => :plugged
endevent :open_door do
transition :from => :plugged, :to => :door_opened
endevent :close_door do
transition :from => :door_opened, :to => :door_closed,
:on_transition => :put_food_in_the_microwave # we can put many actions in an Array for the on_transition parameter
endevent :start do
transition :from => :door_closed, :to => [:started, :started_in_grill_mode],
:on_transition => :start_spinning_the_food,
:guard => :grill_button_pressed? # the method grill_button_pressed? should choose the next state
endevent :stop do
transition :from => [:started, :started_in_grill_mode], :to => :door_closed
end
end
end=== Dice State Machine
class Dice
state_machine do
state :one
state :two
state :three
state :four
state :five
state :sixevent :roll do
transition :from => [:one, :two, :three, :four, :five, :six],
:to => [:one, :two, :three, :four, :five, :six],
:guard => :roll_result,
:on_transition => :display_dice_rolling_animation
end
enddef roll_result
# return one of the states
enddef display_dice_rolling_animation
# draw the new position of the dice
end
endclass User
state_machine do
state :pending # first one is initial state
state :active
state :blocked # the user in this state can't sign inevent :activate do
transition :from => [:pending], :to => :active, :on_transition => :do_activate
endevent :block do
transition :from => [:pending, :active], :to => :blocked
end
end
end=== Other Examples
For other (more complex) examples, please check the following links:
* {Examples without Persistence}[https://github.com/danpersa/edge-state-machine/tree/master/spec/non_persistent/samples]
* {Examples with ActiveRecord}[https://github.com/danpersa/edge-state-machine/tree/master/spec/active_record/samples]
* {Examples with Mongoid}[https://github.com/danpersa/edge-state-machine/tree/master/spec/mongoid/samples]
* {Examples with Mongoid}[https://github.com/danpersa/edge-state-machine/tree/master/spec/mongoid/samples]
* {Examples with MongoMapper}[https://github.com/danpersa/edge-state-machine/tree/master/spec/mongo_mapper/samples]
== NotesFor classes with multiple state machines, the state names, machine names must be unique per class.
The same thing with the event names.
== Credits
The gem is based on Rick Olson's code of ActiveModel::StateMachine,
axed from ActiveModel in {this
commit}[http://github.com/rails/rails/commit/db49c706b62e7ea2ab93f05399dbfddf5087ee0c].And on Krzysiek Heród's gem, {Transitions}[https://github.com/netizer/transitions], which added Mongoid support.