MINT-core 1.0.1 → 2.0.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.
Files changed (214) hide show
  1. data/Gemfile +22 -3
  2. data/Gemfile.lock +98 -22
  3. data/History.txt +262 -0
  4. data/LICENSE +30 -0
  5. data/MINT-core.gemspec +25 -80
  6. data/Manifest.txt +145 -30
  7. data/README.rdoc +6 -163
  8. data/Rakefile +16 -17
  9. data/bin/mint-aui +3 -3
  10. data/bin/mint-cui-gfx +3 -2
  11. data/bin/mint-juggernaut.sh +0 -0
  12. data/bin/mint-tuplespace +0 -0
  13. data/lib/MINT-core.rb +53 -15
  14. data/lib/MINT-core/agent/agent.rb +1 -1
  15. data/lib/MINT-core/agent/aui.rb +0 -14
  16. data/lib/MINT-core/agent/auicontrol.rb +91 -38
  17. data/lib/MINT-core/agent/cui-gfx.rb +3 -3
  18. data/lib/MINT-core/agent/cuicontrol.rb +94 -24
  19. data/lib/MINT-core/connector/redis_connector.rb +16 -0
  20. data/lib/MINT-core/manager/mapping_manager.rb +101 -0
  21. data/lib/MINT-core/manager/mapping_parser.rb +89 -0
  22. data/lib/MINT-core/manager/mapping_server.rb +99 -0
  23. data/lib/MINT-core/manager/position_updater.rb +33 -0
  24. data/lib/MINT-core/manager/scxml_client.rb +118 -0
  25. data/lib/MINT-core/manager/scxml_server.rb +86 -0
  26. data/lib/MINT-core/mapping/action/action.rb +32 -0
  27. data/lib/MINT-core/mapping/action/backend_action.rb +32 -0
  28. data/lib/MINT-core/mapping/action/bind_action.rb +88 -0
  29. data/lib/MINT-core/mapping/action/event_action.rb +40 -0
  30. data/lib/MINT-core/mapping/complementary_mapping.rb +31 -0
  31. data/lib/MINT-core/mapping/mapping.rb +170 -34
  32. data/lib/MINT-core/mapping/observation/negation_observation.rb +64 -0
  33. data/lib/MINT-core/mapping/observation/observation.rb +219 -0
  34. data/lib/MINT-core/mapping/sequential.rb +1 -2
  35. data/lib/MINT-core/mapping/sequential_mapping.rb +60 -0
  36. data/lib/MINT-core/model/aui/AIChoiceElement.rb +17 -0
  37. data/lib/MINT-core/model/aui/AICommand.rb +7 -0
  38. data/lib/MINT-core/model/aui/AIContainer.rb +73 -0
  39. data/lib/MINT-core/model/aui/AIContext.rb +12 -0
  40. data/lib/MINT-core/model/aui/AIIN.rb +8 -0
  41. data/lib/MINT-core/model/aui/AIINContinuous.rb +56 -0
  42. data/lib/MINT-core/model/aui/AIINDiscrete.rb +8 -0
  43. data/lib/MINT-core/model/aui/AIMultiChoice.rb +1 -2
  44. data/lib/MINT-core/model/aui/AIMultiChoiceElement.rb +4 -51
  45. data/lib/MINT-core/model/aui/AIO.rb +76 -123
  46. data/lib/MINT-core/model/aui/AIOUT.rb +8 -0
  47. data/lib/MINT-core/model/aui/AIOUTContinuous.rb +61 -0
  48. data/lib/MINT-core/model/aui/AIReference.rb +16 -0
  49. data/lib/MINT-core/model/aui/AISingleChoice.rb +18 -1
  50. data/lib/MINT-core/model/aui/AISingleChoiceElement.rb +10 -56
  51. data/lib/MINT-core/model/aui/AISinglePresence.rb +39 -71
  52. data/lib/MINT-core/model/aui/aicommand.scxml +47 -0
  53. data/lib/MINT-core/model/aui/aicontainer.scxml +41 -0
  54. data/lib/MINT-core/model/aui/aicontext.scxml +34 -0
  55. data/lib/MINT-core/model/aui/aiincontinuous.scxml +59 -0
  56. data/lib/MINT-core/model/aui/aiinrange.scxml +86 -0
  57. data/lib/MINT-core/model/aui/aimultichoice.scxml +67 -0
  58. data/lib/MINT-core/model/aui/aimultichoiceelement.scxml +51 -0
  59. data/lib/MINT-core/model/aui/aio.scxml +18 -27
  60. data/lib/MINT-core/model/aui/aioutcontinuous.scxml +66 -0
  61. data/lib/MINT-core/model/aui/aireference.scxml +28 -0
  62. data/lib/MINT-core/model/aui/aisinglechoice.scxml +60 -0
  63. data/lib/MINT-core/model/aui/aisinglechoiceelement.scxml +45 -60
  64. data/lib/MINT-core/model/aui/aisinglepresence.scxml +15 -24
  65. data/lib/MINT-core/model/aui/model.rb +15 -38
  66. data/lib/MINT-core/model/cui/gfx/CIC.rb +34 -10
  67. data/lib/MINT-core/model/cui/gfx/CIO.rb +66 -115
  68. data/lib/MINT-core/model/cui/gfx/CarouFredSel.scxml +58 -0
  69. data/lib/MINT-core/model/cui/gfx/MarkableRadioButton.rb +8 -0
  70. data/lib/MINT-core/model/cui/gfx/RadioButton.rb +8 -0
  71. data/lib/MINT-core/model/cui/gfx/RadioButtonGroup.rb +6 -0
  72. data/lib/MINT-core/model/cui/gfx/button.rb +16 -0
  73. data/lib/MINT-core/model/cui/gfx/button.scxml +58 -0
  74. data/lib/MINT-core/model/cui/gfx/caroufredsel.rb +48 -0
  75. data/lib/MINT-core/model/cui/gfx/cic.scxml +57 -0
  76. data/lib/MINT-core/model/cui/gfx/cio.scxml +54 -0
  77. data/lib/MINT-core/model/cui/gfx/markableradiobutton.scxml +67 -0
  78. data/lib/MINT-core/model/cui/gfx/model.rb +39 -176
  79. data/lib/MINT-core/model/cui/gfx/radiobutton.scxml +59 -0
  80. data/lib/MINT-core/model/interactor.rb +167 -46
  81. data/lib/MINT-core/model/interactor.scxml +3 -0
  82. data/lib/MINT-core/model/interactor_helpers.rb +25 -0
  83. data/lib/MINT-core/model/ir/body/OneHandPoseNavigation.rb +15 -0
  84. data/lib/MINT-core/model/ir/body/body.rb +5 -0
  85. data/lib/MINT-core/model/ir/body/fingertip.rb +114 -0
  86. data/lib/MINT-core/model/ir/body/fingertip.scxml +43 -0
  87. data/lib/MINT-core/model/{body → ir/body}/gesture_button.rb +0 -0
  88. data/lib/MINT-core/model/ir/body/hand.rb +5 -0
  89. data/lib/MINT-core/model/ir/body/head.rb +102 -0
  90. data/lib/MINT-core/model/ir/body/head.scxml +92 -0
  91. data/lib/MINT-core/model/ir/body/onehandposenavigation.scxml +53 -0
  92. data/lib/MINT-core/model/ir/body/pose.rb +99 -0
  93. data/lib/MINT-core/model/ir/browserscreen.rb +27 -0
  94. data/lib/MINT-core/model/ir/browserscreen.scxml +14 -0
  95. data/lib/MINT-core/model/{device → ir}/button.rb +1 -1
  96. data/lib/MINT-core/model/ir/ir.rb +5 -0
  97. data/lib/MINT-core/model/ir/irmedia.rb +5 -0
  98. data/lib/MINT-core/model/ir/irmode.rb +5 -0
  99. data/lib/MINT-core/model/{device → ir}/joypad.rb +1 -1
  100. data/lib/MINT-core/model/ir/mouse.rb +44 -0
  101. data/lib/MINT-core/model/ir/mouse.scxml +35 -0
  102. data/lib/MINT-core/model/{device/mouse.rb → ir/mouse_old.rb} +2 -2
  103. data/lib/MINT-core/model/{device → ir}/pointer.rb +20 -22
  104. data/lib/MINT-core/model/ir/pointer.scxml +19 -0
  105. data/lib/MINT-core/model/ir/screen.rb +5 -0
  106. data/lib/MINT-core/model/{device → ir}/wheel.rb +1 -1
  107. data/lib/MINT-core/model/mim/aicommand_activate_to_button_press.xml +13 -0
  108. data/lib/MINT-core/model/mim/aicommand_deactivate_to_button_release.xml +13 -0
  109. data/lib/MINT-core/model/mim/aio_defocus_to_cio_unhighlight.xml +13 -0
  110. data/lib/MINT-core/model/mim/aio_focus_to_cio_highlight.xml +14 -0
  111. data/lib/MINT-core/model/mim/aio_present_to_cio_display.xml +14 -0
  112. data/lib/MINT-core/model/mim/aio_suspend_to_cio_hide.xml +13 -0
  113. data/lib/MINT-core/model/mim/aisinglechoice_present_to_child_present.xml +14 -0
  114. data/lib/MINT-core/model/mim/aisinglechoiceelement_chosen_to_radiobutton_select.xml +13 -0
  115. data/lib/MINT-core/model/mim/aisinglechoiceelement_unchosen_to_radiobutton_unselect.xml +13 -0
  116. data/lib/MINT-core/model/mim/aisinglepresence_children_finished_to_caroufredsel_init_js.xml +14 -0
  117. data/lib/MINT-core/model/mim/aisinglepresence_present_to_child_present.xml +15 -0
  118. data/lib/MINT-core/model/mim/browserscreen_reload_to_cuicontrol_refresh_all.xml +12 -0
  119. data/lib/MINT-core/model/mim/button_press_to_aicommand_activate.xml +12 -0
  120. data/lib/MINT-core/model/mim/button_release_to_aicommand_deactivate.xml +12 -0
  121. data/lib/MINT-core/model/mim/caroufredsel_refreshing_to_caroufredsel_init_js.xml +14 -0
  122. data/lib/MINT-core/model/mim/cio_display_to_aio_defocus.xml +13 -0
  123. data/lib/MINT-core/model/mim/cio_display_to_aio_present.xml +12 -0
  124. data/lib/MINT-core/model/mim/cio_display_to_cio_display_cache_add.xml +11 -0
  125. data/lib/MINT-core/model/mim/cio_hide_to_aio_suspend.xml +12 -0
  126. data/lib/MINT-core/model/mim/cio_hide_to_cio_display_cache_remove.xml +12 -0
  127. data/lib/MINT-core/model/mim/cio_highlight_to_aio_focus.xml +13 -0
  128. data/lib/MINT-core/model/mim/head_looking_left_to_aisinglepresence_prev.xml +14 -0
  129. data/lib/MINT-core/model/mim/head_looking_right_to_aisinglepresence_next.xml +15 -0
  130. data/lib/MINT-core/model/mim/head_nodding_to_aisinglepresence_next.xml +15 -0
  131. data/lib/MINT-core/model/mim/head_tilting_left_to_aisinglepresence_prev.xml +14 -0
  132. data/lib/MINT-core/model/mim/head_tilting_right_to_aisinglepresence_next.xml +15 -0
  133. data/lib/MINT-core/model/mim/left_button_aisinglepresence_enter.xml +15 -0
  134. data/lib/MINT-core/model/mim/left_button_aisinglepresence_next.xml +15 -0
  135. data/lib/MINT-core/model/mim/mim_default.xml +52 -0
  136. data/lib/MINT-core/model/mim/mint-mappings.xsd +127 -0
  137. data/lib/MINT-core/model/mim/mouse_press_to_aicommand_activate.xml +17 -0
  138. data/lib/MINT-core/model/mim/mouse_press_to_aisinglechoiceelement_choose.xml +17 -0
  139. data/lib/MINT-core/model/mim/mouse_press_to_aisinglechoiceelement_unchoose.xml +17 -0
  140. data/lib/MINT-core/model/mim/mouse_release_to_aicommand_deactivate.xml +16 -0
  141. data/lib/MINT-core/model/mim/mouse_stop_to_cio_highlight.xml +13 -0
  142. data/lib/MINT-core/model/mim/onehandposnav_confirm_to_aichoiceelement_choose.xml +14 -0
  143. data/lib/MINT-core/model/mim/onehandposnav_next_to_aio_next.xml +14 -0
  144. data/lib/MINT-core/model/mim/onehandposnav_previous_to_aio_prev.xml +14 -0
  145. data/lib/MINT-core/model/mim/radiobutton_selected_to_aisinglechoiceelement_choose.xml +13 -0
  146. data/lib/MINT-core/model/mim/radiobutton_unselected_to_aisinglechoiceelement_unchoose.xml +13 -0
  147. data/lib/MINT-core/model/mim/right_button_aisinglepresence_prev.xml +15 -0
  148. data/lib/MINT-core/model/task.rb +6 -6
  149. data/script/console +0 -0
  150. data/script/destroy +0 -0
  151. data/script/generate +0 -0
  152. data/spec/AICommand_spec.rb +20 -0
  153. data/spec/AIContainer_spec.rb +161 -0
  154. data/spec/AIINContinuous_spec.rb +92 -0
  155. data/spec/AIOUTContinuous_spec.rb +93 -0
  156. data/spec/AIO_spec.rb +73 -0
  157. data/spec/AIReference_spec.rb +105 -0
  158. data/spec/AISinglePresence_spec.rb +204 -60
  159. data/spec/Button_spec.rb +114 -0
  160. data/spec/CIO_spec.rb +145 -0
  161. data/spec/Interactor_spec.rb +95 -0
  162. data/spec/MappingManager_spec.rb +126 -0
  163. data/spec/Spontaneous_spec.rb +53 -0
  164. data/spec/aio_agent_spec.rb +215 -186
  165. data/spec/aisinglechoice_spec.rb +147 -88
  166. data/spec/aisinglechoiceelement_spec.rb +154 -70
  167. data/spec/complementary_mapping_spec.rb +158 -0
  168. data/spec/core_spec.rb +27 -15
  169. data/spec/cui_helper.rb +100 -0
  170. data/spec/examples/browserscreen_reload_to_cuicontrol_refresh_all.xml +12 -0
  171. data/spec/examples/mim_streaming_example.xml +9 -0
  172. data/spec/examples/mouse_highlight.xml +22 -0
  173. data/spec/examples/performance_mapping.xml +15 -0
  174. data/spec/examples/reset_click.xml +24 -0
  175. data/spec/interactor_test.scxml +32 -0
  176. data/spec/interactor_test_2.scxml +16 -0
  177. data/spec/mapping_performance_spec.rb +118 -0
  178. data/spec/mapping_server_spec.rb +161 -0
  179. data/spec/mapping_spec.rb +307 -0
  180. data/spec/music_spec.rb +301 -135
  181. data/spec/performance_counter.scxml +9 -0
  182. data/spec/sequential_mappings_spec.rb +69 -0
  183. data/spec/shared/aio_shared.rb +144 -0
  184. data/spec/spec_helper.rb +22 -3
  185. data/spec/spontaneous.scxml +11 -0
  186. data/spec/support/connection_helper.rb +19 -0
  187. data/spec/support/redis_connector_monkey_patch.rb +1 -0
  188. data/spec/support/statemachine_helper.rb +84 -0
  189. data/spec/sync_mappings_spec.rb +96 -0
  190. metadata +219 -354
  191. data/lib/MINT-core/mapping/complementary.rb +0 -100
  192. data/lib/MINT-core/mapping/on_state_change.rb +0 -65
  193. data/lib/MINT-core/model/aui/AIC.rb +0 -86
  194. data/lib/MINT-core/model/aui/AIChoice.rb +0 -65
  195. data/lib/MINT-core/model/aui/AIINChoose.rb +0 -54
  196. data/lib/MINT-core/model/aui/AIOUTDiscrete.rb +0 -43
  197. data/lib/MINT-core/model/aui/aic.png +0 -0
  198. data/lib/MINT-core/model/aui/aic.scxml +0 -50
  199. data/lib/MINT-core/model/aui/aichoice.png +0 -0
  200. data/lib/MINT-core/model/aui/aichoice.scxml +0 -60
  201. data/lib/MINT-core/model/aui/aio.png +0 -0
  202. data/lib/MINT-core/model/aui/aisinglechoiceelement.png +0 -0
  203. data/lib/MINT-core/model/aui/aisinglepresence.png +0 -0
  204. data/lib/MINT-core/model/body/handgesture.rb +0 -279
  205. data/lib/MINT-core/model/body/head.png +0 -0
  206. data/lib/MINT-core/model/body/head.rb +0 -51
  207. data/lib/MINT-core/model/body/head.scxml +0 -28
  208. data/lib/MINT-core/model/cui/gfx/screen.rb +0 -18
  209. data/lib/MINT-core/overrides/rinda.rb +0 -34
  210. data/spec/AIC_spec.rb +0 -69
  211. data/spec/MINT-core_spec.rb +0 -11
  212. data/spec/aio_spec.rb +0 -144
  213. data/spec/cio_spec.rb +0 -369
  214. data/tasks/rspec.rake +0 -21
@@ -0,0 +1,64 @@
1
+ class NegationObservation < Observation
2
+
3
+ def check_true_at_startup(cb)
4
+ # check if observation is already true at startup
5
+ model = MINT::Interactor.class_from_channel_name(element)
6
+ e = model.get(name)
7
+ p "Error interactor #{name} of class #{model} is not available!" if e.nil?
8
+ e_states= e.states.map &:to_s
9
+ if e
10
+ if ((e_states & states).length == 0) and ((e.abstract_states.split('|') & states).length == 0)
11
+ cb.call element, true, result(MultiJson.decode e.to_json(:only => e.class::PUBLISH_ATTRIBUTES)),id
12
+ return true
13
+ end
14
+ end
15
+ return false
16
+ end
17
+
18
+ def start(observations_results,cb)
19
+ @observation_results=observations_results
20
+
21
+ res = false
22
+
23
+ res = check_true_at_startup(cb) if is_continuous? or is_instant?
24
+
25
+ if not res and is_instant? # instant checks do not require a subscribe and directly fail if false
26
+ fail(cb)
27
+ return self
28
+ end
29
+
30
+ return self if res and is_instant?
31
+
32
+ redis = RedisConnector.redis
33
+ @proc_observation = Proc.new { |key,message|
34
+ if @should_listen
35
+ found=MultiJson.decode message
36
+
37
+ if name.nil? or name.eql? found["name"]
38
+
39
+ if found.has_key? "new_states"
40
+ if (found["new_states"] & states).length==0 # checks if both arrays share no element
41
+
42
+ cb.call element, true , result(found),id
43
+ else
44
+ if (found["states"] & states).length > 0
45
+ cb.call element, false, {},id
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ }
52
+
53
+ if not @cb_observation_has_subscribed
54
+ @should_listen = true
55
+ redis.pubsub.psubscribe("#{element}*",@proc_observation).callback {
56
+ @cb_observation_has_subscribed = true
57
+ call_subscribed_callbacks
58
+ }
59
+ end
60
+ self
61
+ end
62
+
63
+
64
+ end
@@ -0,0 +1,219 @@
1
+ class Observation
2
+
3
+ def initialize(parameters)
4
+ @observation = parameters
5
+
6
+ # state of subscription, to ensure that an observation only subscribes once
7
+ @cb_observation_has_subscribed = false
8
+
9
+ # defines if the ongoing subscription should act or has been temporary disabled using stop
10
+ @should_listen = false
11
+ end
12
+
13
+ def is_continuous?
14
+ @observation[:process].nil? or @observation[:process] == :continuous
15
+ end
16
+
17
+ def is_instant?
18
+ @observation[:process] == :instant
19
+ end
20
+
21
+ def is_onchange?
22
+ @observation[:process] == :onchange
23
+ end
24
+
25
+
26
+ def id
27
+ @observation[:id]
28
+ end
29
+
30
+ def element
31
+ @observation[:element]
32
+ end
33
+
34
+ def states
35
+ @observation[:states].map &:to_s
36
+ end
37
+
38
+ def resultName
39
+ @observation[:result]
40
+ end
41
+
42
+ def result(r)
43
+ if resultName and r
44
+ {resultName => r }
45
+ else
46
+ {}
47
+ end
48
+ end
49
+
50
+ def name
51
+ if @observation[:name] =~ /\./ # check if refers to variable used in sync mappings
52
+ selector = @observation[:name].split "."
53
+ variable = selector.shift
54
+ attributes = selector
55
+ if (@observation_results and @observation_results.has_key? variable)
56
+ interactor_data= @observation_results[variable]
57
+ interactor = MINT::Interactor.get(interactor_data["mint_model"],interactor_data["name"])
58
+
59
+ attributes.each do |attr|
60
+ interactor = interactor.method(attr).call
61
+ end
62
+ return interactor
63
+ end
64
+ else
65
+ return @observation[:name]
66
+ end
67
+ end
68
+
69
+ def check_true_at_startup(cb)
70
+ # check if observation is already true at startup
71
+ model = MINT::Interactor.class_from_channel_name(element)
72
+
73
+ results = nil
74
+ if (name) # if a name is specified, query directly otherwise select by state and return the first one found
75
+ results = []
76
+ r =model.get(model.getModel,name)
77
+ return false if r.nil? # handles the case that the named interactor does not exist!
78
+ results << r
79
+ else
80
+ results = model.all
81
+ end
82
+
83
+ # if no states variable is set, there is no need to filter states
84
+ if states and states.length >0 and results.length > 0
85
+ r = results.find_all { |e|
86
+ ((e.states.map(&:to_s) & states).length>0) or ((e.abstract_states.split('|') & states).length>0)
87
+ }
88
+ else
89
+ r = results
90
+ end
91
+
92
+ if r.length > 0
93
+ if r.length ==1
94
+ cb.call element, true, result(MultiJson.decode r[0].to_json(:only => r[0].class::PUBLISH_ATTRIBUTES)),id
95
+ else
96
+ res = []
97
+ r.each do |e|
98
+ res << MultiJson.decode(e.to_json(:only => e.class::PUBLISH_ATTRIBUTES))
99
+ end
100
+
101
+ cb.call element, true, result(res),id
102
+ end
103
+
104
+ return true
105
+ else
106
+ return false
107
+ end
108
+
109
+ end
110
+
111
+ def stop
112
+ # RedisConnector.redis.pubsub.unsubscribe_proc("#{element}",@proc_observation)
113
+ @should_listen = false
114
+ #@cb_observation_has_subscribed = false
115
+ @subscribed_callbacks = []
116
+ end
117
+
118
+ def fail(cb)
119
+ cb.call element, :fail , nil, id
120
+ end
121
+
122
+ def start(observations_results,cb)
123
+ @observation_results=observations_results
124
+
125
+ if @cb_observation_has_subscribed # restart!!
126
+ @should_listen = true
127
+
128
+ if is_instant?
129
+ fail(cb) if not check_true_at_startup(cb)
130
+ elsif is_continuous?
131
+ check_true_at_startup(cb)
132
+ end
133
+ return self
134
+ end
135
+
136
+ @proc_observation_wo_name = Proc.new { |key, message|
137
+ if @should_listen
138
+ found=MultiJson.decode message
139
+ if name.nil? or name.eql? found["name"]
140
+ if found.has_key? "new_states"
141
+ if (found["new_states"] & states).length>0 # checks if both arrays share at least one element
142
+ cb.call element, true , result(found),id
143
+ else
144
+ if (found["states"] & states).length == 0
145
+ cb.call element, false, {},id
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ }
152
+
153
+ @proc_observation = Proc.new { |message|
154
+ if @should_listen
155
+ found=MultiJson.decode message
156
+ if found.has_key? "new_states"
157
+ if (found["new_states"] & states).length>0 # checks if both arrays share at least one element
158
+ cb.call element, true , result(found),id
159
+ else
160
+ if (found["states"] & states).length == 0
161
+ cb.call element, false, {},id
162
+ end
163
+ end
164
+ end
165
+ end
166
+ }
167
+
168
+ res = false
169
+
170
+ res = check_true_at_startup(cb) if is_continuous? or is_instant?
171
+
172
+ if not res and is_instant? # instant checks do not require a subscribe and directly fail if false
173
+ fail(cb)
174
+ return self
175
+ end
176
+
177
+ if not @cb_observation_has_subscribed
178
+ @should_listen = true
179
+ redis = RedisConnector.redis
180
+
181
+ if (name)
182
+ redis.pubsub.subscribe("#{element}.#{name}",@proc_observation).callback { |count|
183
+ @cb_observation_has_subscribed = true
184
+ call_subscribed_callbacks
185
+ }
186
+ else
187
+ redis.pubsub.psubscribe("#{element}*",@proc_observation_wo_name).callback { |count|
188
+ @cb_observation_has_subscribed = true
189
+ call_subscribed_callbacks
190
+ }
191
+ end
192
+
193
+ end
194
+ self
195
+ end
196
+
197
+
198
+
199
+ # This callback is used to inform that the observation has been successfully subscribed
200
+ def is_subscribed_callback(&block)
201
+ return unless block
202
+
203
+ if @cb_observation_has_subscribed
204
+ block.call(self)
205
+ else
206
+ @subscribed_callbacks ||= []
207
+ @subscribed_callbacks.unshift block # << block
208
+ end
209
+ end
210
+
211
+ def call_subscribed_callbacks
212
+ @subscribed_callbacks ||= []
213
+ while cb = @subscribed_callbacks.pop
214
+ cb.call(self)
215
+ end
216
+ @subscribed_callbacks.clear if @subscribed_callbacks
217
+ end
218
+
219
+ end
@@ -1,6 +1,6 @@
1
1
  module MINT
2
2
 
3
- # click_select_mapping = Sequential.new(HWButton,:pressed,HWButton,:released, 300, { AIINChoose =>"focused"},:choose)
3
+ # click_select_mapping = Sequential.new(HWButton,:pressed,HWButton,:released, 300, { AIChoiceElement =>"focused"},:choose)
4
4
 
5
5
  class Sequential < Mapping
6
6
  def initialize(source_model_1,state_1,source_model_2,state_2, state_2_conditions, min_time, max_time, conditions, error_recovery = nil)
@@ -19,7 +19,6 @@ module MINT
19
19
 
20
20
  def execute
21
21
  t1 = @source_model_1.notify("write", { :new_states=> /(^|\|)#{Regexp.quote(@state_1)}/},self.method(:save_state_1_happened))
22
- p "registered for model #{@source_model_1} writes on state #{@state_1}"
23
22
  # t2 = @source_model_2.notify("write", { :abstract_states=> /#{Regexp.quote(@state_2)}/},self.method(:check_sequence))
24
23
  # p "registered for model #{@source_model_2} writes on state #{@state_2}"
25
24
  return t1
@@ -0,0 +1,60 @@
1
+ module MINT
2
+ class SequentialMapping < ComplementaryMapping
3
+
4
+ @active_observation = nil
5
+
6
+ def start_observations
7
+ @active_observation = 0
8
+
9
+ observations[@active_observation].start(@observation_results,self.method(:cb_activate_action)).is_subscribed_callback { |observation|
10
+ @observation_state[observation.element] = false
11
+ @state_callback.call(@mapping[:name], {:id => observation.id, :state => :activated}) if @state_callback
12
+ call_activated_callbacks
13
+ }
14
+ end
15
+
16
+ # function is called every time an observation has been fulfilled
17
+ def cb_activate_action(element,in_state,result,id)
18
+ # @state_callback.call(@mapping[:name], {:id => id, :state => in_state.to_s.to_sym}) if @state_callback
19
+ @state_callback.call(@mapping[:name], {:id => id, :element => element, :result => result, :state => in_state.to_s.to_sym}) if @state_callback
20
+
21
+ @observation_state[element] = in_state
22
+
23
+ # ignore incoming updates of a previous observation that is still subscribed
24
+ return if not observations[@active_observation].element.eql? element
25
+
26
+ if in_state == :fail
27
+ observations[@active_observation].stop # unsubscribe observation
28
+ restart # restart mapping
29
+ return
30
+ end
31
+ if in_state
32
+ @observation_results.merge! result
33
+ observations[@active_observation].stop # unsubscribe observation
34
+ @active_observation += 1
35
+
36
+ # check if already all other observations have been matched
37
+ if observations.length <= @active_observation
38
+ startAction(@observation_results).actions_succeeded_callback { |m,result|
39
+ state = :failed
40
+ state = :succeeded if result
41
+
42
+ @state_callback.call(@mapping[:name], {:id => @mapping[:id], :mapping_state => state}) if @state_callback
43
+
44
+ # add callback for action if succeeded & implement parallel action execution
45
+ m.restart
46
+
47
+ }
48
+ else # start next observation
49
+ observations[@active_observation].start(@observation_results,self.method(:cb_activate_action))
50
+ end
51
+ end
52
+ end
53
+
54
+ def restart
55
+ @active_observation = 0
56
+ super
57
+ self
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,17 @@
1
+ module MINT
2
+ class AIChoiceElement < AIReference
3
+
4
+ def unchoose_others
5
+ aios = []
6
+ self.parent.children.each do |c|
7
+ if c.is_in? :chosen
8
+ aios << c
9
+ end
10
+ end
11
+ aios.each do |aio|
12
+ aio.process_event("unchoose")
13
+ end
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,7 @@
1
+ module MINT
2
+ class AICommand < AIReference
3
+ def getSCXML
4
+ "#{File.dirname(__FILE__)}/aicommand.scxml"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,73 @@
1
+ module MINT
2
+
3
+ class AIContainer < AIOUT
4
+
5
+ property :children, String
6
+
7
+ def children
8
+ p = super
9
+ result = nil
10
+ if p
11
+ result=[]
12
+ c = p.split("|")
13
+ c.each do |name|
14
+ result << AIO.get(name)
15
+ end
16
+ return result
17
+ else
18
+ []
19
+ end
20
+ []
21
+ end
22
+
23
+ def children= children
24
+ if children.is_a? Array
25
+ a= children.map { |c| c.name if not c.is_a? String}
26
+
27
+ super(a.join("|"))
28
+ else
29
+ super(children)
30
+ end
31
+ end
32
+
33
+ def getSCXML
34
+ "#{File.dirname(__FILE__)}/aicontainer.scxml"
35
+ end
36
+
37
+ def suspend_children
38
+ cs = self.children
39
+ if (cs)
40
+ cs.each do |c|
41
+ c.process_event("suspend")
42
+ end
43
+
44
+ end
45
+ end
46
+
47
+ def present_children
48
+ if (self.children)
49
+ self.children.each do |c|
50
+ c.process_event("present")
51
+ end
52
+
53
+ end
54
+ end
55
+
56
+
57
+ def focus_child
58
+ if (self.children && self.children.first)
59
+ self.children.first.process_event("focus")
60
+ else
61
+ return nil # TODO not working, find abbruchbedingung!!!
62
+ end
63
+ end
64
+
65
+
66
+ # hook that is called from a child if it enters presenting state
67
+ def child_to_presenting(child)
68
+ true
69
+ end
70
+
71
+ end
72
+
73
+ end