MINT-core 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,86 @@
1
+
2
+ require 'rubygems'
3
+ require "bundler/setup"
4
+ require "MINT-core"
5
+ require "MINT-scxml"
6
+
7
+ class SCXMLServer
8
+ attr_accessor :connections
9
+ attr_accessor :manager
10
+
11
+ class StatefulProtocol < EventMachine::Connection
12
+ include EM::Protocols::LineText2
13
+ attr_accessor :manager
14
+
15
+ def initialize
16
+ super()
17
+ end
18
+
19
+ def subscribe_redis(interactor,name)
20
+ @interactor = interactor
21
+ @name = name
22
+
23
+ redis = EventMachine::Hiredis.connect
24
+
25
+ redis.pubsub.psubscribe(@interactor) { |key, message|
26
+
27
+ found=MultiJson.decode message
28
+ if @name.nil? or @name.eql? found["name"]
29
+ if found.has_key? "new_states"
30
+ # send new state
31
+ found["new_states"].each { |state|
32
+ p "activated: #{state}"
33
+ send_active_state state }
34
+ end
35
+
36
+ if(@state_store[key])
37
+ activated_states = @state_store[key]
38
+
39
+ current_active_states = found["states"] + found["abstract_states"]
40
+
41
+ deactivated_states = activated_states - current_active_states
42
+
43
+ # send deactivate states
44
+
45
+ deactivated_states.each {|state|
46
+ p "deactivated: #{state}"
47
+ send_inactive_state state
48
+ }
49
+
50
+ #save activated states
51
+ @state_store[key] = current_active_states
52
+ end
53
+ end
54
+ }.callback { p "subscribed to #{@interactor} name #{@name}"}
55
+
56
+ end
57
+
58
+ def send_active_state(name)
59
+ send_data "1 #{name}"
60
+ end
61
+
62
+ def send_inactive_state(name)
63
+ send_data "0 #{name}"
64
+ end
65
+ end
66
+
67
+ def initialize(_interactor,_name)
68
+ @interactor = _interactor
69
+ @name = _name
70
+ end
71
+
72
+ def start(host="0.0.0.0",port=3001)
73
+ EventMachine::start_server host, port, StatefulProtocol do |conn|
74
+ conn.subscribe_redis(@interactor,@name)
75
+ @connections << conn
76
+
77
+ puts "connection..."
78
+
79
+ # inform about all currently activated states
80
+ # @state_store[@interactor]
81
+ end
82
+ puts "Started server on #{host}:#{port}"
83
+ end
84
+
85
+ end
86
+
@@ -0,0 +1,32 @@
1
+ class Action
2
+
3
+ def initialize
4
+
5
+ # sucecss of action used by finisheh callback
6
+ @result = false
7
+ end
8
+
9
+ def id
10
+ @action[:id]
11
+ end
12
+
13
+ def identifier
14
+
15
+ end
16
+
17
+ def initiated_callback(cb)
18
+
19
+ end
20
+
21
+ def start (observation_results)
22
+ self
23
+ end
24
+
25
+
26
+ # This callback is used to inform that the action has been successfully finished
27
+ def finished_callback (&block)
28
+ block.call(id,@result)
29
+ end
30
+
31
+
32
+ end
@@ -0,0 +1,32 @@
1
+ class BackendAction < Action
2
+ # BackendAction.new(:call => CUIControl.method(:find_cio_from_coordinates))
3
+ def initialize(params)
4
+ super()
5
+ @action = params
6
+ end
7
+
8
+
9
+ def parameter
10
+ return [] if @action[:parameter].nil?
11
+ @action[:parameter].split(',')
12
+ end
13
+
14
+ def call_function
15
+ @action[:call]
16
+ end
17
+
18
+ def identifier
19
+ call_function.name.to_s
20
+ end
21
+
22
+ def start(observation_results)
23
+ @result = false
24
+ params = []
25
+ parameter.each { |p|
26
+ params << observation_results[p]
27
+ }
28
+
29
+ @result = call_function.call *params
30
+ self
31
+ end
32
+ end
@@ -0,0 +1,88 @@
1
+ class BindAction < Action
2
+
3
+
4
+ def initialize(params)
5
+ super()
6
+ @action = params
7
+ @cb_observation_has_subscribed=nil
8
+ @is_bound = false
9
+ end
10
+
11
+ def initiated_callback(cb)
12
+ @cb_observation_has_subscribed = cb
13
+ end
14
+
15
+
16
+
17
+ def elementIn
18
+ @action[:elementIn]
19
+ end
20
+
21
+ def elementOut
22
+ @action[:elementOut]
23
+ end
24
+
25
+ def identifier
26
+ elementIn
27
+ end
28
+
29
+ def nameIn
30
+ @action[:nameIn]
31
+ end
32
+
33
+ def nameOut
34
+ @action[:nameOut]
35
+ end
36
+
37
+ def attrIn
38
+ @action[:attrIn]
39
+ end
40
+
41
+ def attrOut
42
+ @action[:attrOut]
43
+ end
44
+
45
+ def channelIn
46
+ "#{attrIn}:#{elementIn}.#{nameIn}"
47
+ end
48
+
49
+ def channelOut
50
+ "#{attrOut}:#{elementOut}.#{nameOut}"
51
+ end
52
+
53
+
54
+ def start(observation_results) # TODO handle observation_variables
55
+ @result = false
56
+ if @is_bound
57
+ @cb_observation_has_subscribed.call(elementIn) if @cb_observation_has_subscribed
58
+ return self
59
+ end
60
+
61
+ redis = RedisConnector.redis
62
+ redis.pubsub.subscribe(channelIn) { |message|
63
+
64
+
65
+ found=MultiJson.decode message
66
+
67
+ if nameIn.eql? found['name']
68
+
69
+ if found.has_key? @action[:attrIn]
70
+ result = found[@action[:attrIn]]
71
+ result = @action[:transform].call result if @action[:transform]
72
+ redis.publish channelOut, MultiJson.encode({:name=>@action[:nameOut], @action[:attrOut] => result})
73
+
74
+ end
75
+
76
+ end
77
+ }.callback do
78
+ @is_bound = true
79
+ @cb_observation_has_subscribed.call(elementIn) if @cb_observation_has_subscribed
80
+ end
81
+ @result = true
82
+ self
83
+ end
84
+
85
+ def unbind
86
+ RedisConnector.sub.unsubscribe(@action[:in])
87
+ end
88
+ end
@@ -0,0 +1,40 @@
1
+ class EventAction < Action
2
+ # BackendAction.new(:call => CUIControl.method(:find_cio_from_coordinates))
3
+ def initialize(params)
4
+ super()
5
+ @action = params
6
+ end
7
+
8
+ def event
9
+ @action[:event]
10
+ end
11
+
12
+ def target
13
+ @action[:target]
14
+ end
15
+
16
+ def selector
17
+ @action[:selector]
18
+ end
19
+
20
+ def start(observation_results)
21
+ @result = false
22
+ results = []
23
+ interactor_data= observation_results[target]
24
+
25
+ interactor_data = [interactor_data] if not interactor_data.kind_of?(Array)
26
+
27
+ interactor_data.each do |int_data|
28
+ interactor = MINT::Interactor.get(int_data["mint_model"],int_data["name"])
29
+ interactor = interactor.method(selector).call if not selector.nil?
30
+
31
+ results << interactor.process_event(event)
32
+
33
+ end
34
+
35
+ @result = true if results != nil and results.count(nil)==0
36
+
37
+ self
38
+ end
39
+
40
+ end
@@ -0,0 +1,31 @@
1
+ module MINT
2
+ class ComplementaryMapping < Mapping
3
+ def start
4
+ @state_callback.call(@mapping[:name], {:id => @mapping[:id], :mapping_state => :started}) if @state_callback
5
+ start_observations
6
+ self
7
+ end
8
+
9
+ def restart
10
+ @state_callback.call(@mapping[:name], {:id => @mapping[:id], :mapping_state => :restarted}) if @state_callback
11
+ start_observations
12
+ self
13
+ end
14
+
15
+ def start_observations
16
+ @observation_init = 0
17
+ observations.each do |observation|
18
+ @observation_init += 1
19
+ observation.start(@observation_results,self.method(:cb_activate_action)).is_subscribed_callback { |observation|
20
+ @observation_state[observation.element] = false
21
+ @state_callback.call(@mapping[:name], {:id => observation.id, :state => :activated}) if @state_callback
22
+ @observation_init -= 1
23
+ if @observation_init == 0
24
+ @mapping_activated = true
25
+ call_activated_callbacks
26
+ end
27
+ }
28
+ end
29
+ end
30
+ end
31
+ end
@@ -5,43 +5,179 @@ module MINT
5
5
  # updates to elements or element removals.
6
6
  #
7
7
  class Mapping
8
- attr_accessor :source_model, :on_action, :execute
9
-
10
- # A mapping is initialized with
11
- # @param [Class] source_model the other agents' model to listen to for events
12
- # @param [String] action to the tuple space that should be listened to. This is one of "take", "read", "write"
13
- # @param [Method] execute this method of the agent that runs the mapping, the specified action has happened.
14
- # @param [Method] inital method to call upon initialization of the mapping without the action to be happened, but scans the model for already happened events (write) and executes the method with these data.
15
- #
16
- def initialize (source_model,action,execute,initial=nil)
17
- @source_model = source_model
18
- @execute = execute
19
- @initial = initial
20
- @on_action = action
21
- end
22
-
23
- # Starts the mapping thread to listen to events
24
- #
25
- def execute
26
- raise NotImplementedError, "#{self.class}#execute not implemented"
27
- end
28
-
29
- def publish_events(events)
30
- # p "in check OR cond #{@conditions.inspect}"
31
-
32
- events.each do |c,event|
33
- c.each do |model,state|
34
- state.each do |s|
35
- result=model.first( :abstract_states=> /(^|\|)#{Regexp.quote(s)}/)
36
- if not result.nil?
37
- p "Sending #{event} to #{result.name}"
38
- p result.inspect
39
- p result.process_event(event)
40
- end
8
+
9
+ # informs mapping tool about state changes
10
+ attr_accessor :state_callback
11
+
12
+ def initialize(params)
13
+ @mapping = params
14
+
15
+
16
+ # to fire callback if all observations have been successfully initialized
17
+ @observation_init = 0
18
+
19
+ @activated_callback = nil
20
+ @action_activated = {}
21
+
22
+ # to fire callback to inform mapping state
23
+ @state_callback = nil
24
+
25
+ # stores variables assigned by observations
26
+ @observation_results = {}
27
+
28
+ @observation_state = {}
29
+
30
+ @action_states = {}
31
+
32
+ #overall action sucecces used for direct callback
33
+ @actions_success = false
34
+ end
35
+
36
+ def mapping_name
37
+ return @mapping[:name] if @mapping[:name]
38
+ "unnamed"
39
+ end
40
+
41
+ def id
42
+ @mapping[:id]
43
+ end
44
+
45
+ def observations
46
+ @mapping[:observations]
47
+ end
48
+
49
+ def actions
50
+ @mapping[:actions]
51
+ end
52
+
53
+ def start
54
+ return self
55
+ end
56
+
57
+ def startAction(observation_results)
58
+ @action_init = 0
59
+ @actions_success = false
60
+ actions.each do |action|
61
+ @action_init += 1
62
+ @state_callback.call(@mapping[:name], {:id => action.id, :state => :activated}) if @state_callback
63
+ action.start(observation_results).finished_callback { |id,result|
64
+ state = :failed
65
+ state = :succeeded if result
66
+
67
+ @action_states[id]=state
68
+
69
+ @state_callback.call(@mapping[:name], {:id => action.id, :state => state}) if @state_callback
70
+ @action_init -= 1
71
+ if @action_init == 0
72
+ @action_activated = true
73
+ r = false
74
+ r = true if not @action_states.values.include? :failed
75
+ @actions_success = r
76
+ call_actions_succeeded_callbacks r
41
77
  end
78
+ } # pass observation variables
79
+ end
80
+ self
81
+ end
82
+
83
+
84
+
85
+
86
+ # This callback is used to inform that all observations have been successfully activated (subscribed)
87
+ def activated_callback(&block)
88
+ return unless block
89
+
90
+ if @mapping_activated
91
+ block.call(self)
92
+ else
93
+ @activated_callbacks ||= []
94
+ @activated_callbacks.unshift block # << block
95
+ end
96
+ end
97
+
98
+ def call_activated_callbacks
99
+ @activated_callbacks ||= []
100
+
101
+ while cb = @activated_callbacks.pop
102
+ cb.call(self)
103
+ end
104
+ @activated_callbacks.clear if @activated_callbacks
105
+ end
106
+
107
+ # This callback is used to inform that all actions have been finished
108
+ def actions_succeeded_callback(&block)
109
+ return unless block
110
+
111
+ if @action_activated
112
+ block.call(self,@actions_success )
113
+ else
114
+ @actions_succeeded_callbacks ||= []
115
+ @actions_succeeded_callbacks.unshift block # << block
116
+ end
117
+ end
118
+
119
+
120
+ def call_actions_succeeded_callbacks(result)
121
+ @actions_succeeded_callbacks ||= []
122
+
123
+ while cb = @actions_succeeded_callbacks.pop
124
+ cb.call(self,result)
125
+ end
126
+ @actions_succeeded_callbacks.clear if @actions_succeeded_callbacks
127
+ end
128
+
129
+ # function is called every time an observation has been fulfilled or failed (in_state == :fail)
130
+ def cb_activate_action(element,in_state,result,id)
131
+ @state_callback.call(@mapping[:name], {:id => id, :element => element, :result => result, :state => in_state.to_s.to_sym}) if @state_callback
132
+
133
+ @observation_state[element] = in_state
134
+
135
+ if in_state == :fail
136
+ stop_observations # unsubscribe observations
137
+ @state_callback.call(@mapping[:name], {:id => @mapping[:id], :mapping_state => :failed}) if @state_callback
138
+ restart # restart mapping
139
+ return
140
+ end
141
+ if in_state
142
+ @observation_results.merge! result
143
+ # check if already all other observations have been matched
144
+ if not @observation_state.values.include? false
145
+ stop_observations # unsubscribe observations
146
+
147
+ startAction(@observation_results).actions_succeeded_callback { |m,result|
148
+ state = :failed
149
+ state = :succeeded if result
150
+
151
+ @state_callback.call(@mapping[:name], {:id => @mapping[:id], :mapping_state => state}) if @state_callback
152
+
153
+ # TODO -clean restart and move check_at_startup inside observation
154
+ # - add callback for action if succeeded & implement parallel action execution
155
+ m.restart
156
+
157
+ }
42
158
  end
43
159
  end
44
- true
45
160
  end
161
+
162
+ def restart
163
+ @observation_state = {}
164
+ @action_states = {}
165
+
166
+ observations.each do |observation|
167
+ @observation_state[observation.element] = false
168
+ observation.start
169
+ end
170
+
171
+ end
172
+
173
+ def stop_observations
174
+ observations.each do |observation|
175
+ observation.stop
176
+ end
177
+
178
+ end
179
+
46
180
  end
181
+
182
+
47
183
  end