Class: Roby::RelationGraph

Inherits:
BGL::Graph show all
Includes:
Distributed::DRobyConstant::Dump
Defined in:
lib/roby/relations.rb,
lib/roby/distributed/protocol.rb

Overview

This class manages the graph defined by an object relation in Roby. Relation graphs are managed in hierarchies (for instance, in EventStructure, Precedence is a superset of CausalLink, and CausalLink a superset of both Forwarding and Signal). In this hierarchy, at each level, an edge cannot be present in more than one graph. Nonetheless, it is possible for a parent relation to have an edge which is present in none of its children.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Distributed::DRobyConstant::Dump

#droby_dump

Methods inherited from BGL::Graph

#components, #each_bfs, #each_dfs, #each_edge, #each_vertex, #generated_subgraphs, #include?, #initialize_copy, #insert, #linked?, #neighborhood, #prune, #reachable?, #remove, #replace_vertex, #same_graph?, #topological_sort, #unlink

Constructor Details

#initialize(name, options = {}) ⇒ RelationGraph

if this relation graph should be seen by remote hosts



201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/roby/relations.rb', line 201

def initialize(name, options = {})
    @name = name
    @options = options
    @subsets = ValueSet.new
    @distribute = options[:distribute]
    @dag = options[:dag]
    @weak = options[:weak]

    if options[:subsets]
	options[:subsets].each(&method(:superset_of))
    end
end

Instance Attribute Details

#nameObject (readonly)

The relation name



183
184
185
# File 'lib/roby/relations.rb', line 183

def name
  @name
end

#optionsObject (readonly)

The graph options as given to RelationSpace#relation



189
190
191
# File 'lib/roby/relations.rb', line 189

def options
  @options
end

#parentObject

The relation parent if any



185
186
187
# File 'lib/roby/relations.rb', line 185

def parent
  @parent
end

#subsetsObject (readonly)

The set of graphs



187
188
189
# File 'lib/roby/relations.rb', line 187

def subsets
  @subsets
end

#supportObject

The Ruby module that gets included in graph objects



368
369
370
# File 'lib/roby/relations.rb', line 368

def support
  @support
end

Instance Method Details



295
# File 'lib/roby/relations.rb', line 295

alias :__bgl_link :link

#add_relation(from, to, info = nil) ⇒ Object

If #dag? is true, it checks that the new relation does not create a cycle



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
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/roby/relations.rb', line 234

def add_relation(from, to, info = nil)
    # Get the toplevel DAG in our relation hierarchy. We only test for the
    # DAG property on this one, as it is the union of all its children
    top_dag = nil
    new_relations = []
    rel     = self
    while rel
	top_dag = rel if rel.dag?
	new_relations << rel
	rel = rel.parent
    end
    if top_dag && !top_dag.linked?(from, to) && top_dag.reachable?(to, from)
	raise CycleFoundError, "cannot add a #{from} -> #{to} relation since it would create a cycle"
    end

    # Now compute the set of relations in which we really have to add a
    # new relation
    top_rel = new_relations.last
    if top_rel.linked?(from, to)
	if !(old_info = from[to, top_rel]).nil?
	    if old_info != info
		raise ArgumentError, "trying to change edge information"
	    end
	end

	changed_info = [new_relations.pop]

	while !new_relations.empty?
	    if new_relations.last.linked?(from, to)
		changed_info << new_relations.pop
	    else
		break
	    end
	end

	for rel in changed_info
	    from[to, rel] = info
	end
    end

    unless new_relations.empty?
	if from.respond_to?(:adding_child_object)
	    from.adding_child_object(to, new_relations, info)
	end
	if to.respond_to?(:adding_parent_object)
	    to.adding_parent_object(from, new_relations, info)
	end

	for rel in new_relations
	    rel.__bgl_link(from, to, info)
	end

	if from.respond_to?(:added_child_object)
	    from.added_child_object(to, new_relations, info)
	end
	if to.respond_to?(:added_parent_object)
	    to.added_parent_object(from, new_relations, info)
	end
    end
end

Reimplemented from BGL::Graph. Unlike this implementation, it is possible to add an already existing edge if the info parameter matches.



299
300
301
302
303
304
305
306
307
# File 'lib/roby/relations.rb', line 299

def link(from, to, info)
    if linked?(from, to)
	if info != from[to, self]
	    raise ArgumentError, "trying to change edge information"
	end
	return
    end
    super
end

#linked_in_hierarchy?(source, target) ⇒ Boolean

Returns true if there is an edge source -> target in this graph or in one of its parents

Returns:

  • (Boolean)


346
347
348
# File 'lib/roby/relations.rb', line 346

def linked_in_hierarchy?(source, target) # :nodoc:
    linked?(source, target) || (parent.linked?(source, target) if parent)
end

#remove_relation(from, to) ⇒ Object

Remove the relation between from and to, in this graph and in its parent graphs as well



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/roby/relations.rb', line 311

def remove_relation(from, to)
    rel = self
    relations = []
    while rel
	relations << rel
	rel = rel.parent
    end

    if from.respond_to?(:removing_child_object)
	from.removing_child_object(to, relations)
    end
    if to.respond_to?(:removing_parent_object)
	to.removing_parent_object(from, relations)
    end

    for rel in relations
	rel.unlink(from, to)
    end

    if from.respond_to?(:removed_child_object)
	from.removed_child_object(to, relations)
    end
    if to.respond_to?(:removed_parent_object)
	to.removed_parent_object(from, relations)
    end
end

#root_relation?Boolean

True if this relation does not have a parent

Returns:

  • (Boolean)


227
# File 'lib/roby/relations.rb', line 227

def root_relation?; !parent end

#subset?(relation) ⇒ Boolean

Returns true if relation is included in this relation (i.e. it is either the same relation or one of its children)

Returns:

  • (Boolean)


340
341
342
# File 'lib/roby/relations.rb', line 340

def subset?(relation)
    self.eql?(relation) || subsets.any? { |subrel| subrel.subset?(relation) }
end

#superset_of(relation) ⇒ Object

Declare that relation is a superset of this relation



351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/roby/relations.rb', line 351

def superset_of(relation)
    relation.each_edge do |source, target, info|
	if linked_in_hierarchy?(source, target)
	    raise ArgumentError, "relation and self already share an edge"
	end
    end

    relation.parent = self
    subsets << relation

    # Copy the relations of the child into this graph
    relation.each_edge do |source, target, info|
	source.add_child_object(target, self, info)
    end
end

#to_sObject



224
# File 'lib/roby/relations.rb', line 224

def to_s; name end