roby 0.7

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 (240) hide show
  1. data/.gitignore +29 -0
  2. data/History.txt +4 -0
  3. data/License-fr.txt +519 -0
  4. data/License.txt +515 -0
  5. data/Manifest.txt +245 -0
  6. data/NOTES +4 -0
  7. data/README.txt +163 -0
  8. data/Rakefile +161 -0
  9. data/TODO.txt +146 -0
  10. data/app/README.txt +24 -0
  11. data/app/Rakefile +8 -0
  12. data/app/config/ROBOT.rb +5 -0
  13. data/app/config/app.yml +91 -0
  14. data/app/config/init.rb +7 -0
  15. data/app/config/roby.yml +3 -0
  16. data/app/controllers/.gitattributes +0 -0
  17. data/app/controllers/ROBOT.rb +2 -0
  18. data/app/data/.gitattributes +0 -0
  19. data/app/planners/ROBOT/main.rb +6 -0
  20. data/app/planners/main.rb +5 -0
  21. data/app/scripts/distributed +3 -0
  22. data/app/scripts/generate/bookmarks +3 -0
  23. data/app/scripts/replay +3 -0
  24. data/app/scripts/results +3 -0
  25. data/app/scripts/run +3 -0
  26. data/app/scripts/server +3 -0
  27. data/app/scripts/shell +3 -0
  28. data/app/scripts/test +3 -0
  29. data/app/tasks/.gitattributes +0 -0
  30. data/app/tasks/ROBOT/.gitattributes +0 -0
  31. data/bin/roby +210 -0
  32. data/bin/roby-log +168 -0
  33. data/bin/roby-shell +25 -0
  34. data/doc/images/event_generalization.png +0 -0
  35. data/doc/images/exception_propagation_1.png +0 -0
  36. data/doc/images/exception_propagation_2.png +0 -0
  37. data/doc/images/exception_propagation_3.png +0 -0
  38. data/doc/images/exception_propagation_4.png +0 -0
  39. data/doc/images/exception_propagation_5.png +0 -0
  40. data/doc/images/replay_handler_error.png +0 -0
  41. data/doc/images/replay_handler_error_0.png +0 -0
  42. data/doc/images/replay_handler_error_1.png +0 -0
  43. data/doc/images/roby_cycle_overview.png +0 -0
  44. data/doc/images/roby_replay_02.png +0 -0
  45. data/doc/images/roby_replay_03.png +0 -0
  46. data/doc/images/roby_replay_04.png +0 -0
  47. data/doc/images/roby_replay_event_representation.png +0 -0
  48. data/doc/images/roby_replay_first_state.png +0 -0
  49. data/doc/images/roby_replay_relations.png +0 -0
  50. data/doc/images/roby_replay_startup.png +0 -0
  51. data/doc/images/task_event_generalization.png +0 -0
  52. data/doc/papers.rdoc +11 -0
  53. data/doc/styles/allison.css +314 -0
  54. data/doc/styles/allison.js +316 -0
  55. data/doc/styles/allison.rb +276 -0
  56. data/doc/styles/jamis.rb +593 -0
  57. data/doc/tutorials/01-GettingStarted.rdoc +86 -0
  58. data/doc/tutorials/02-GoForward.rdoc +220 -0
  59. data/doc/tutorials/03-PlannedPath.rdoc +268 -0
  60. data/doc/tutorials/04-EventPropagation.rdoc +236 -0
  61. data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
  62. data/doc/tutorials/06-Overview.rdoc +40 -0
  63. data/doc/videos.rdoc +69 -0
  64. data/ext/droby/dump.cc +175 -0
  65. data/ext/droby/extconf.rb +3 -0
  66. data/ext/graph/algorithm.cc +746 -0
  67. data/ext/graph/extconf.rb +7 -0
  68. data/ext/graph/graph.cc +529 -0
  69. data/ext/graph/graph.hh +183 -0
  70. data/ext/graph/iterator_sequence.hh +102 -0
  71. data/ext/graph/undirected_dfs.hh +226 -0
  72. data/ext/graph/undirected_graph.hh +421 -0
  73. data/lib/roby.rb +41 -0
  74. data/lib/roby/app.rb +870 -0
  75. data/lib/roby/app/rake.rb +56 -0
  76. data/lib/roby/app/run.rb +14 -0
  77. data/lib/roby/app/scripts/distributed.rb +13 -0
  78. data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
  79. data/lib/roby/app/scripts/replay.rb +31 -0
  80. data/lib/roby/app/scripts/results.rb +15 -0
  81. data/lib/roby/app/scripts/run.rb +26 -0
  82. data/lib/roby/app/scripts/server.rb +18 -0
  83. data/lib/roby/app/scripts/shell.rb +88 -0
  84. data/lib/roby/app/scripts/test.rb +40 -0
  85. data/lib/roby/basic_object.rb +151 -0
  86. data/lib/roby/config.rb +5 -0
  87. data/lib/roby/control.rb +747 -0
  88. data/lib/roby/decision_control.rb +17 -0
  89. data/lib/roby/distributed.rb +32 -0
  90. data/lib/roby/distributed/base.rb +440 -0
  91. data/lib/roby/distributed/communication.rb +871 -0
  92. data/lib/roby/distributed/connection_space.rb +592 -0
  93. data/lib/roby/distributed/distributed_object.rb +206 -0
  94. data/lib/roby/distributed/drb.rb +62 -0
  95. data/lib/roby/distributed/notifications.rb +539 -0
  96. data/lib/roby/distributed/peer.rb +550 -0
  97. data/lib/roby/distributed/protocol.rb +529 -0
  98. data/lib/roby/distributed/proxy.rb +343 -0
  99. data/lib/roby/distributed/subscription.rb +311 -0
  100. data/lib/roby/distributed/transaction.rb +498 -0
  101. data/lib/roby/event.rb +897 -0
  102. data/lib/roby/exceptions.rb +234 -0
  103. data/lib/roby/executives/simple.rb +30 -0
  104. data/lib/roby/graph.rb +166 -0
  105. data/lib/roby/interface.rb +390 -0
  106. data/lib/roby/log.rb +3 -0
  107. data/lib/roby/log/chronicle.rb +303 -0
  108. data/lib/roby/log/console.rb +72 -0
  109. data/lib/roby/log/data_stream.rb +197 -0
  110. data/lib/roby/log/dot.rb +279 -0
  111. data/lib/roby/log/event_stream.rb +151 -0
  112. data/lib/roby/log/file.rb +340 -0
  113. data/lib/roby/log/gui/basic_display.ui +83 -0
  114. data/lib/roby/log/gui/chronicle.rb +26 -0
  115. data/lib/roby/log/gui/chronicle_view.rb +40 -0
  116. data/lib/roby/log/gui/chronicle_view.ui +70 -0
  117. data/lib/roby/log/gui/data_displays.rb +172 -0
  118. data/lib/roby/log/gui/data_displays.ui +155 -0
  119. data/lib/roby/log/gui/notifications.rb +26 -0
  120. data/lib/roby/log/gui/relations.rb +248 -0
  121. data/lib/roby/log/gui/relations.ui +123 -0
  122. data/lib/roby/log/gui/relations_view.rb +185 -0
  123. data/lib/roby/log/gui/relations_view.ui +149 -0
  124. data/lib/roby/log/gui/replay.rb +327 -0
  125. data/lib/roby/log/gui/replay_controls.rb +200 -0
  126. data/lib/roby/log/gui/replay_controls.ui +259 -0
  127. data/lib/roby/log/gui/runtime.rb +130 -0
  128. data/lib/roby/log/hooks.rb +185 -0
  129. data/lib/roby/log/logger.rb +202 -0
  130. data/lib/roby/log/notifications.rb +244 -0
  131. data/lib/roby/log/plan_rebuilder.rb +470 -0
  132. data/lib/roby/log/relations.rb +1056 -0
  133. data/lib/roby/log/server.rb +550 -0
  134. data/lib/roby/log/sqlite.rb +47 -0
  135. data/lib/roby/log/timings.rb +164 -0
  136. data/lib/roby/plan-object.rb +247 -0
  137. data/lib/roby/plan.rb +762 -0
  138. data/lib/roby/planning.rb +13 -0
  139. data/lib/roby/planning/loops.rb +302 -0
  140. data/lib/roby/planning/model.rb +906 -0
  141. data/lib/roby/planning/task.rb +151 -0
  142. data/lib/roby/propagation.rb +562 -0
  143. data/lib/roby/query.rb +619 -0
  144. data/lib/roby/relations.rb +583 -0
  145. data/lib/roby/relations/conflicts.rb +70 -0
  146. data/lib/roby/relations/ensured.rb +20 -0
  147. data/lib/roby/relations/error_handling.rb +23 -0
  148. data/lib/roby/relations/events.rb +9 -0
  149. data/lib/roby/relations/executed_by.rb +193 -0
  150. data/lib/roby/relations/hierarchy.rb +239 -0
  151. data/lib/roby/relations/influence.rb +10 -0
  152. data/lib/roby/relations/planned_by.rb +63 -0
  153. data/lib/roby/robot.rb +7 -0
  154. data/lib/roby/standard_errors.rb +218 -0
  155. data/lib/roby/state.rb +5 -0
  156. data/lib/roby/state/events.rb +221 -0
  157. data/lib/roby/state/information.rb +55 -0
  158. data/lib/roby/state/pos.rb +110 -0
  159. data/lib/roby/state/shapes.rb +32 -0
  160. data/lib/roby/state/state.rb +353 -0
  161. data/lib/roby/support.rb +92 -0
  162. data/lib/roby/task-operations.rb +182 -0
  163. data/lib/roby/task.rb +1618 -0
  164. data/lib/roby/test/common.rb +399 -0
  165. data/lib/roby/test/distributed.rb +214 -0
  166. data/lib/roby/test/tasks/empty_task.rb +9 -0
  167. data/lib/roby/test/tasks/goto.rb +36 -0
  168. data/lib/roby/test/tasks/simple_task.rb +23 -0
  169. data/lib/roby/test/testcase.rb +519 -0
  170. data/lib/roby/test/tools.rb +160 -0
  171. data/lib/roby/thread_task.rb +87 -0
  172. data/lib/roby/transactions.rb +462 -0
  173. data/lib/roby/transactions/proxy.rb +292 -0
  174. data/lib/roby/transactions/updates.rb +139 -0
  175. data/plugins/fault_injection/History.txt +4 -0
  176. data/plugins/fault_injection/README.txt +37 -0
  177. data/plugins/fault_injection/Rakefile +18 -0
  178. data/plugins/fault_injection/TODO.txt +0 -0
  179. data/plugins/fault_injection/app.rb +52 -0
  180. data/plugins/fault_injection/fault_injection.rb +89 -0
  181. data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
  182. data/plugins/subsystems/README.txt +40 -0
  183. data/plugins/subsystems/Rakefile +18 -0
  184. data/plugins/subsystems/app.rb +171 -0
  185. data/plugins/subsystems/test/app/README +24 -0
  186. data/plugins/subsystems/test/app/Rakefile +8 -0
  187. data/plugins/subsystems/test/app/config/app.yml +71 -0
  188. data/plugins/subsystems/test/app/config/init.rb +9 -0
  189. data/plugins/subsystems/test/app/config/roby.yml +3 -0
  190. data/plugins/subsystems/test/app/planners/main.rb +20 -0
  191. data/plugins/subsystems/test/app/scripts/distributed +3 -0
  192. data/plugins/subsystems/test/app/scripts/replay +3 -0
  193. data/plugins/subsystems/test/app/scripts/results +3 -0
  194. data/plugins/subsystems/test/app/scripts/run +3 -0
  195. data/plugins/subsystems/test/app/scripts/server +3 -0
  196. data/plugins/subsystems/test/app/scripts/shell +3 -0
  197. data/plugins/subsystems/test/app/scripts/test +3 -0
  198. data/plugins/subsystems/test/app/tasks/services.rb +15 -0
  199. data/plugins/subsystems/test/test_subsystems.rb +71 -0
  200. data/test/distributed/test_communication.rb +178 -0
  201. data/test/distributed/test_connection.rb +282 -0
  202. data/test/distributed/test_execution.rb +373 -0
  203. data/test/distributed/test_mixed_plan.rb +341 -0
  204. data/test/distributed/test_plan_notifications.rb +238 -0
  205. data/test/distributed/test_protocol.rb +516 -0
  206. data/test/distributed/test_query.rb +102 -0
  207. data/test/distributed/test_remote_plan.rb +491 -0
  208. data/test/distributed/test_transaction.rb +463 -0
  209. data/test/mockups/tasks.rb +27 -0
  210. data/test/planning/test_loops.rb +380 -0
  211. data/test/planning/test_model.rb +427 -0
  212. data/test/planning/test_task.rb +106 -0
  213. data/test/relations/test_conflicts.rb +42 -0
  214. data/test/relations/test_ensured.rb +38 -0
  215. data/test/relations/test_executed_by.rb +149 -0
  216. data/test/relations/test_hierarchy.rb +158 -0
  217. data/test/relations/test_planned_by.rb +54 -0
  218. data/test/suite_core.rb +24 -0
  219. data/test/suite_distributed.rb +9 -0
  220. data/test/suite_planning.rb +3 -0
  221. data/test/suite_relations.rb +8 -0
  222. data/test/test_bgl.rb +508 -0
  223. data/test/test_control.rb +399 -0
  224. data/test/test_event.rb +894 -0
  225. data/test/test_exceptions.rb +592 -0
  226. data/test/test_interface.rb +37 -0
  227. data/test/test_log.rb +114 -0
  228. data/test/test_log_server.rb +132 -0
  229. data/test/test_plan.rb +584 -0
  230. data/test/test_propagation.rb +210 -0
  231. data/test/test_query.rb +266 -0
  232. data/test/test_relations.rb +180 -0
  233. data/test/test_state.rb +414 -0
  234. data/test/test_support.rb +16 -0
  235. data/test/test_task.rb +938 -0
  236. data/test/test_testcase.rb +122 -0
  237. data/test/test_thread_task.rb +73 -0
  238. data/test/test_transactions.rb +569 -0
  239. data/test/test_transactions_proxy.rb +198 -0
  240. metadata +570 -0
@@ -0,0 +1,149 @@
1
+ <ui version="4.0" >
2
+ <class>RelationsView</class>
3
+ <widget class="QMainWindow" name="RelationsView" >
4
+ <property name="geometry" >
5
+ <rect>
6
+ <x>0</x>
7
+ <y>0</y>
8
+ <width>800</width>
9
+ <height>600</height>
10
+ </rect>
11
+ </property>
12
+ <property name="windowTitle" >
13
+ <string>MainWindow</string>
14
+ </property>
15
+ <widget class="QWidget" name="centralwidget" >
16
+ <layout class="QVBoxLayout" >
17
+ <item>
18
+ <widget class="QGraphicsView" name="graphics" >
19
+ <property name="renderHints" >
20
+ <set>QPainter::Antialiasing|QPainter::TextAntialiasing</set>
21
+ </property>
22
+ </widget>
23
+ </item>
24
+ </layout>
25
+ </widget>
26
+ <widget class="QMenuBar" name="menubar" >
27
+ <property name="geometry" >
28
+ <rect>
29
+ <x>0</x>
30
+ <y>0</y>
31
+ <width>800</width>
32
+ <height>29</height>
33
+ </rect>
34
+ </property>
35
+ <widget class="QMenu" name="menuView" >
36
+ <property name="title" >
37
+ <string>View</string>
38
+ </property>
39
+ <addaction name="actionKeepSignals" />
40
+ <addaction name="actionHideFinalized" />
41
+ <addaction name="actionShowAll" />
42
+ <addaction name="actionRedraw" />
43
+ <addaction name="separator" />
44
+ <addaction name="actionZoom" />
45
+ <addaction name="actionUnzoom" />
46
+ <addaction name="actionFit" />
47
+ <addaction name="separator" />
48
+ <addaction name="actionSVGExport" />
49
+ <addaction name="actionPrint" />
50
+ </widget>
51
+ <widget class="QMenu" name="menuTask_labels" >
52
+ <property name="title" >
53
+ <string>Task labels</string>
54
+ </property>
55
+ <widget class="QMenu" name="menuRemovedPrefixes" >
56
+ <property name="title" >
57
+ <string>Removed prefixes</string>
58
+ </property>
59
+ <addaction name="actionPrefixAdd" />
60
+ <addaction name="separator" />
61
+ </widget>
62
+ <addaction name="actionOwnership" />
63
+ <addaction name="menuRemovedPrefixes" />
64
+ </widget>
65
+ <addaction name="menuView" />
66
+ <addaction name="menuTask_labels" />
67
+ </widget>
68
+ <action name="actionShowAll" >
69
+ <property name="text" >
70
+ <string>Show All</string>
71
+ </property>
72
+ </action>
73
+ <action name="actionRedraw" >
74
+ <property name="text" >
75
+ <string>Redaw</string>
76
+ </property>
77
+ </action>
78
+ <action name="actionZoom" >
79
+ <property name="text" >
80
+ <string>Zoom +</string>
81
+ </property>
82
+ </action>
83
+ <action name="actionUnzoom" >
84
+ <property name="text" >
85
+ <string>Zoom -</string>
86
+ </property>
87
+ </action>
88
+ <action name="actionFit" >
89
+ <property name="text" >
90
+ <string>Fit</string>
91
+ </property>
92
+ </action>
93
+ <action name="actionOwnership" >
94
+ <property name="checkable" >
95
+ <bool>true</bool>
96
+ </property>
97
+ <property name="checked" >
98
+ <bool>true</bool>
99
+ </property>
100
+ <property name="text" >
101
+ <string>Ownership</string>
102
+ </property>
103
+ </action>
104
+ <action name="actionPrefixAdd" >
105
+ <property name="text" >
106
+ <string>Add...</string>
107
+ </property>
108
+ </action>
109
+ <action name="actionSVGExport" >
110
+ <property name="text" >
111
+ <string>SVG Export</string>
112
+ </property>
113
+ </action>
114
+ <action name="actionPrint" >
115
+ <property name="text" >
116
+ <string>Print</string>
117
+ </property>
118
+ </action>
119
+ <action name="actionKeepSignals" >
120
+ <property name="checkable" >
121
+ <bool>true</bool>
122
+ </property>
123
+ <property name="checked" >
124
+ <bool>false</bool>
125
+ </property>
126
+ <property name="text" >
127
+ <string>Keep signals</string>
128
+ </property>
129
+ </action>
130
+ <action name="actionBookmarksAdd" >
131
+ <property name="text" >
132
+ <string>Add ...</string>
133
+ </property>
134
+ </action>
135
+ <action name="actionHideFinalized" >
136
+ <property name="checkable" >
137
+ <bool>true</bool>
138
+ </property>
139
+ <property name="checked" >
140
+ <bool>true</bool>
141
+ </property>
142
+ <property name="text" >
143
+ <string>Hide Finalized</string>
144
+ </property>
145
+ </action>
146
+ </widget>
147
+ <resources/>
148
+ <connections/>
149
+ </ui>
@@ -0,0 +1,327 @@
1
+ require 'Qt4'
2
+ require 'roby/app'
3
+ require 'optparse'
4
+
5
+ require 'roby/log/gui/replay_controls'
6
+ require 'roby/log/gui/data_displays'
7
+
8
+ # This class is a data stream list model for offline replay:
9
+ # it holds a list of log file which can then be used for
10
+ # display by log/replay
11
+ class OfflineStreamListModel < DataStreamListModel
12
+ def edit(stream)
13
+ dir = if !stream || stream.files.empty? then ""
14
+ else File.dirname(stream.files.first) end
15
+
16
+ newfiles = Qt::FileDialog.get_open_file_names nil, "New data stream", dir
17
+ return if newfiles.empty?
18
+ if !newfiles.empty?
19
+ if newstream = Roby.app.data_stream(newfiles)
20
+ return newstream
21
+ else
22
+ Qt::MessageBox.warning nil, "Add data stream", "Cannot determine data stream type for #{newfiles.join(", ")}"
23
+ return
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ class Replay < Qt::MainWindow
30
+ attr_reader :streams
31
+ attr_reader :streams_model
32
+
33
+ # The widget which controls the data stream => display mapping, and display
34
+ # control
35
+ attr_reader :ui_displays
36
+ # The widget which hold the replay controls (play, pause, ...)
37
+ attr_reader :ui_controls
38
+
39
+ # The set of bookmarks as a name => time map
40
+ attr_reader :bookmarks
41
+
42
+ KEY_GOTO = Qt::KeySequence.new('g')
43
+
44
+ # True if we should start playing right away
45
+ attr_accessor :play_now
46
+ # The log directory, or Roby.app.log_dir
47
+ attr_accessor :log_dir
48
+ # Set to a time at which we should go to
49
+ attr_accessor :initial_time
50
+ # A set of procs which are to be called to set up the display
51
+ attr_accessor :initial_setup
52
+
53
+ def initialize
54
+ super()
55
+ @play_speed = 1.0
56
+ @play_now = nil
57
+ @logdir = nil
58
+ @goto = nil
59
+ @initial_setup = []
60
+ @bookmarks = Hash.new
61
+
62
+ # Create the vertical layout for this window
63
+ central_widget = Qt::Widget.new(self)
64
+ self.central_widget = central_widget
65
+ layout = Qt::VBoxLayout.new(central_widget)
66
+ layout.spacing = 6
67
+ layout.margin = 0
68
+
69
+ # Add support for the data streams and display setup
70
+ @streams = Array.new
71
+ @streams_model = OfflineStreamListModel.new(streams)
72
+ displays_holder = Qt::Widget.new(central_widget)
73
+ layout.add_widget displays_holder
74
+ @ui_displays = Ui_DataDisplays.new
75
+ ui_displays.setupUi(displays_holder)
76
+ ui_displays.streams.model = streams_model
77
+ connect(ui_displays.add_stream, SIGNAL("clicked()"), self, SLOT("add_stream()"))
78
+ connect(ui_displays.remove_stream, SIGNAL("clicked()"), self, SLOT("remove_stream()"))
79
+ connect(ui_displays.display_add, SIGNAL("clicked()"), self, SLOT("add_display()"))
80
+
81
+ controls_holder = Qt::Widget.new(central_widget)
82
+ @ui_controls = Ui::ReplayControls.new
83
+ ui_controls.setupUi(self, controls_holder)
84
+ layout.add_widget controls_holder
85
+ end
86
+
87
+ def play_speed=(value)
88
+ ui_controls.speed.text = value.to_s
89
+ @play_speed = value
90
+
91
+ if play_timer
92
+ play_timer.stop
93
+ play_timer.start(Integer(time_slice * 1000))
94
+ end
95
+ end
96
+ def time_slice
97
+ if play_speed < 1
98
+ BASE_TIME_SLICE / play_speed
99
+ else
100
+ BASE_TIME_SLICE
101
+ end
102
+ end
103
+
104
+ def displayed_streams
105
+ streams.find_all do |s|
106
+ s.displayed?
107
+ end
108
+ end
109
+
110
+ # Time of the first known sample
111
+ attr_reader :first_sample
112
+ # Time of the last known sample
113
+ attr_reader :last_sample
114
+
115
+ def seek(time, integrate = true)
116
+ if time && !first_sample
117
+ seek(nil)
118
+ elsif time && first_sample && time < first_sample
119
+ time = nil
120
+ end
121
+
122
+ displayed_streams.each { |s| s.prepare_seek(time) }
123
+ if !time || time == Time.at(0)
124
+ min, max = displayed_streams.inject([nil, nil]) do |(min, max), stream|
125
+ stream_min, stream_max = stream.range
126
+ if !min || stream_min < min
127
+ min = stream_min
128
+ end
129
+ if !max || stream_max > max
130
+ max = stream_max
131
+ end
132
+ [min, max]
133
+ end
134
+
135
+ @first_sample = @time = min
136
+ @last_sample = max
137
+
138
+ ui_controls.progress.minimum = min.to_i
139
+ ui_controls.progress.maximum = max.to_i
140
+ ui_controls.update_bookmarks_menu
141
+ else
142
+ play_until time, integrate
143
+ end
144
+
145
+ update_time_display
146
+ end
147
+
148
+ def update_time_display
149
+ ui_controls.time_lcd.display(((self.time - first_sample) * 1000.0).round / 1000.0)
150
+ ui_controls.progress.value = self.time.to_i
151
+ end
152
+
153
+ attr_reader :time
154
+
155
+ def next_time
156
+ displayed_streams.
157
+ map { |s| s.next_time }.
158
+ compact.min
159
+ end
160
+
161
+ BASE_TIME_SLICE = 0.5
162
+ attr_reader :play_timer, :play_speed
163
+ def play
164
+ seek(nil) unless first_sample
165
+
166
+ @play_timer = Qt::Timer.new(self)
167
+ connect(play_timer, SIGNAL("timeout()"), self, SLOT("play_step_timer()"))
168
+ play_timer.start(Integer(time_slice * 1000))
169
+ end
170
+
171
+ def stop
172
+ if play_timer
173
+ ui_controls.play.checked = false
174
+ play_timer.stop
175
+ @play_timer = nil
176
+ end
177
+ end
178
+
179
+ def play_step
180
+ seek(nil) unless first_sample
181
+ play_until(next_time)
182
+ end
183
+
184
+ def play_step_timer
185
+ start = Time.now
186
+ play_until(time + time_slice * play_speed)
187
+ end
188
+ slots 'play_step_timer()'
189
+
190
+ def play_until(max_time, integrate = true)
191
+ start_at = Time.now
192
+ displayed_streams.inject(timeline = []) do |timeline, s|
193
+ if s.next_time
194
+ timeline << [s.next_time, s]
195
+ end
196
+ timeline
197
+ end
198
+
199
+ if timeline.empty?
200
+ stop
201
+ return
202
+ end
203
+
204
+ updated_streams = Set.new
205
+
206
+ timeline.sort_by { |t, _| t }
207
+ while !timeline.empty? && (timeline[0][0] - max_time) < 0.001
208
+ @time, stream = timeline.first
209
+
210
+ stream.advance
211
+ stream.clear_integrated unless integrate
212
+ updated_streams << stream
213
+ if next_time = stream.next_time
214
+ timeline[0] = [next_time, stream]
215
+ else
216
+ timeline.shift
217
+ end
218
+ timeline.sort_by { |t, _| t }
219
+ end
220
+
221
+ replayed = Time.now
222
+
223
+ updated_streams.each do |stream|
224
+ stream.display
225
+ end
226
+
227
+ STDERR.puts "replay #{replayed - start_at}, display #{Time.now-replayed}"
228
+
229
+ if timeline.empty? then stop
230
+ else @time = max_time
231
+ end
232
+
233
+ if time > last_sample
234
+ @last_sample = time
235
+
236
+ time_display = time.to_i
237
+ if ui_controls.progress.maximum < time_display
238
+ ui_controls.progress.maximum = (first_sample + (last_sample - first_sample) * 4 / 3).to_i
239
+ end
240
+ end
241
+ update_time_display
242
+
243
+ rescue Exception => e
244
+ message = "<html>#{Qt.escape(e.message)}<ul><li>#{e.backtrace.join("</li><li>")}</li></ul></html>"
245
+ Qt::MessageBox.critical self, "Replay failure", message
246
+ stop
247
+ end
248
+
249
+ def add_stream(stream = nil)
250
+ streams_model.add_new(stream)
251
+ end
252
+ slots 'add_stream()'
253
+
254
+ def remove_stream
255
+ index = ui_displays.streams.current_index.row
256
+ streams.removeRow(index, Qt::ModelIndex.new)
257
+ end
258
+ slots 'remove_stream()'
259
+
260
+ def add_display(kind = nil)
261
+ ui_displays.add_display(streams_model, kind)
262
+ end
263
+ slots 'add_display()'
264
+
265
+ def self.setup(argv)
266
+ replay = self.new
267
+
268
+ parser = OptionParser.new do |opt|
269
+ Ui_DataDisplays::DISPLAYS.each_value do |config_ui|
270
+ config_ui.setup_optparse(opt, replay)
271
+ end
272
+
273
+ opt.on("--logdir=DIR", String, "the log directory in which we initialize the data streams") do |dir|
274
+ replay.log_dir = dir
275
+ end
276
+ opt.on("--play", "start playing after loading the event log") do
277
+ replay.play_now = true
278
+ end
279
+
280
+ opt.on("--speed=SPEED", Integer, "play speed") do |speed|
281
+ replay.play_speed = speed
282
+ end
283
+ opt.on("--goto=TIME", String, "go to TIME before playing normally. Time is given relatively to the simulation start") do |goto|
284
+ replay.initial_time = goto
285
+ end
286
+ opt.on('--bookmarks=FILE', String, "load the bookmarks in FILE") do |file|
287
+ replay.ui_controls.load_bookmarks(file)
288
+ end
289
+ end
290
+ args = argv.dup
291
+ parser.parse!(args)
292
+
293
+ yield(replay, parser, args) if block_given?
294
+
295
+ replay
296
+ end
297
+
298
+ def setup
299
+ initial_setup.each do |prc|
300
+ prc.call(self)
301
+ end
302
+
303
+ show
304
+ if initial_time
305
+ seek(nil)
306
+
307
+ seek_time = if initial_time[0] == ?@
308
+ Time.from_hms(initial_time[1..-1])
309
+ else
310
+ first_sample + (Time.from_hms(initial_time) - Time.at(0))
311
+ end
312
+ seek(seek_time, false)
313
+ end
314
+
315
+ if play_now
316
+ ui_controls.play.checked = true
317
+ end
318
+ end
319
+ end
320
+
321
+ if $0 == __FILE__
322
+ a = Qt::Application.new(ARGV)
323
+ w = Replay.new
324
+ w.show
325
+ a.exec
326
+ end
327
+