MINT-scxml 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,5 +1,5 @@
1
1
  source :rubygems
2
- gem "MINT-statemachine","1.3.0"
2
+ gem "MINT-statemachine", "1.3.2"
3
3
  gem "rspec","2.8.0"
4
4
  gem "rake","0.9.2"
5
5
  gem "hoe", "2.9.6"
@@ -1,7 +1,7 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- MINT-statemachine (1.3.0)
4
+ MINT-statemachine (1.3.2)
5
5
  diff-lcs (1.1.3)
6
6
  hoe (2.9.6)
7
7
  rake (~> 0.8)
@@ -20,7 +20,7 @@ PLATFORMS
20
20
  x86-mingw32
21
21
 
22
22
  DEPENDENCIES
23
- MINT-statemachine (= 1.3.0)
23
+ MINT-statemachine (= 1.3.2)
24
24
  hoe (= 2.9.6)
25
25
  rake (= 0.9.2)
26
26
  rspec (= 2.8.0)
@@ -1,3 +1,12 @@
1
+ === 1.1.2 / 2013-02-28
2
+
3
+ * Another bugfix for spontaneous transitions to parallel states, now depends on MINT-statemachine version 1.3.2
4
+ * improved documentation
5
+
6
+ === 1.1.1 / 2013-02-26
7
+
8
+ * Bugfix for spontaneous transitions to parallel states.
9
+
1
10
  === 1.1.0 / 2012-11-20
2
11
 
3
12
  * (Sebastian) fixed bug: root statemachine was wrongly set for states that are nested inside parallel
@@ -4,36 +4,63 @@
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- This gem implements a state chart XML (SCXML) parser that generates a ruby statemachine.
7
+ This gem implements all core constucts of the state chart XML (SCXML) specification of the W3C.
8
+ (http://www.w3.org/TR/scxml/)
9
+
10
+ Instead of implementing an interpreter, this gem implements a parser that create a ruby statemachine instance based
11
+ on the MINT-statemachine gem (https://github.com/sfeu/statemachine).
8
12
 
9
13
  == FEATURES/PROBLEMS:
10
14
 
11
- * Currently only supports the very basic set of SCXML
15
+ We currently do not support the definition of a data model. Instead the ruby class that contains the statemachine
16
+ instance can be used to store data. Conditions can be defined using ruby inside the SCXML definition and member
17
+ functionc can be called using SCXML script or invoke.
18
+
19
+ == EXAMPLE:
20
+
21
+ Parses an SCXML string and creates a statemachine instance in @sm. The messenger object
22
+ can be used to capture the SCXML log messenges (using the log statement).
23
+
24
+ @messenger = mock("messenger" )
25
+
26
+ parser = StatemachineParser.new(nil,@messenger)
27
+
28
+ scxml = <<EOS
29
+ <scxml name="SCXML" xmlns="http://www.w3.org/2005/07/scxml">
30
+ <state id="state1">
31
+ <transition event="event1" target="state2"/>
32
+ <transition event="event4" target="state2">
33
+ <log expr="transition executing"/>
34
+ </transition>
35
+ </state>
12
36
 
13
- == SYNOPSIS:
37
+ <state id="state2">
38
+ <transition event="event2" target="state3"/>
39
+ </state>
40
+
41
+ <state id="state3">
42
+ <transition event="event3" target="state1"/>
43
+ </state>
44
+ </scxml>
45
+ EOS
46
+
47
+ @sm = parser.build_from_scxml_string scxml
48
+ @sm.reset
14
49
 
15
50
  See tests
16
51
 
17
52
  == REQUIREMENTS:
18
53
 
19
- * Depends on MINT-statemachine gem
54
+ * Depends on MINT-statemachine gem (https://github.com/sfeu/statemachine)
20
55
 
21
56
  == INSTALL:
22
57
 
23
58
  * sudo gem install MINT-scxml
24
59
 
25
- == DEVELOPERS:
26
-
27
- After checking out the source, run:
28
-
29
- $ rake newb
30
-
31
- This task will install any missing dependencies, run the tests/specs,
32
- and generate the RDoc.
33
60
 
34
61
  == LICENSE:
35
62
 
36
- Copyright (C) 2010-2012 Sebastian Feuerstack, Jessica H. Colnago
63
+ Copyright (C) 2010-2013 Sebastian Feuerstack, Jessica H. Colnago
37
64
 
38
65
  This library is free software; you can redistribute it and/or
39
66
  modify it under the terms of the GNU Lesser General Public
@@ -1,5 +1,5 @@
1
1
  class SCXML_MINT
2
- VERSION = '1.1.0'
2
+ VERSION = '1.1.2'
3
3
  end
4
4
 
5
5
  require "MINT-scxml/scxml-parser"
@@ -19,27 +19,59 @@ class StatemachineParser < Statemachine::StatemachineBuilder
19
19
 
20
20
  def initialize(context = nil, logger = nil, queue = nil)
21
21
  super()
22
- @current_transition = nil
23
- @current_state = nil
24
- @current_element = nil
25
- @parallel = nil
26
- @history_state = nil
22
+
27
23
  @statemachine.messenger = logger
28
24
  @statemachine.message_queue = queue
29
25
  @statemachine.context= context
30
- @actions = Array.new
26
+
27
+ # The current variables are used to temporarily store the value of the _"type"
28
+ # in order to acquire the necessary data before adding the to its proper stack
29
+ @current_transition = nil
30
+ @current_state = nil
31
+ @current_element = nil
32
+
33
+ # Stacks
34
+ # These stacks (created as Arrays but used as stacks: push & pop) are used
35
+ # to store and treat the structure of the scxml file read.
36
+ # Some require auxiliary stacks due to the necessity of different treatments
37
+ # in different situations (e.g.: substate_aux is necessary due to the fact that
38
+ # a parallel state's superstate can have substates that would only be treated when
39
+ # the superstate is closed, which only happens after the parallel state is treated.
40
+ # Which in turn can have its own set of substates).
41
+ # Obs: These variables are used as stacks due to two basic situations: the ability of
42
+ # nested elements in statemachines and the need to create a single structure to be
43
+ # passed to element's constructors.
44
+ @actions = Array.new # stores the actions to later be added to the transition they belong.
31
45
  @actions_aux = Array.new
32
- @state = Array.new
33
- @substate = Array.new
34
- @transitions = Array.new
46
+ @state = Array.new # stores the order of nested states to be treated and used further on.
47
+ @substate = Array.new # similar to state, it stores the substates in order to later be added
48
+ # and have the proper transition treatment related to its parent state
49
+ @substate_aux = Array.new
50
+ @transitions = Array.new # stores the transitions in order to be later added to its proper state.
51
+ # so on and so forth.
52
+ @parallel_state = Array.new
35
53
  @history_states = Array.new
36
54
  @history_target = Array.new
37
- @parallel_state = Array.new
55
+
56
+ # These variables are used to store the value of the element that gives its
57
+ # name in order to be used as parameters or "situation check" in future parts
58
+ # of the parser.
59
+ @parallel = nil
60
+ @history_state = nil
61
+
62
+ # These variables are used to help in the creation of actions that have if clauses.
38
63
  @if_actions = Array.new
39
64
  @if_actions_aux = Array.new
40
65
  @if = Array.new
41
66
  @tag = Array.new
42
67
  @cond = Array.new
68
+
69
+ # These boolean variables are used to determine in which case we are on
70
+ # so to treat each case properly.
71
+ # If a history state was read, if inside a parallel state and if it has
72
+ # an outermost scxml_state (the latter implicates on different treatments due
73
+ # to the fact that it is added to the states stack and therefore it might not be
74
+ # empty as expected in certain situations)
43
75
  @history = false
44
76
  @is_parallel = false
45
77
  @scxml_state = false
@@ -104,6 +136,11 @@ class StatemachineParser < Statemachine::StatemachineBuilder
104
136
  end
105
137
  when 'parallel'
106
138
  @is_parallel = true
139
+ # If the parent superstate of the parallel state has substates, save them for later
140
+ if not @substate.empty?
141
+ @substate_aux = @substate
142
+ @substate = []
143
+ end
107
144
  # If there is a state that encapsulates the parallel state, change it to a superstate
108
145
  if not @state.empty? and @state.last.is_a? Statemachine::StateBuilder
109
146
  state = Statemachine::SuperstateBuilder.new(@state.last.subject.id, @state.last.subject.superstate, @state.last.subject.statemachine)
@@ -237,6 +274,8 @@ class StatemachineParser < Statemachine::StatemachineBuilder
237
274
  when 'parallel'
238
275
  @statemachine.add_state(@parallel.subject)
239
276
  @is_parallel = false
277
+ @substate = @substate_aux
278
+ @substate_aux = []
240
279
  when 'state'
241
280
  if @state.last.is_a? Statemachine::SuperstateBuilder
242
281
  s = statemachine.get_state(@state.last.subject.id)
@@ -644,7 +644,112 @@ EOS
644
644
  @sm.disconnect
645
645
  @log.should=="Goodbye cruel world!"
646
646
  end
647
+
648
+
649
+ end
650
+ end
651
+ end
652
+
653
+ describe "with spontaneous transitions to parallel states" do
654
+ it "should enter using spontaneous transitions " do
655
+
656
+ class ActivationCallback
657
+ attr_reader :called
658
+ attr_reader :new_states
659
+ attr_reader :abstract_states
660
+ attr_reader :atomic_states
661
+
662
+ def initialize
663
+ @called = []
664
+ @new_states = []
665
+ @abstract_states = []
666
+ @atomic_states =[]
667
+
668
+ end
669
+ def activate(new_states,abstract_states, atomic_states)
670
+ @called << true
671
+ @new_states<< new_states
672
+ @abstract_states << abstract_states
673
+ @atomic_states << atomic_states
674
+ puts "activate #{@new_states.last} #{@abstract_states.last} #{@atomic_states.last}"
675
+ end
647
676
  end
677
+
678
+ @callback = ActivationCallback.new
679
+
680
+
681
+ def isInstant?
682
+ true
683
+ end
684
+
685
+ def isContinuous?
686
+ true
687
+ end
688
+
689
+ def isOnChange?
690
+ false
691
+ end
692
+
693
+ def evaluate
694
+ true
695
+ end
696
+ parser = StatemachineParser.new(nil,nil)
697
+
698
+ scxml = <<EOS
699
+ <scxml initial="inactive" name="StateObservation" version="0.9" xmlns="http://www.w3.org/2005/07/scxml"><!-- node-size-and-position x=0.0 y=0.0 w=868.0 h=725.0 -->
700
+ <state id="inactive"><!-- node-size-and-position x=180.0 y=40.0 w=80.0 h=50.0 -->
701
+ <transition event="start" target="active"><!-- edge-path [active] x=170.0 y=120.0 pointx=0.0 pointy=-29.0 offsetx=-12.0 offsety=14.0 --></transition>
702
+ </state>
703
+ <state id="active" initial="init"><!-- node-size-and-position x=160.0 y=140.0 w=610.0 h=450.0 -->
704
+ <transition event="stop" target="inactive"></transition>
705
+ <state id="init"><!-- node-size-and-position x=20.0 y=30.0 w=60.0 h=40.0 -->
706
+ <transition cond="isInstant? or isContinuous?" target="instant_evaluation">
707
+ <script>evaluate</script>
708
+ </transition>
709
+ <transition cond="isOnChange?" target="subscribing"></transition>
710
+ </state>
711
+ <state id="instant_evaluation"><!-- node-size-and-position x=180.0 y=30.0 w=130.0 h=40.0 -->
712
+ <transition cond="(not @result.nil?) and @result.length&gt;0" target="true">
713
+ <invoke src="@varmap.merge! @result" type="x-mint"></invoke>
714
+ </transition>
715
+ <transition cond="@result.nil?" target="false"></transition>
716
+ </state>
717
+ <parallel id="running"><!-- node-size-and-position x=40.0 y=130.0 w=480.0 h=300.0 -->
718
+ <state id="result" initial="false"><!-- node-size-and-position x=200.0 y=60.0 w=270.0 h=90.0 -->
719
+ <state id="true"><!-- node-size-and-position x=170.0 y=40.0 w=50.0 h=30.0 -->
720
+ <transition event="false" target="false"></transition>
721
+ </state>
722
+ <state id="false"><!-- node-size-and-position x=10.0 y=40.0 w=80.0 h=30.0 -->
723
+ <transition event="true" target="true"><!-- edge-path [true] x=130.0 y=40.0 pointx=0.0 pointy=14.0 offsetx=17.0 offsety=4.0 --></transition>
724
+ </state>
725
+ </state>
726
+ <state id="subscription" initial="check"><!-- node-size-and-position x=30.0 y=40.0 w=150.0 h=250.0 -->
727
+ <state id="subscribing"><!-- node-size-and-position x=40.0 y=110.0 w=80.0 h=40.0 -->
728
+ <onentry>@subscribed=true</onentry>
729
+ <transition event="subscribed" target="subscribed"></transition>
730
+ </state>
731
+ <state id="subscribed"><!-- node-size-and-position x=40.0 y=190.0 w=80.0 h=40.0 --></state>
732
+ <state id="check"><!-- node-size-and-position x=40.0 y=30.0 w=80.0 h=40.0 -->
733
+ <transition cond="isOnChange? or isContinuous?" target="subscribing"></transition>
734
+ </state>
735
+ </state>
736
+ </parallel>
737
+ </state>
738
+ </scxml>
739
+ EOS
740
+
741
+ @sm = parser.build_from_scxml_string scxml
742
+ @sm.reset
743
+ @sm.activation=@callback.method(:activate)
744
+ @sm.context = self
745
+ @sm.start
746
+
747
+ @callback.called.length.should == 4
748
+
749
+ @callback.new_states[0].should == [:active,:init]
750
+ @callback.new_states[1].should == [:instant_evaluation]
751
+ @callback.new_states[2].should == [:running, :result, :subscription, :false, :check]
752
+ @callback.new_states[3].should == [:subscribing]
648
753
  end
649
754
  end
650
755
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: MINT-scxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-20 00:00:00.000000000Z
12
+ date: 2013-02-28 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: MINT-statemachine
16
- requirement: &73711550 !ruby/object:Gem::Requirement
16
+ requirement: &87413670 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,49 +21,25 @@ dependencies:
21
21
  version: 1.3.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *73711550
25
- - !ruby/object:Gem::Dependency
26
- name: rdoc
27
- requirement: &73710560 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ~>
31
- - !ruby/object:Gem::Version
32
- version: '3.10'
33
- type: :development
34
- prerelease: false
35
- version_requirements: *73710560
36
- - !ruby/object:Gem::Dependency
37
- name: newgem
38
- requirement: &73710050 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: 1.5.3
44
- type: :development
45
- prerelease: false
46
- version_requirements: *73710050
24
+ version_requirements: *87413670
47
25
  - !ruby/object:Gem::Dependency
48
26
  name: hoe
49
- requirement: &73709310 !ruby/object:Gem::Requirement
27
+ requirement: &87413430 !ruby/object:Gem::Requirement
50
28
  none: false
51
29
  requirements:
52
30
  - - ~>
53
31
  - !ruby/object:Gem::Version
54
- version: '3.1'
32
+ version: '2.9'
55
33
  type: :development
56
34
  prerelease: false
57
- version_requirements: *73709310
58
- description: This gem implements a state chart XML (SCXML) parser that generates a
59
- ruby statemachine.
35
+ version_requirements: *87413430
36
+ description: ''
60
37
  email: Sebastian@Feuerstack.org
61
38
  executables: []
62
39
  extensions: []
63
40
  extra_rdoc_files:
64
41
  - History.txt
65
42
  - Manifest.txt
66
- - README.rdoc
67
43
  files:
68
44
  - Gemfile
69
45
  - Gemfile.lock
@@ -102,12 +78,12 @@ files:
102
78
  - statemachines/specs/AISingleChoiceElement_spec.rb
103
79
  - statemachines/specs/AISingleChoice_spec.rb
104
80
  - .gemtest
105
- homepage: http://www.multi-access.de
81
+ homepage:
106
82
  licenses: []
107
83
  post_install_message:
108
84
  rdoc_options:
109
85
  - --main
110
- - README.rdoc
86
+ - README.txt
111
87
  require_paths:
112
88
  - lib
113
89
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -116,6 +92,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
92
  - - ! '>='
117
93
  - !ruby/object:Gem::Version
118
94
  version: '0'
95
+ segments:
96
+ - 0
97
+ hash: -834397197
119
98
  required_rubygems_version: !ruby/object:Gem::Requirement
120
99
  none: false
121
100
  requirements:
@@ -127,6 +106,5 @@ rubyforge_project: MINT-scxml
127
106
  rubygems_version: 1.8.15
128
107
  signing_key:
129
108
  specification_version: 3
130
- summary: This gem implements a state chart XML (SCXML) parser that generates a ruby
131
- statemachine.
109
+ summary: ''
132
110
  test_files: []