MINT-statemachine 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. data/CHANGES +135 -0
  2. data/LICENSE +16 -0
  3. data/MINT-statemachine.gemspec +27 -0
  4. data/README.rdoc +69 -0
  5. data/Rakefile +88 -0
  6. data/TODO +2 -0
  7. data/lib/statemachine.rb +26 -0
  8. data/lib/statemachine/action_invokation.rb +83 -0
  9. data/lib/statemachine/builder.rb +383 -0
  10. data/lib/statemachine/generate/dot_graph.rb +1 -0
  11. data/lib/statemachine/generate/dot_graph/dot_graph_statemachine.rb +127 -0
  12. data/lib/statemachine/generate/java.rb +1 -0
  13. data/lib/statemachine/generate/java/java_statemachine.rb +265 -0
  14. data/lib/statemachine/generate/src_builder.rb +48 -0
  15. data/lib/statemachine/generate/util.rb +50 -0
  16. data/lib/statemachine/parallelstate.rb +196 -0
  17. data/lib/statemachine/state.rb +102 -0
  18. data/lib/statemachine/statemachine.rb +279 -0
  19. data/lib/statemachine/stub_context.rb +26 -0
  20. data/lib/statemachine/superstate.rb +53 -0
  21. data/lib/statemachine/transition.rb +76 -0
  22. data/lib/statemachine/version.rb +17 -0
  23. data/spec/action_invokation_spec.rb +101 -0
  24. data/spec/builder_spec.rb +243 -0
  25. data/spec/default_transition_spec.rb +111 -0
  26. data/spec/generate/dot_graph/dot_graph_stagemachine_spec.rb +27 -0
  27. data/spec/generate/java/java_statemachine_spec.rb +349 -0
  28. data/spec/history_spec.rb +107 -0
  29. data/spec/noodle.rb +23 -0
  30. data/spec/sm_action_parameterization_spec.rb +99 -0
  31. data/spec/sm_activation_spec.rb +116 -0
  32. data/spec/sm_entry_exit_actions_spec.rb +99 -0
  33. data/spec/sm_odds_n_ends_spec.rb +67 -0
  34. data/spec/sm_parallel_state_spec.rb +207 -0
  35. data/spec/sm_simple_spec.rb +26 -0
  36. data/spec/sm_super_state_spec.rb +55 -0
  37. data/spec/sm_turnstile_spec.rb +76 -0
  38. data/spec/spec_helper.rb +121 -0
  39. data/spec/transition_spec.rb +107 -0
  40. metadata +115 -0
data/CHANGES ADDED
@@ -0,0 +1,135 @@
1
+ = Statemachine Changelog
2
+
3
+ == Version 1.2.2
4
+
5
+ * Transitions can fail
6
+
7
+ == Version 1.2.1
8
+
9
+ * Multiple actions
10
+
11
+ Instead of a single action, multiple actions can be defined for a transition
12
+ by using an array.
13
+
14
+ * Redefinition of states without loosing transitions
15
+
16
+ In a statemachine definition you can pass another statemachine and replace for the
17
+ new statemachine a state with a superstate without loosing the original transitions.
18
+
19
+ Each action that is called during a transaction has to return true for the transition to suceed.
20
+ Otherwise the entire transition is assumed as failed and the statemachine remains in its origin
21
+ state.
22
+
23
+ * Support for GemBundler
24
+
25
+ rake make_spec can be used to create a gemspec file that is required for GemBundler
26
+ integration.
27
+
28
+ == Version 1.1.0
29
+
30
+ DotGraph
31
+ * DotGraph generator was added to generate graphs of statemachines using Omnigraffle.
32
+ * Fixed bug in Java generator where Statenames where not formated correctly.
33
+
34
+ == Version 1.0.0
35
+
36
+ Generator
37
+ * Java generator was added. Statemachines defined in the Ruby DSL can generate Java code.
38
+
39
+ == Version 0.4.2
40
+
41
+ Simple Fixes
42
+ * Fixed respond_to? to handle the, what should be impossible, case when the state is nil
43
+ * Switch history members variable to store id rather than object.
44
+
45
+ == Version 0.4.1
46
+
47
+ Simple Fixes
48
+ * Fixed priority of default transitions, self defaults first, then superstate defaults.
49
+
50
+ == Version 0.4.0
51
+
52
+ Feature enhancements
53
+ * enabled nested superstate history
54
+ * TransitionMissingException's are raised when the statemachine can't respond to an event
55
+ * Statmachine overrides respond_to? to respond to valid events.
56
+
57
+ Behavior Fixes
58
+ * fixed default transition so that superstate transitions have priority over default
59
+
60
+ == Version 0.3.0
61
+
62
+ Feature enhancements
63
+ * added default transitions
64
+ * added default history for superstates
65
+ * the context method in the builder will set the context's statemachine variable if the context respond_to?(:statemachine=)
66
+
67
+ Behavior Fixes
68
+ * the entry action of the startstate is called when the statemachine starts or is reset.
69
+ * resetting the statemachine will reset the history state for each superstate.
70
+
71
+ == Version 0.2.2
72
+
73
+ Minor plugin update
74
+ * introduced before_event and after_event hooks for controllers
75
+
76
+ == Version 0.2.1
77
+
78
+ Rails Plugin.
79
+ * Rails plugin introduced
80
+
81
+ == Version 0.2.0
82
+
83
+ Separation of logic from behavior.
84
+ * Prefered builder syntax implemented
85
+ * statemachine have a context which defines all the behavior
86
+ * startstate can be set at any time in the builder
87
+ * states can be declared without blocks
88
+ * context can be set in builder
89
+
90
+ == Version 0.1.0
91
+
92
+ A new way to build the statemachines
93
+ * cleaner API for running a statemachine
94
+ * much refactoring
95
+ * new API for building statemachine
96
+ * process_event accepts strings
97
+
98
+ == Version 0.0.4
99
+
100
+ Some minor improvements
101
+ * Proper handling of state transition implemented, such that the proper state is set for entry and exit actions.
102
+ * can now use State objects in addition to symbols while creating a transition
103
+ * more compliant implementation of history state
104
+
105
+ == Version 0.0.3
106
+
107
+ Bug fix dealing with entry and exit actions. The state machine's state need to be set to the entered/exited state before calling the
108
+ exit/entry action.
109
+ * added a couple specs in the exit_entry_spec
110
+ * modified state.entered/exited methods to set the state
111
+ * modifed the StateMachine.state to accept state objects.
112
+ * removed running attribute from StateMachine because it wasn't much use
113
+ * also removed the nil (end state)
114
+
115
+ == Version 0.0.2
116
+
117
+ More conventional file structure
118
+ * nothing much to report in terms of changes.
119
+
120
+ == Version 0.0.1
121
+
122
+ 0.0.0 didn't seem to work as a gem so maybe this one will.
123
+
124
+ * nothing really, just playing with rake and release configuration
125
+
126
+ == Version 0.0.0
127
+
128
+ The first release. Most finite state machine features are implemented
129
+ * states
130
+ * transitions
131
+ * transition actions
132
+ * super states
133
+ * entry actions
134
+ * exit actions
135
+ * history state
data/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ Copyright (C) 2010,2011 Sebastian Feuerstack, Jessica Colnago
2
+ Copyright (C) 2006-2010 Micah Martin
3
+
4
+ This library is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU Lesser General Public
6
+ License as published by the Free Software Foundation; either
7
+ version 2.1 of the License, or (at your option) any later version.
8
+
9
+ This library is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public
15
+ License along with this library; if not, write to the Free Software
16
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{MINT-statemachine}
5
+ s.version = "1.2.2"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = [%q{Sebastian Feuerstack}]
9
+ s.date = %q{2011-06-30}
10
+ s.description = %q{The MINT Statemachine is a ruby library for building Finite State Machines, based on the Statemachine gem by Micah Martin.}
11
+ s.email = %q{Sebastian@Feuerstack.org}
12
+ s.files = [%q{Rakefile}, %q{README.rdoc}, %q{CHANGES}, %q{TODO}, %q{LICENSE}, %q{lib/statemachine/generate/java/java_statemachine.rb}, %q{lib/statemachine/generate/src_builder.rb}, %q{lib/statemachine/generate/java.rb}, %q{lib/statemachine/generate/dot_graph.rb}, %q{lib/statemachine/generate/util.rb}, %q{lib/statemachine/generate/dot_graph/dot_graph_statemachine.rb}, %q{lib/statemachine/transition.rb}, %q{lib/statemachine/superstate.rb}, %q{lib/statemachine/version.rb}, %q{lib/statemachine/statemachine.rb}, %q{lib/statemachine/stub_context.rb}, %q{lib/statemachine/state.rb}, %q{lib/statemachine/parallelstate.rb}, %q{lib/statemachine/action_invokation.rb}, %q{lib/statemachine/builder.rb}, %q{lib/statemachine.rb}, %q{spec/sm_turnstile_spec.rb}, %q{spec/generate/java/java_statemachine_spec.rb}, %q{spec/generate/dot_graph/dot_graph_stagemachine_spec.rb}, %q{spec/sm_odds_n_ends_spec.rb}, %q{spec/noodle.rb}, %q{spec/sm_entry_exit_actions_spec.rb}, %q{spec/default_transition_spec.rb}, %q{spec/action_invokation_spec.rb}, %q{spec/sm_parallel_state_spec.rb}, %q{spec/builder_spec.rb}, %q{spec/sm_activation_spec.rb}, %q{spec/sm_super_state_spec.rb}, %q{spec/transition_spec.rb}, %q{spec/spec_helper.rb}, %q{spec/sm_simple_spec.rb}, %q{spec/sm_action_parameterization_spec.rb}, %q{spec/history_spec.rb}]
13
+ s.homepage = %q{http://www.multi-access.de}
14
+ s.require_paths = [%q{lib}]
15
+ s.rubygems_version = %q{1.8.5}
16
+ s.summary = %q{MINT-Statemachine-1.2.2 - Statemachine Library for Ruby based on statemachine from http://slagyr.github.com/statemachine http://www.multi-access.de/open-source-software/third-party-software-extensions/}
17
+ s.test_files = [%q{spec/sm_turnstile_spec.rb}, %q{spec/sm_odds_n_ends_spec.rb}, %q{spec/sm_entry_exit_actions_spec.rb}, %q{spec/default_transition_spec.rb}, %q{spec/action_invokation_spec.rb}, %q{spec/sm_parallel_state_spec.rb}, %q{spec/builder_spec.rb}, %q{spec/sm_activation_spec.rb}, %q{spec/sm_super_state_spec.rb}, %q{spec/transition_spec.rb}, %q{spec/sm_simple_spec.rb}, %q{spec/sm_action_parameterization_spec.rb}, %q{spec/history_spec.rb}]
18
+
19
+ if s.respond_to? :specification_version then
20
+ s.specification_version = 3
21
+
22
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
23
+ else
24
+ end
25
+ else
26
+ end
27
+ end
data/README.rdoc ADDED
@@ -0,0 +1,69 @@
1
+ = MINT Statemachine Gem extensions
2
+
3
+ This branch contains extensions that we implemented as part of the MINT project
4
+ to run multimodal applications.
5
+
6
+ It is based on the great Statemachine Ruby Library, which enables simple creation
7
+ of full-features Finite Statemachines that has been originally developed by Micah Martin.
8
+
9
+ To get started, please look at the documentation on the Statemachine website:
10
+ http://slagyr.github.com/statemachine
11
+
12
+ == Changes
13
+
14
+ === Multiple actions
15
+
16
+ Instead of a single action, multiple actions can be defined for a transition by using an
17
+ array.
18
+
19
+ sm = Statemachine.build do |smb|
20
+ smb.trans :cold, :fire, :hot, [:cook, Proc.new { @tasty = true;true }, "@shape = 'fettucini'"]
21
+ end
22
+
23
+ === Redefinition of states without loosing transitions
24
+
25
+ In a statemachine definition you can pass another statemachine and replace for the
26
+ new statemachine a state with a superstate without loosing the original transitions.
27
+
28
+ In this example the state :unlocked of @old_sm gets replaced by a super state.
29
+
30
+ @sm = Statemachine.build @old_sm do
31
+ superstate :unlocked do
32
+ trans :u1, :u, :u2
33
+ trans :u2, :e, :maintenance
34
+ end
35
+ end
36
+
37
+ === Transitions can fail
38
+
39
+ Each action that is called during a transaction has to return true for the transition to suceed.
40
+ Otherwise the entire transition is assumed as failed and the statemachine remains in its origin
41
+ state.
42
+
43
+ === Support for GemBundler
44
+
45
+ rake make_spec can be used to create a gemspec file that is required for GemBundler
46
+ integration.
47
+
48
+ == Project website
49
+
50
+ http://www.multi-access.de
51
+
52
+ == License
53
+
54
+ Copyright (C) 2010,2011 Sebastian Feuerstack, Jessica Colnago
55
+ Copyright (C) 2006-2010 Micah Martin
56
+
57
+ This library is free software; you can redistribute it and/or
58
+ modify it under the terms of the GNU Lesser General Public
59
+ License as published by the Free Software Foundation; either
60
+ version 2.1 of the License, or (at your option) any later version.
61
+
62
+ This library is distributed in the hope that it will be useful,
63
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
64
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
65
+ Lesser General Public License for more details.
66
+
67
+ You should have received a copy of the GNU Lesser General Public
68
+ License along with this library; if not, write to the Free Software
69
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
data/Rakefile ADDED
@@ -0,0 +1,88 @@
1
+ $:.unshift('lib')
2
+ require 'rubygems'
3
+ require 'rake/gempackagetask'
4
+ require 'rake/clean'
5
+ require 'rake/rdoctask'
6
+ require 'spec/rake/spectask'
7
+ require 'statemachine'
8
+
9
+ PKG_NAME = "MINT-statemachine"
10
+ PKG_VERSION = Statemachine::VERSION::STRING
11
+ PKG_TAG = Statemachine::VERSION::TAG
12
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
13
+ PKG_FILES = FileList[
14
+ '[A-Z]*',
15
+ 'lib/**/*.rb',
16
+ 'spec/**/*.rb'
17
+ ]
18
+
19
+ task :default => :spec
20
+
21
+ desc "Run all specs"
22
+ Spec::Rake::SpecTask.new do |t|
23
+ t.spec_files = FileList['spec/**/*_spec.rb']
24
+ end
25
+
26
+ desc 'Generate RDoc'
27
+ rd = Rake::RDocTask.new do |rdoc|
28
+ rdoc.options << '--title' << 'Statemachine' << '--line-numbers' << '--inline-source' << '--main' << 'README.rdoc'
29
+ rdoc.rdoc_files.include('README.rdoc', 'CHANGES', 'lib/**/*.rb')
30
+ end
31
+ task :rdoc
32
+
33
+ spec = Gem::Specification.new do |s|
34
+ s.name = PKG_NAME
35
+ s.version = PKG_VERSION
36
+ s.summary = Statemachine::VERSION::DESCRIPTION
37
+ s.description = "The MINT Statemachine is a ruby library for building Finite State Machines, based on the Statemachine gem by Micah Martin."
38
+ s.files = PKG_FILES.to_a
39
+ s.require_path = 'lib'
40
+ s.test_files = Dir.glob('spec/*_spec.rb')
41
+ s.require_path = 'lib'
42
+ s.author = "Sebastian Feuerstack"
43
+ s.email = "Sebastian@Feuerstack.org"
44
+ s.homepage = "http://www.multi-access.de"
45
+ end
46
+
47
+ Rake::GemPackageTask.new(spec) do |pkg|
48
+ pkg.need_zip = true
49
+ pkg.need_tar = true
50
+ end
51
+
52
+ def egrep(pattern)
53
+ Dir['**/*.rb'].each do |fn|
54
+ count = 0
55
+ open(fn) do |f|
56
+ while line = f.gets
57
+ count += 1
58
+ if line =~ pattern
59
+ puts "#{fn}:#{count}:#{line}"
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ desc "create a gemspec file"
67
+ task :make_spec do
68
+ File.open("#{PKG_NAME}.gemspec", "w") do |file|
69
+ file.puts spec.to_ruby
70
+ end
71
+ end
72
+
73
+ desc "Look for TODO and FIXME tags in the code"
74
+ task :todo do
75
+ egrep /(FIXME|TODO|TBD)/
76
+ end
77
+
78
+ task :release => [:clobber, :verify_committed, :verify_user, :verify_password, :spec, :publish_packages, :tag, :publish_website, :publish_news]
79
+
80
+ desc "Verifies that there is no uncommitted code"
81
+ task :verify_committed do
82
+ IO.popen('svn stat') do |io|
83
+ io.each_line do |line|
84
+ raise "\n!!! Do a svn commit first !!!\n\n" if line =~ /^\s*M\s*/
85
+ end
86
+ end
87
+ end
88
+
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ Maybe:
2
+ Implement superstate endstate with automatic transition
@@ -0,0 +1,26 @@
1
+ #--
2
+ # Copyright (C) 2006 Micah Martin
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License as published by the Free Software Foundation; either
7
+ # version 2.1 of the License, or (at your option) any later version.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ #++
18
+
19
+ require 'statemachine/action_invokation'
20
+ require 'statemachine/state'
21
+ require 'statemachine/superstate'
22
+ require 'statemachine/parallelstate'
23
+ require 'statemachine/transition'
24
+ require 'statemachine/statemachine'
25
+ require 'statemachine/builder'
26
+ require 'statemachine/version'
@@ -0,0 +1,83 @@
1
+ module Statemachine
2
+
3
+ module ActionInvokation #:nodoc:
4
+
5
+ def invoke_action(action, args, message, messenger, message_queue)
6
+ if !(action.is_a? Array)
7
+ action = [action]
8
+ end
9
+ result = true
10
+ action.each {|a|
11
+ if a.is_a? Symbol
12
+ result = invoke_method(a, args, message)
13
+ elsif a.is_a? Proc
14
+ result = invoke_proc(a, args, message)
15
+ elsif a.is_a? Array
16
+ result = send(a[0],a[1])
17
+ else
18
+ log("#{a}")
19
+ result =invoke_string(a) if not messenger
20
+ end
21
+ return false if result ==false
22
+ }
23
+ result
24
+ end
25
+
26
+ private
27
+
28
+ def send(target,event)
29
+ @message_queue.send(target, event) if @message_queue
30
+ end
31
+
32
+ def log(message)
33
+ @messenger.puts message if @messenger
34
+ end
35
+
36
+ def invoke_method(symbol, args, message)
37
+ method = @context.method(symbol)
38
+ raise StatemachineException.new("No method '#{symbol}' for context. " + message) if not method
39
+
40
+ parameters = params_for_block(method, args, message)
41
+ method.call(*parameters)
42
+ end
43
+
44
+ def invoke_proc(proc, args, message)
45
+ parameters = params_for_block(proc, args, message)
46
+ @context.instance_exec(*parameters, &proc)
47
+ end
48
+
49
+ def invoke_string(expression)
50
+ @context.instance_eval(expression)
51
+ end
52
+
53
+ def params_for_block(block, args, message)
54
+ arity = block.arity
55
+ required_params = arity < 0 ? arity.abs - 1 : arity
56
+
57
+ raise StatemachineException.new("Insufficient parameters. (#{message})") if required_params > args.length
58
+
59
+ return arity < 0 ? args : args[0...arity]
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ class Object
67
+
68
+ module InstanceExecHelper; end
69
+
70
+ include InstanceExecHelper
71
+
72
+ def instance_exec(*args, &block) # !> method redefined; discarding old instance_exec
73
+ mname = "__instance_exec_#{Thread.current.object_id.abs}_#{object_id.abs}"
74
+ InstanceExecHelper.module_eval{ define_method(mname, &block) }
75
+ begin
76
+ ret = send(mname, *args)
77
+ ensure
78
+ InstanceExecHelper.module_eval{ undef_method(mname) } rescue nil
79
+ end
80
+ ret
81
+ end
82
+
83
+ end