Class: Roby::Log::ChronicleDisplay

Inherits:
Qt::Object
  • Object
show all
Includes:
DataDisplay, TaskDisplaySupport
Defined in:
lib/roby/log/chronicle.rb

Defined Under Namespace

Classes: Line

Instance Attribute Summary collapse

Attributes included from DataDisplay

#config_ui, #decoder, #main

Instance Method Summary collapse

Methods included from TaskDisplaySupport

#filter_prefixes, #update_prefixes_removal

Methods included from DataDisplay

#clear, #splat?

Constructor Details

#initializeChronicleDisplay

Returns a new instance of ChronicleDisplay.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/roby/log/chronicle.rb', line 45

def initialize
    @scene  = Qt::GraphicsScene.new
    super()

    @main = Qt::MainWindow.new
    main.resize 500, 500
    @ui = Ui::ChronicleView.new
    ui.setupUi(self, main)
    ui.graphics.scene = @scene

    @signalled_events    = []
    @execution_events    = []
    @graphic_stack       = []
    @graphic_objects     = Hash.new
    @last_event_graphics = Hash.new
    self.show_ownership = false

    connect(ui.graphics.horizontalScrollBar, SIGNAL('valueChanged(int)'), self, SLOT('hscroll()'))
    connect(ui.graphics.verticalScrollBar, SIGNAL('valueChanged(int)'), self, SLOT('vscroll()'))

    @time_scale = 100.0
end

Instance Attribute Details

#execution_eventsObject (readonly)

Returns the value of attribute execution_events.



36
37
38
# File 'lib/roby/log/chronicle.rb', line 36

def execution_events
  @execution_events
end

#graphic_objectsObject (readonly)

Returns the value of attribute graphic_objects.



38
39
40
# File 'lib/roby/log/chronicle.rb', line 38

def graphic_objects
  @graphic_objects
end

#graphic_stackObject (readonly)

Returns the value of attribute graphic_stack.



37
38
39
# File 'lib/roby/log/chronicle.rb', line 37

def graphic_stack
  @graphic_stack
end

#last_event_graphicsObject (readonly)

Returns the value of attribute last_event_graphics.



39
40
41
# File 'lib/roby/log/chronicle.rb', line 39

def last_event_graphics
  @last_event_graphics
end

#sceneObject (readonly)

Returns the value of attribute scene.



32
33
34
# File 'lib/roby/log/chronicle.rb', line 32

def scene
  @scene
end

#signalled_eventsObject (readonly)

Returns the value of attribute signalled_events.



35
36
37
# File 'lib/roby/log/chronicle.rb', line 35

def signalled_events
  @signalled_events
end

#time_scaleObject

Returns the value of attribute time_scale.



40
41
42
# File 'lib/roby/log/chronicle.rb', line 40

def time_scale
  @time_scale
end

#uiObject (readonly)

Returns the value of attribute ui.



33
34
35
# File 'lib/roby/log/chronicle.rb', line 33

def ui
  @ui
end

Instance Method Details

#append_event(task, event) ⇒ Object



158
159
160
161
# File 'lib/roby/log/chronicle.rb', line 158

def append_event(task, event)
    index = line_of(task)
    create_or_get_item(event, index)
end

#create_line(item) ⇒ Object



119
120
121
122
123
# File 'lib/roby/log/chronicle.rb', line 119

def create_line(item)
    group = scene.create_item_group([])
    graphic_stack << (new_line = Line.new(0, item, [], group))
    new_line
end

#create_or_get_task(item, time) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/roby/log/chronicle.rb', line 125

def create_or_get_task(item, time)
    unless g = graphic_objects[item]
 pos_x = time_to_display(time)

 g = graphic_objects[item] = item.display_create(self)
 g.rect = Qt::RectF.new(0, 0, 0, Log::DEFAULT_TASK_HEIGHT)
 g.move_by pos_x, 0
 line = create_line(item)
 line.add g, time
    end
    g
end

#generator_called(time, generator, context) ⇒ Object



286
287
288
# File 'lib/roby/log/chronicle.rb', line 286

def generator_called(time, generator, context)
    execution_events << [EVENT_CALLED, time, local_event(generator)]
end

#generator_fired(time, generator, event_id, event_time, event_context) ⇒ Object



289
290
291
292
# File 'lib/roby/log/chronicle.rb', line 289

def generator_fired(time, generator, event_id, event_time, event_context)
    generator = local_event(generator)
    execution_events << [EVENT_EMITTED, event_time, generator]
end

#generator_forwarding(time, flag, from, to, event_id, event_time, event_context) ⇒ Object



296
297
298
# File 'lib/roby/log/chronicle.rb', line 296

def generator_forwarding(time, flag, from, to, event_id, event_time, event_context)
    signalled_events << [flag, local_event(from), local_event(to), event_id]
end

#generator_signalling(time, flag, from, to, event_id, event_time, event_context) ⇒ Object



293
294
295
# File 'lib/roby/log/chronicle.rb', line 293

def generator_signalling(time, flag, from, to, event_id, event_time, event_context)
    signalled_events << [flag, local_event(from), local_event(to), event_id]
end

#hscroll(user = true) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/roby/log/chronicle.rb', line 92

def hscroll(user = true)
    left_side = ui.graphics.mapToScene(0, 0).x

    if user
 scrollbar = ui.graphics.horizontalScrollBar
 @display_follows_execution = (scrollbar.maximum == scrollbar.value)
    end

    graphic_stack.each do |line|
 item = line.item
 next unless item.kind_of?(Roby::Task::DRoby)

 graphics = graphic_objects[item]
 dx = graphics.pos.x - left_side
 if dx <= 0
      graphics.text.set_pos(-dx, graphics.text.pos.y)
 else
      graphics.text.set_pos(0, graphics.text.pos.y)
 end
    end
end

#line_of(object) ⇒ Object



138
139
140
141
142
143
# File 'lib/roby/log/chronicle.rb', line 138

def line_of(object)
    graphic_stack.each_with_index do |line, i|
 return i if line.item == object
    end
    nil
end

#local_event(obj) ⇒ Object



282
# File 'lib/roby/log/chronicle.rb', line 282

def local_event(obj);  decoder.local_event(obj) end

#local_object(obj) ⇒ Object



284
# File 'lib/roby/log/chronicle.rb', line 284

def local_object(obj); decoder.local_object(obj) end

#local_plan(obj) ⇒ Object



283
# File 'lib/roby/log/chronicle.rb', line 283

def local_plan(obj);   decoder.local_plan(obj) end

#local_task(obj) ⇒ Object



281
# File 'lib/roby/log/chronicle.rb', line 281

def local_task(obj);   decoder.local_task(obj) end

#stream=(stream) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
# File 'lib/roby/log/chronicle.rb', line 145

def stream=(stream)
    super

    # Initialize the set of running tasks
    update_prefixes_removal
    decoder.tasks.each_key do |task|
 if task.current_state == :started
      create_or_get_task(task, decoder.time)
 end
    end
end

#time_to_display(time) ⇒ Object



115
116
117
# File 'lib/roby/log/chronicle.rb', line 115

def time_to_display(time)
    (time - decoder.start_time) * time_scale
end

#updateObject



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/roby/log/chronicle.rb', line 163

def update
    update_prefixes_removal

    execution_events.each do |flags, time, event|
 graphics = event.display_create(self)
 graphics.move_by time_to_display(time), 0
 y_offset = Log::EVENT_CIRCLE_RADIUS + Log::TASK_EVENT_SPACING

 if event.respond_to?(:task)
      task_graphics = create_or_get_task(event.task, time)
      line = line_of(event.task)

      # Check that the event labels to not collide. If it is
      # the case, move the current label at the bottom of the
      # last label found
      line_info = graphic_stack[line]
      if line_info.graphic_items.size > 1
  last_event = line_info.graphic_items[-1]
  last_br    = last_event.text.scene_bounding_rect
  current_br = graphics.text.scene_bounding_rect
  if last_br.right > current_br.left
        if event.task.last_event[1] == event
   last_event.text.hide
        else
   graphics.text.set_pos(0, last_br.bottom - last_event.scene_pos.y)
        end
  end
      end

      # Move the right edge of the task to reflect that it is
      # still running. Then, make sure the rectangle can
      # contain the event graphics
      expected_height = graphics.text.bounding_rect.bottom + y_offset
      if expected_height > task_graphics.rect.height
  task_graphics.set_rect(0, 0, time_to_display(time) - time_to_display(line_info.start_time), expected_height)
  task_graphics.text.set_pos(task_graphics.text.pos.x, expected_height)
      end
      event.task.last_event = [time, event]

 elsif !(line = line_of(event))
      group = create_line(event)
      line = (graphic_stack.size - 1)
 end

 line_info = graphic_stack[line]
 graphics.move_by 0, line_info.y + y_offset

 # Try to handle too-near events gracefully
 #old_flag, old_graphics = last_event_graphics[event]
 #if old_flag
 #    flag = 2 if old_flag == 0 && flag == 1
 #    if old_graphics.text.bounding_rect.right > graphics.text.bounding_rect.left
 #        old_graphics.text.hide
 #    end
 #end
 #last_event_graphics[event] = [flag, graphics]

 graphics.brush, graphics.pen = EventGeneratorDisplay.style(event, flags)
 if flags & EVENT_EMITTED == 1
      graphics.z_layer += 1
 end
 line_info.add graphics, time
    end

    removed_objects = (graphic_objects.keys - decoder.tasks.keys - decoder.events.keys)
    removed_objects.each do |obj|
 if line = line_of(obj)
      graphic_objects.delete(obj)
      scene.remove_item graphic_stack[line].graphic_group
      graphic_stack.delete_at(line)
 end
    end

    decoder.tasks.each_key do |task|
 next unless task_graphics = graphic_objects[task]
 line_info = graphic_stack[line_of(task)]

 old_state = task.displayed_state
 task.update_graphics(self, task_graphics)

 state = task.current_state
 rect = task_graphics.rect

 last_time = if state == :success || state == :finished
   task.last_event[0]
        else decoder.time
        end
 task_graphics.set_rect(0, 0, time_to_display(last_time) - time_to_display(line_info.start_time), rect.height)
    end

    if display_follows_execution?
 scrollbar = ui.graphics.horizontalScrollBar
 scrollbar.value = scrollbar.maximum
 hscroll(false)
    end

    if display_follows_new_tasks?
 scrollbar = ui.graphics.verticalScrollBar
 scrollbar.value = scrollbar.maximum
    end

    # layout lines
    y = 0
    graphic_stack.each do |line|
 offset = y - line.y
 if offset != 0
      line.y = y
      line.graphic_group.move_by 0, offset
 end

 br = line.graphic_group.bounding_rect | line.graphic_group.children_bounding_rect
 y += br.bottom + Log::TASK_EVENT_SPACING
    end

    execution_events.clear
    signalled_events.clear
end

#vscroll(user = true) ⇒ Object



84
85
86
87
88
89
# File 'lib/roby/log/chronicle.rb', line 84

def vscroll(user = true)
    if user
 scrollbar = ui.graphics.verticalScrollBar
 @display_follows_new_tasks = (scrollbar.maximum == scrollbar.value)
    end
end