MINT-scxml 1.0.0 → 1.1.0
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.
- data/Gemfile +2 -2
- data/Gemfile.lock +12 -4
- data/History.txt +14 -0
- data/MINT-scxml.gemspec +26 -20
- data/Manifest.txt +2 -15
- data/README.rdoc +1 -1
- data/Rakefile +1 -7
- data/lib/MINT-scxml.rb +1 -1
- data/lib/MINT-scxml/scxml-parser.rb +213 -75
- data/spec/if_spec.rb +209 -0
- data/spec/parser_spec.rb +465 -208
- data/spec/spec_helper.rb +1 -1
- data/spec/test_handgestures_spec.rb +2 -1
- data/spec/testmachines/button.scxml +52 -0
- metadata +64 -78
- data/statemachines/aui-scxml/AIC.scxml +0 -26
- data/statemachines/aui-scxml/AICommand.scxml +0 -34
- data/statemachines/aui-scxml/AICommand2.scxml +0 -32
- data/statemachines/aui-scxml/AIO.scxml +0 -25
- data/statemachines/aui/AIC.rb +0 -29
- data/statemachines/aui/AIChoiceElement.rb +0 -32
- data/statemachines/aui/AICommand.rb +0 -34
- data/statemachines/aui/AIIN.rb +0 -7
- data/statemachines/aui/AIINContinous.rb +0 -41
- data/statemachines/aui/AIMultiChoice.rb +0 -46
- data/statemachines/aui/AIMultiChoiceElement.rb +0 -46
- data/statemachines/aui/AIOUTContinous.rb +0 -41
- data/statemachines/aui/AISingleChoice.rb +0 -42
- data/statemachines/aui/AISingleChoiceElement.rb +0 -45
- data/statemachines/aui/aio.rb +0 -28
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,18 +1,26 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
MINT-statemachine (1.
|
4
|
+
MINT-statemachine (1.3.0)
|
5
|
+
diff-lcs (1.1.3)
|
5
6
|
hoe (2.9.6)
|
6
7
|
rake (~> 0.8)
|
7
8
|
rake (0.9.2)
|
8
|
-
rspec (
|
9
|
+
rspec (2.8.0)
|
10
|
+
rspec-core (~> 2.8.0)
|
11
|
+
rspec-expectations (~> 2.8.0)
|
12
|
+
rspec-mocks (~> 2.8.0)
|
13
|
+
rspec-core (2.8.0)
|
14
|
+
rspec-expectations (2.8.0)
|
15
|
+
diff-lcs (~> 1.1.2)
|
16
|
+
rspec-mocks (2.8.0)
|
9
17
|
|
10
18
|
PLATFORMS
|
11
19
|
ruby
|
12
20
|
x86-mingw32
|
13
21
|
|
14
22
|
DEPENDENCIES
|
15
|
-
MINT-statemachine (= 1.
|
23
|
+
MINT-statemachine (= 1.3.0)
|
16
24
|
hoe (= 2.9.6)
|
17
25
|
rake (= 0.9.2)
|
18
|
-
rspec (=
|
26
|
+
rspec (= 2.8.0)
|
data/History.txt
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 1.1.0 / 2012-11-20
|
2
|
+
|
3
|
+
* (Sebastian) fixed bug: root statemachine was wrongly set for states that are nested inside parallel
|
4
|
+
* (Sebastian) added test for spontaneous transitions inside parallel states
|
5
|
+
* (Sebastian) removed old MINT test state machines
|
6
|
+
* (Jessica) transitions now stored as an array
|
7
|
+
* (Jessica) fixed parallel superstate bug
|
8
|
+
* (Jessica) All tests working. Added on_entry, on_exit and transitions for parallel states
|
9
|
+
* (Jessica) added spontaneous transition
|
10
|
+
* (Jessica) WIP: script
|
11
|
+
* (Jessica) added treatment for ifs
|
12
|
+
* (Jessica) fixed history states support and history state tests
|
13
|
+
* (Jessica) Removed unnecessary transitions.
|
14
|
+
|
1
15
|
=== 1.0.0 / 2011-11-01
|
2
16
|
|
3
17
|
* First version
|
data/MINT-scxml.gemspec
CHANGED
@@ -1,35 +1,41 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
5
|
-
s.version = "1.
|
4
|
+
s.name = "MINT-scxml"
|
5
|
+
s.version = "1.1.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
-
s.authors = [
|
9
|
-
s.date =
|
10
|
-
s.description =
|
11
|
-
s.email =
|
12
|
-
s.extra_rdoc_files = [
|
13
|
-
s.files = [
|
14
|
-
s.homepage =
|
15
|
-
s.rdoc_options = [
|
16
|
-
s.require_paths = [
|
17
|
-
s.rubyforge_project =
|
18
|
-
s.rubygems_version =
|
19
|
-
s.summary =
|
8
|
+
s.authors = ["Jessica H. Colnago, Sebastian Feuerstack"]
|
9
|
+
s.date = "2012-11-20"
|
10
|
+
s.description = "This gem implements a state chart XML (SCXML) parser that generates a ruby statemachine."
|
11
|
+
s.email = "Sebastian@Feuerstack.org"
|
12
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
|
13
|
+
s.files = ["Gemfile", "Gemfile.lock", "History.txt", "MINT-scxml.gemspec", "Manifest.txt", "README.rdoc", "Rakefile", "lib/MINT-scxml.rb", "lib/MINT-scxml/scxml-parser.rb", "spec/atm_spec.rb", "spec/if_spec.rb", "spec/parser_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "spec/test_handgestures_spec.rb", "spec/testmachines/atm_enhanced.rb", "spec/testmachines/button.scxml", "spec/testmachines/handgestures-scxmlgui.png", "spec/testmachines/handgestures-scxmlgui.scxml", "spec/testmachines/multiplestates.rb", "spec/testmachines/traffic_light_enhanced.rb", "spec/testmachines/vending_machine1.rb", "spec/testmachines/vending_machine2.rb", "spec/testmachines/vending_machine3.rb", "spec/testmachines/vending_machine4.rb", "spec_helper.rb", "statemachines/AICommand_scxml_spec.rb", "statemachines/AIO_scxml_spec.rb", "statemachines/specs/AICommand_spec.rb", "statemachines/specs/AIINContinous_spec.rb", "statemachines/specs/AIMultiChoiceElement_spec.rb", "statemachines/specs/AIMultiChoice_spec.rb", "statemachines/specs/AIOUTContinous_spec.rb", "statemachines/specs/AIO_spec.rb", "statemachines/specs/AISingleChoiceElement_spec.rb", "statemachines/specs/AISingleChoice_spec.rb", ".gemtest"]
|
14
|
+
s.homepage = "http://www.multi-access.de"
|
15
|
+
s.rdoc_options = ["--main", "README.rdoc"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = "MINT-scxml"
|
18
|
+
s.rubygems_version = "1.8.15"
|
19
|
+
s.summary = "This gem implements a state chart XML (SCXML) parser that generates a ruby statemachine."
|
20
20
|
|
21
21
|
if s.respond_to? :specification_version then
|
22
22
|
s.specification_version = 3
|
23
23
|
|
24
24
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
25
|
-
s.add_runtime_dependency(%q<MINT-statemachine>, ["~> 1.
|
26
|
-
s.add_development_dependency(%q<
|
25
|
+
s.add_runtime_dependency(%q<MINT-statemachine>, ["~> 1.3.0"])
|
26
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.10"])
|
27
|
+
s.add_development_dependency(%q<newgem>, [">= 1.5.3"])
|
28
|
+
s.add_development_dependency(%q<hoe>, ["~> 3.1"])
|
27
29
|
else
|
28
|
-
s.add_dependency(%q<MINT-statemachine>, ["~> 1.
|
29
|
-
s.add_dependency(%q<
|
30
|
+
s.add_dependency(%q<MINT-statemachine>, ["~> 1.3.0"])
|
31
|
+
s.add_dependency(%q<rdoc>, ["~> 3.10"])
|
32
|
+
s.add_dependency(%q<newgem>, [">= 1.5.3"])
|
33
|
+
s.add_dependency(%q<hoe>, ["~> 3.1"])
|
30
34
|
end
|
31
35
|
else
|
32
|
-
s.add_dependency(%q<MINT-statemachine>, ["~> 1.
|
33
|
-
s.add_dependency(%q<
|
36
|
+
s.add_dependency(%q<MINT-statemachine>, ["~> 1.3.0"])
|
37
|
+
s.add_dependency(%q<rdoc>, ["~> 3.10"])
|
38
|
+
s.add_dependency(%q<newgem>, [">= 1.5.3"])
|
39
|
+
s.add_dependency(%q<hoe>, ["~> 3.1"])
|
34
40
|
end
|
35
41
|
end
|
data/Manifest.txt
CHANGED
@@ -8,11 +8,13 @@ Rakefile
|
|
8
8
|
lib/MINT-scxml.rb
|
9
9
|
lib/MINT-scxml/scxml-parser.rb
|
10
10
|
spec/atm_spec.rb
|
11
|
+
spec/if_spec.rb
|
11
12
|
spec/parser_spec.rb
|
12
13
|
spec/spec.opts
|
13
14
|
spec/spec_helper.rb
|
14
15
|
spec/test_handgestures_spec.rb
|
15
16
|
spec/testmachines/atm_enhanced.rb
|
17
|
+
spec/testmachines/button.scxml
|
16
18
|
spec/testmachines/handgestures-scxmlgui.png
|
17
19
|
spec/testmachines/handgestures-scxmlgui.scxml
|
18
20
|
spec/testmachines/multiplestates.rb
|
@@ -24,21 +26,6 @@ spec/testmachines/vending_machine4.rb
|
|
24
26
|
spec_helper.rb
|
25
27
|
statemachines/AICommand_scxml_spec.rb
|
26
28
|
statemachines/AIO_scxml_spec.rb
|
27
|
-
statemachines/aui-scxml/AIC.scxml
|
28
|
-
statemachines/aui-scxml/AICommand.scxml
|
29
|
-
statemachines/aui-scxml/AICommand2.scxml
|
30
|
-
statemachines/aui-scxml/AIO.scxml
|
31
|
-
statemachines/aui/AIC.rb
|
32
|
-
statemachines/aui/AIChoiceElement.rb
|
33
|
-
statemachines/aui/AICommand.rb
|
34
|
-
statemachines/aui/AIIN.rb
|
35
|
-
statemachines/aui/AIINContinous.rb
|
36
|
-
statemachines/aui/AIMultiChoice.rb
|
37
|
-
statemachines/aui/AIMultiChoiceElement.rb
|
38
|
-
statemachines/aui/AIOUTContinous.rb
|
39
|
-
statemachines/aui/AISingleChoice.rb
|
40
|
-
statemachines/aui/AISingleChoiceElement.rb
|
41
|
-
statemachines/aui/aio.rb
|
42
29
|
statemachines/specs/AICommand_spec.rb
|
43
30
|
statemachines/specs/AIINContinous_spec.rb
|
44
31
|
statemachines/specs/AIMultiChoiceElement_spec.rb
|
data/README.rdoc
CHANGED
@@ -33,7 +33,7 @@ and generate the RDoc.
|
|
33
33
|
|
34
34
|
== LICENSE:
|
35
35
|
|
36
|
-
Copyright (C) 2010
|
36
|
+
Copyright (C) 2010-2012 Sebastian Feuerstack, Jessica H. Colnago
|
37
37
|
|
38
38
|
This library is free software; you can redistribute it and/or
|
39
39
|
modify it under the terms of the GNU Lesser General Public
|
data/Rakefile
CHANGED
@@ -16,16 +16,10 @@ Hoe.plugin :newgem
|
|
16
16
|
Hoe.spec 'MINT-scxml' do
|
17
17
|
self.developer 'Jessica H. Colnago, Sebastian Feuerstack', 'Sebastian@Feuerstack.org'
|
18
18
|
self.rubyforge_name = self.name # TODO this is default value
|
19
|
-
self.extra_deps = [['MINT-statemachine','~> 1.
|
19
|
+
self.extra_deps = [['MINT-statemachine','~> 1.3.0']]
|
20
20
|
self.email = "Sebastian@Feuerstack.org"
|
21
21
|
|
22
|
-
# HEY! If you fill these out in ~/.hoe_template/Rakefile.erb then
|
23
|
-
# you'll never have to touch them again!
|
24
|
-
# (delete this comment too, of course)
|
25
22
|
|
26
|
-
# developer('FIX', 'FIX@example.com')
|
27
|
-
|
28
|
-
# self.rubyforge_name = 'scxml-gemx' # if different than 'scxml-gem'
|
29
23
|
end
|
30
24
|
|
31
25
|
# vim: syntax=ruby
|
data/lib/MINT-scxml.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
# -*- coding: raw-text -*-
|
2
1
|
require 'rubygems'
|
3
2
|
require "bundler/setup"
|
4
3
|
require 'statemachine'
|
@@ -20,98 +19,164 @@ class StatemachineParser < Statemachine::StatemachineBuilder
|
|
20
19
|
|
21
20
|
def initialize(context = nil, logger = nil, queue = nil)
|
22
21
|
super()
|
23
|
-
@actions = Array.new
|
24
22
|
@current_transition = nil
|
25
23
|
@current_state = nil
|
26
24
|
@current_element = nil
|
27
25
|
@parallel = nil
|
28
|
-
@
|
26
|
+
@history_state = nil
|
29
27
|
@statemachine.messenger = logger
|
30
28
|
@statemachine.message_queue = queue
|
31
29
|
@statemachine.context= context
|
30
|
+
@actions = Array.new
|
31
|
+
@actions_aux = Array.new
|
32
|
+
@state = Array.new
|
32
33
|
@substate = Array.new
|
33
34
|
@transitions = Array.new
|
34
35
|
@history_states = Array.new
|
35
36
|
@history_target = Array.new
|
36
|
-
@
|
37
|
+
@parallel_state = Array.new
|
38
|
+
@if_actions = Array.new
|
39
|
+
@if_actions_aux = Array.new
|
40
|
+
@if = Array.new
|
41
|
+
@tag = Array.new
|
42
|
+
@cond = Array.new
|
37
43
|
@history = false
|
38
44
|
@is_parallel = false
|
39
45
|
@scxml_state = false
|
40
|
-
@parallel_state = Array.new
|
41
46
|
end
|
42
47
|
|
48
|
+
# This function parses scxml from a file
|
43
49
|
def build_from_scxml(filename)
|
44
50
|
source = File.new filename
|
45
51
|
Document.parse_stream(source, self)
|
46
|
-
|
47
|
-
|
52
|
+
#@statemachine.reset
|
53
|
+
@statemachine
|
48
54
|
end
|
49
55
|
|
50
|
-
# parses scxml directly from string parameter stringbuffer
|
56
|
+
# This function parses scxml directly from the string parameter "stringbuffer"
|
51
57
|
def build_from_scxml_string(stringbuffer)
|
52
58
|
Document.parse_stream(stringbuffer, self)
|
53
|
-
|
54
|
-
|
59
|
+
#@statemachine.reset
|
60
|
+
@statemachine
|
55
61
|
end
|
56
62
|
|
63
|
+
|
64
|
+
# This function deals with the different scenarios for the creation of actions with if
|
65
|
+
def creating_ifs
|
66
|
+
if @if.size == 1
|
67
|
+
@if_actions.push(@if_actions_aux.last) if @if_actions_aux.size != 0
|
68
|
+
if @actions_aux.size != 0
|
69
|
+
@actions_aux.each do |j|
|
70
|
+
@if_actions.push(j)
|
71
|
+
end
|
72
|
+
@actions_aux = []
|
73
|
+
end
|
74
|
+
@actions.push([@tag.last, @cond.last, @if_actions])
|
75
|
+
else
|
76
|
+
if @if_actions.size != 0
|
77
|
+
@if_actions_aux.push(@if_actions)
|
78
|
+
end
|
79
|
+
@actions_aux.push([@tag.last, @cond.last, @if_actions_aux.last])
|
80
|
+
end
|
81
|
+
@if_actions = []
|
82
|
+
@cond.pop
|
83
|
+
@tag.pop
|
84
|
+
@if_actions_aux.pop if @if_actions_aux.size != 0
|
85
|
+
end
|
86
|
+
|
87
|
+
# This function defines the actions to be taken for each different tag when the tag is opened
|
57
88
|
def tag_start(name, attributes)
|
58
89
|
case name
|
59
90
|
when 'scxml'
|
91
|
+
# If the initial tag <scxml> has a n ame attribute, define it as the most outer super state
|
60
92
|
if attributes['name']
|
61
93
|
@scxml_state = true
|
62
|
-
state = nil
|
63
94
|
@current_state = State.new
|
64
|
-
@current_state.id = attributes['
|
95
|
+
@current_state.id = attributes['id']
|
65
96
|
@current_state.initial = attributes['initial']
|
66
97
|
state = Statemachine::SuperstateBuilder.new(attributes['name'].to_sym, @subject, @statemachine)
|
67
|
-
|
98
|
+
# If the current state has an initial state defined, add it to the state created.
|
99
|
+
if @current_state.initial != nil
|
68
100
|
state.startstate(@current_state.initial.to_sym)
|
69
101
|
end
|
102
|
+
# Adds it to a list of "open" states
|
70
103
|
@state.push(state)
|
71
104
|
end
|
72
105
|
when 'parallel'
|
73
|
-
@parallel = Statemachine::ParallelStateBuilder.new(attributes['id'].to_sym, @subject, @statemachine)
|
74
106
|
@is_parallel = true
|
75
107
|
# If there is a state that encapsulates the parallel state, change it to a superstate
|
76
|
-
if
|
77
|
-
|
78
|
-
|
79
|
-
|
108
|
+
if not @state.empty? and @state.last.is_a? Statemachine::StateBuilder
|
109
|
+
state = Statemachine::SuperstateBuilder.new(@state.last.subject.id, @state.last.subject.superstate, @state.last.subject.statemachine)
|
110
|
+
@state.pop # pops the old one
|
111
|
+
@state.push(state) # pushes the new one
|
112
|
+
end
|
113
|
+
if @state.empty?
|
114
|
+
@parallel = Statemachine::ParallelStateBuilder.new(attributes['id'].to_sym, @subject, @statemachine)
|
115
|
+
else
|
116
|
+
@parallel = Statemachine::ParallelStateBuilder.new(attributes['id'].to_sym, @state.last.subject, @statemachine)
|
80
117
|
end
|
118
|
+
|
81
119
|
when 'state'
|
82
120
|
@current_state = State.new
|
83
121
|
@current_state.id = attributes['id']
|
84
122
|
@current_state.initial = attributes['initial']
|
85
|
-
if
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
state = Statemachine::StateBuilder.new(attributes['id'].to_sym, @subject, @statemachine)
|
91
|
-
end
|
92
|
-
else # It is a substate
|
93
|
-
if (@current_state.initial != nil) # AND it is a superstate
|
94
|
-
state = Statemachine::SuperstateBuilder.new(attributes['id'].to_sym, @state.last.subject, @statemachine)
|
123
|
+
if @state.empty?
|
124
|
+
# It is not a substate
|
125
|
+
if @current_state.initial != nil
|
126
|
+
# and it is a superstate
|
127
|
+
state = Statemachine::SuperstateBuilder.new(attributes['id'].to_sym, @subject, @statemachine)
|
95
128
|
state.startstate(@current_state.initial.to_sym)
|
96
|
-
else
|
97
|
-
|
129
|
+
else
|
130
|
+
# and it is a state
|
131
|
+
state = Statemachine::StateBuilder.new(attributes['id'].to_sym, @subject, @statemachine)
|
132
|
+
end
|
133
|
+
else
|
134
|
+
#It is a substate
|
135
|
+
if @state.last.is_a? Statemachine::StateBuilder
|
136
|
+
# Its parent is not a superstate yet
|
137
|
+
if @is_parallel and @parallel_state.empty?
|
138
|
+
state = Statemachine::SuperstateBuilder.new(@state.last.subject.id, @parallel.subject, @state.last.subject.statemachine)
|
139
|
+
else
|
98
140
|
state = Statemachine::SuperstateBuilder.new(@state.last.subject.id, @state.last.subject.superstate, @state.last.subject.statemachine)
|
99
|
-
@state.pop # pops the old one
|
100
|
-
@state.push(state) # pushes the new one
|
101
|
-
if @is_parallel
|
102
|
-
@parallel_state.pop
|
103
|
-
@parallel_state.push(state)
|
104
|
-
end
|
105
141
|
end
|
106
|
-
state
|
142
|
+
@state.pop # pops the old one
|
143
|
+
@state.push(state) # pushes the new one
|
144
|
+
if @is_parallel
|
145
|
+
@parallel_state.pop
|
146
|
+
@parallel_state.push(state)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
if @current_state.initial != nil
|
150
|
+
# and it is a superstate
|
151
|
+
if @is_parallel and @parallel_state.empty?
|
152
|
+
state = Statemachine::SuperstateBuilder.new(attributes['id'].to_sym, @parallel.subject, @statemachine)
|
153
|
+
else
|
154
|
+
state = Statemachine::SuperstateBuilder.new(attributes['id'].to_sym, @state.last.subject, @statemachine)
|
155
|
+
end
|
156
|
+
state.startstate(@current_state.initial.to_sym)
|
157
|
+
else
|
158
|
+
# and it is a state
|
159
|
+
if @is_parallel and @parallel_state.empty?
|
160
|
+
state = Statemachine::StateBuilder.new(attributes['id'].to_sym, @parallel.subject, @statemachine)
|
161
|
+
else
|
162
|
+
state = Statemachine::StateBuilder.new(attributes['id'].to_sym, @state.last.subject, @statemachine)
|
163
|
+
end
|
107
164
|
end
|
108
165
|
end
|
109
166
|
@state.push(state)
|
110
167
|
@parallel_state.push(state) if @is_parallel
|
111
168
|
when 'transition'
|
112
169
|
@current_transition = Transition.new
|
113
|
-
|
114
|
-
|
170
|
+
if attributes['target'] == @history_state.to_s and @history_state
|
171
|
+
@current_transition.target = attributes['target']+"_H"
|
172
|
+
else
|
173
|
+
@current_transition.target = attributes['target']
|
174
|
+
end
|
175
|
+
if attributes['event']
|
176
|
+
@current_transition.event = attributes['event']
|
177
|
+
else
|
178
|
+
@current_transition.event = nil
|
179
|
+
end
|
115
180
|
if attributes['cond']
|
116
181
|
@current_transition.cond = attributes['cond']
|
117
182
|
else
|
@@ -121,74 +186,108 @@ class StatemachineParser < Statemachine::StatemachineBuilder
|
|
121
186
|
when 'onentry'
|
122
187
|
when 'onexit'
|
123
188
|
when 'history'
|
124
|
-
@history=true
|
189
|
+
@history = true
|
125
190
|
@history_states.push(@state.last.subject.id)
|
126
191
|
@history_state = @state.last.subject.id
|
192
|
+
when 'if'
|
193
|
+
@if.push(true)
|
194
|
+
if @if.size >= 1
|
195
|
+
@if_actions_aux.push(@if_actions) if @if_actions.size != 0
|
196
|
+
@if_actions = []
|
197
|
+
end
|
198
|
+
@cond.push(attributes['cond'])
|
199
|
+
@tag.push("if")
|
200
|
+
when 'elseif'
|
201
|
+
creating_ifs
|
202
|
+
@cond.push(attributes['cond'])
|
203
|
+
@tag.push("elseif")
|
204
|
+
when 'else'
|
205
|
+
creating_ifs
|
206
|
+
@cond.push(true)
|
207
|
+
@tag.push("else")
|
127
208
|
when 'log'
|
128
|
-
@
|
209
|
+
if @if.last
|
210
|
+
@if_actions.push(["log", attributes['expr']])
|
211
|
+
else
|
212
|
+
@actions.push(["log", attributes['expr']])
|
213
|
+
end
|
129
214
|
when 'send'
|
130
|
-
@
|
215
|
+
if @if.last
|
216
|
+
@if_actions.push(["send", attributes['target'], attributes['event']])
|
217
|
+
else
|
218
|
+
@actions.push(["send", attributes['target'], attributes['event']])
|
219
|
+
end
|
131
220
|
when 'invoke'
|
132
|
-
@
|
221
|
+
if @if.last
|
222
|
+
@if_actions.push(["invoke", attributes['src'].to_sym])
|
223
|
+
else
|
224
|
+
@actions.push(["invoke", attributes['src'].to_sym])
|
225
|
+
end
|
226
|
+
when 'script'
|
227
|
+
@script = true
|
228
|
+
@script_code = ""
|
133
229
|
else
|
134
230
|
@current_element = name
|
135
|
-
|
231
|
+
end
|
136
232
|
end
|
137
233
|
|
234
|
+
# This function defines the actions to be taken for each different tag when the tag is closed
|
138
235
|
def tag_end(name)
|
139
236
|
case name
|
140
237
|
when 'parallel'
|
141
238
|
@statemachine.add_state(@parallel.subject)
|
142
239
|
@is_parallel = false
|
143
240
|
when 'state'
|
144
|
-
if
|
241
|
+
if @state.last.is_a? Statemachine::SuperstateBuilder
|
145
242
|
s = statemachine.get_state(@state.last.subject.id)
|
146
243
|
|
147
|
-
# Changing the state's id
|
148
244
|
if (s.id == @history_state)
|
149
|
-
|
150
|
-
|
151
|
-
|
245
|
+
if @history_target.last
|
246
|
+
s.default_history = @history_target.last.to_sym
|
247
|
+
@history_target.pop
|
248
|
+
end
|
152
249
|
end
|
153
250
|
|
154
|
-
#
|
155
|
-
@substate.each
|
156
|
-
if
|
251
|
+
# Every state belonging to this superstate should respond to the superstate's transitions
|
252
|
+
@substate.each do |j|
|
253
|
+
if s
|
157
254
|
s1 = statemachine.get_state(j.subject.id)
|
158
|
-
s.transitions.each
|
159
|
-
if
|
160
|
-
|
161
|
-
end
|
162
|
-
}
|
255
|
+
s.transitions.each do |k|
|
256
|
+
s1.add(k) if s1
|
257
|
+
end
|
163
258
|
end
|
164
|
-
|
259
|
+
end
|
165
260
|
end
|
261
|
+
|
166
262
|
# In case of parallel statemachines the outmost states will become parallel statemachines
|
167
263
|
# only considering parallel on a root level
|
168
|
-
|
169
264
|
if @parallel_state.size == 1 and @parallel.is_a? Statemachine::ParallelStateBuilder
|
170
|
-
statemachine_aux = Statemachine::Statemachine.new(@
|
265
|
+
statemachine_aux = Statemachine::Statemachine.new(@parallel.subject)
|
266
|
+
statemachine_aux.add_state(@parallel_state.last.subject)
|
267
|
+
@statemachine.remove_state(@parallel_state.last.subject)
|
171
268
|
@substate.each do |j|
|
269
|
+
j.subject.modify_statemachine(statemachine_aux)
|
172
270
|
statemachine_aux.add_state(j.subject)
|
173
271
|
@statemachine.remove_state(j.subject)
|
174
272
|
end
|
175
|
-
statemachine_aux.reset
|
273
|
+
#statemachine_aux.reset
|
176
274
|
@parallel.subject.add_statemachine(statemachine_aux)
|
177
275
|
end
|
276
|
+
|
178
277
|
@substate.push(@state.last)
|
179
278
|
|
180
279
|
if (@state.size == 1 and not @scxml_state) or (@state.size == 2 and @scxml_state) or (@parallel_state.size == 1)
|
181
280
|
@substate = []
|
182
281
|
# TODO make this better. Too inefficient
|
183
|
-
while
|
282
|
+
while @history_states.size != 0
|
184
283
|
# change every transitions where @history_states.last was the target state to history_states.last+"_H"
|
185
284
|
# for every history state
|
186
285
|
@statemachine.states.each_value do |s|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
286
|
+
s.transitions.each do |t|
|
287
|
+
if t.destination_id == @history_states.last
|
288
|
+
t.destination_id = (t.destination_id.to_s + "_H").to_s
|
289
|
+
end
|
290
|
+
end
|
192
291
|
end
|
193
292
|
@history_states.pop
|
194
293
|
end
|
@@ -196,30 +295,69 @@ class StatemachineParser < Statemachine::StatemachineBuilder
|
|
196
295
|
@state.pop
|
197
296
|
@parallel_state.pop if @is_parallel
|
198
297
|
when 'transition'
|
199
|
-
if
|
298
|
+
if @transitions.last.event == nil
|
200
299
|
if @history
|
201
300
|
@history_target.push(@transitions.last.target)
|
202
301
|
@history = false
|
203
302
|
else
|
204
|
-
|
303
|
+
if @is_parallel and @parallel_state.empty?
|
304
|
+
@parallel.event(nil, @transitions.last.target.to_sym, @actions, @transitions.last.cond)
|
305
|
+
else
|
306
|
+
@state.last.event(nil, @transitions.last.target.to_sym, @actions, @transitions.last.cond)
|
307
|
+
end
|
205
308
|
end
|
206
309
|
else
|
207
|
-
if
|
208
|
-
|
209
|
-
|
210
|
-
|
310
|
+
if @transitions.last.target != nil
|
311
|
+
if @is_parallel and @parallel_state.empty?
|
312
|
+
@parallel.event(@transitions.last.event.to_sym, @transitions.last.target.to_sym, @actions, @transitions.last.cond)
|
313
|
+
else
|
314
|
+
@state.last.event(@transitions.last.event.to_sym, @transitions.last.target.to_sym, @actions, @transitions.last.cond)
|
315
|
+
end
|
316
|
+
else
|
317
|
+
# if it doesn't have a target state, it is its own target state
|
318
|
+
if @is_parallel and @parallel_state.empty?
|
319
|
+
@parallel.event(@transitions.last.event.to_sym, @state.last.subject.id.to_sym, @actions, @transitions.last.cond)
|
320
|
+
else
|
321
|
+
@state.last.event(@transitions.last.event.to_sym, @state.last.subject.id.to_sym, @actions, @transitions.last.cond)
|
322
|
+
end
|
211
323
|
end
|
212
324
|
end
|
213
325
|
@actions=[]
|
214
326
|
@transitions.pop
|
215
327
|
when 'onentry'
|
216
|
-
@
|
328
|
+
if @is_parallel and @parallel_state.empty?
|
329
|
+
@parallel.on_entry(@actions)
|
330
|
+
else
|
331
|
+
@state.last.on_entry(@actions)
|
332
|
+
end
|
217
333
|
@actions=[]
|
218
334
|
when 'onexit'
|
219
|
-
@
|
335
|
+
if @is_parallel and @parallel_state.empty?
|
336
|
+
@parallel.on_exit(@actions)
|
337
|
+
else
|
338
|
+
@state.last.on_exit(@actions)
|
339
|
+
end
|
220
340
|
@actions=[]
|
221
341
|
when 'history'
|
222
342
|
@history = false
|
343
|
+
when 'if'
|
344
|
+
creating_ifs
|
345
|
+
@if.pop
|
346
|
+
when 'script'
|
347
|
+
@script = false
|
348
|
+
if @if.last
|
349
|
+
@if_actions.push(["script", @script_code])
|
350
|
+
else
|
351
|
+
@actions.push(["script", @script_code])
|
352
|
+
end
|
353
|
+
else
|
354
|
+
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def text(text)
|
359
|
+
if @script
|
360
|
+
@script_code += text
|
223
361
|
end
|
224
362
|
end
|
225
363
|
|