Class: Roby::PlanObject
- Inherits:
- BasicObject
- Includes:
- DirectedRelationSupport, Distributed::RelationModificationHooks, Transactions::PlanObjectUpdates
- Defined in:
- lib/roby/plan-object.rb,
lib/roby.rb
Overview
Base class for all objects which are included in a plan.
Direct Known Subclasses
Defined Under Namespace
Classes: DRoby
Constant Summary
Constants included from Log::BasicObjectHooks
Instance Attribute Summary collapse
-
#executable ⇒ Object
writeonly
- A three-state flag with the following values: nil
- the object is executable if its plan is true
- the object is executable false
-
the object is not executable.
-
#plan ⇒ Object
The plan this object belongs to.
-
#removed_at ⇒ Object
The place where this object has been removed from its plan.
Attributes inherited from BasicObject
Class Method Summary collapse
-
.child_plan_object(attribute) ⇒ Object
This class method sets up the enclosing class as a child object, with the root object being returned by the given attribute.
Instance Method Summary collapse
-
#add_child_object(child, type, info = nil) ⇒ Object
Synchronizes the plan of this object from the one of its peer.
-
#apply_relation_changes(object, changes) ⇒ Object
Transfers a set of relations from this plan object to
object. -
#each_plan_child ⇒ Object
Iterates on all the children of this root object.
-
#executable? ⇒ Boolean
If this object is executable.
-
#finalized? ⇒ Boolean
True if this object has been included in a plan, but has been removed from it since.
-
#forget_peer(peer) ⇒ Object
Called when all links to
peershould be removed. -
#read_write? ⇒ Boolean
True if this object can be modified by the local plan manager.
-
#remotely_useful? ⇒ Boolean
True if this object is useful for one of our peers.
-
#removing_child_object(child, type) ⇒ Object
Checks if we have the right to remove a relation.
-
#replace_by(object) ⇒ Object
Replaces
selfbyobjectin all graphsselfis part of. -
#replace_subplan_by(object) ⇒ Object
Replaces, in the plan, the subplan generated by this plan object by the one generated by
object. -
#root_object ⇒ Object
Return the root plan object for this object.
-
#root_object? ⇒ Boolean
True if this object is a root object in the plan.
-
#subscribed? ⇒ Boolean
True if we are explicitely subscribed to this object.
-
#update_on?(peer) ⇒ Boolean
True if we should send updates about this object to
peer. -
#updated_by?(peer) ⇒ Boolean
True if we receive updates for this object from
peer.
Methods included from Distributed::RelationModificationHooks
#added_child_object, #removed_child_object
Methods included from Transactions::PlanObjectUpdates
Methods included from DirectedRelationSupport
#add_parent_object, #check_is_relation, #related_objects, #relations, #remove_child_object, #remove_children, #remove_parent_object, #remove_parents, #remove_relations
Methods inherited from BasicObject
#add_sibling_for, #distribute?, distribute?, #has_sibling_on?, #initialize_copy, local_only, #remove_sibling_for, #self_owned?, #sibling_of, #sibling_on, #subscribe, #updated?, #updated_peers
Methods included from Log::BasicObjectHooks
Instance Attribute Details
#executable=(value) ⇒ Object (writeonly)
A three-state flag with the following values:
- nil
-
the object is executable if its plan is
- true
-
the object is executable
- false
-
the object is not executable
36 37 38 |
# File 'lib/roby/plan-object.rb', line 36 def executable=(value) @executable = value end |
#plan ⇒ Object
The plan this object belongs to
11 12 13 |
# File 'lib/roby/plan-object.rb', line 11 def plan @plan end |
#removed_at ⇒ Object
The place where this object has been removed from its plan. Once an object is removed from its plan, it cannot be added back again.
15 16 17 |
# File 'lib/roby/plan-object.rb', line 15 def removed_at @removed_at end |
Class Method Details
.child_plan_object(attribute) ⇒ Object
This class method sets up the enclosing class as a child object, with the root object being returned by the given attribute. Task event generators are for instance defined by
class TaskEventGenerator < EventGenerator
# The task this generator belongs to
attr_reader :task
child_plan_object :task
end
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/roby/plan-object.rb', line 116 def self.child_plan_object(attribute) class_eval <<-EOD def root_object; #{attribute} end def root_object?; false end def owners; #{attribute}.owners end def distribute?; #{attribute}.distribute? end def plan; #{attribute}.plan end def executable?; #{attribute}.executable? end def subscribed?; #{attribute}.subscribed? end def updated?; #{attribute}.updated? end def updated_by?(peer); #{attribute}.updated_by?(peer) end def update_on?(peer); #{attribute}.update_on?(peer) end def updated_peers; #{attribute}.updated_peers end def remotely_useful?; #{attribute}.remotely_useful? end def forget_peer(peer) remove_sibling_for(peer) end def sibling_of(remote_object, peer) if !distribute? raise ArgumentError, "#{self} is local only" end add_sibling_for(peer, remote_object) end private :plan= private :executable= EOD end |
Instance Method Details
#add_child_object(child, type, info = nil) ⇒ Object
Synchronizes the plan of this object from the one of its peer
91 92 93 94 95 96 97 |
# File 'lib/roby/plan-object.rb', line 91 def add_child_object(child, type, info = nil) # :nodoc: if child.plan != plan root_object.synchronize_plan(child.root_object) end super end |
#apply_relation_changes(object, changes) ⇒ Object
Transfers a set of relations from this plan object to object. changes is formatted as a sequence of relation, parents, children slices, where parents and children are sets of objects.
For each of these slices, the method removes the parent->self and self->child edges in the given relation, and then adds the corresponding parent->object and object->child edges.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/roby/plan-object.rb', line 157 def apply_relation_changes(object, changes) # The operation is done in two parts to avoid problems with # creating cycles in the graph: first we remove the old edges, then # we add the new ones. changes.each_slice(3) do |rel, parents, children| parents.each_slice(2) do |parent, info| parent.remove_child_object(self, rel) end children.each_slice(2) do |child, info| remove_child_object(child, rel) end end changes.each_slice(3) do |rel, parents, children| parents.each_slice(2) do |parent, info| parent.add_child_object(object, rel, info) end children.each_slice(2) do |child, info| object.add_child_object(child, rel, info) end end end |
#each_plan_child ⇒ Object
Iterates on all the children of this root object
104 |
# File 'lib/roby/plan-object.rb', line 104 def each_plan_child; self end |
#executable? ⇒ Boolean
If this object is executable
39 40 41 |
# File 'lib/roby/plan-object.rb', line 39 def executable? @executable || (@executable.nil? && plan && plan.executable?) end |
#finalized? ⇒ Boolean
True if this object has been included in a plan, but has been removed from it since
19 |
# File 'lib/roby/plan-object.rb', line 19 def finalized?; !!removed_at end |
#forget_peer(peer) ⇒ Object
Called when all links to peer should be removed.
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/roby/plan-object.rb', line 79 def forget_peer(peer) if !root_object? raise ArgumentError, "#{self} is not root" end each_plan_child do |child| child.forget_peer(peer) end super end |
#read_write? ⇒ Boolean
True if this object can be modified by the local plan manager
225 226 227 228 229 230 231 232 233 234 |
# File 'lib/roby/plan-object.rb', line 225 def read_write? if (owners.include?(Distributed) || Distributed.updating?(root_object) || !plan) true elsif plan.owners.include?(Distributed) for peer in owners return false unless plan.owners.include?(peer) end true end end |
#remotely_useful? ⇒ Boolean
True if this object is useful for one of our peers
59 |
# File 'lib/roby/plan-object.rb', line 59 def remotely_useful?; (plan && plan.remotely_useful?) || super end |
#removing_child_object(child, type) ⇒ Object
Checks if we have the right to remove a relation. Raises OwnershipError if it is not the case
238 239 240 241 242 243 244 |
# File 'lib/roby/plan-object.rb', line 238 def removing_child_object(child, type) super if defined? super unless read_write? || child.read_write? raise OwnershipError, "cannot remove a relation between two objects we don't own" end end |
#replace_by(object) ⇒ Object
Replaces self by object in all graphs self is part of. Unlike BGL::Vertex#replace_by, this calls the various add/remove hooks defined in DirectedRelationSupport
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/roby/plan-object.rb', line 203 def replace_by(object) changes = [] each_relation do |rel| parents = [] each_parent_object(rel) do |parent| unless parent.root_object == root_object parents << parent << parent[self, rel] end end children = [] each_child_object(rel) do |child| unless child.root_object == root_object children << child << self[child, rel] end end changes << rel << parents << children end apply_relation_changes(object, changes) end |
#replace_subplan_by(object) ⇒ Object
Replaces, in the plan, the subplan generated by this plan object by the one generated by object. In practice, it means that we transfer all parent edges whose target is self from the receiver to object. It calls the various add/remove hooks defined in DirectedRelationSupport.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/roby/plan-object.rb', line 185 def replace_subplan_by(object) changes = [] each_relation do |rel| parents = [] each_parent_object(rel) do |parent| unless parent.root_object == root_object parents << parent << parent[self, rel] end end changes << rel << parents << [] end apply_relation_changes(object, changes) end |
#root_object ⇒ Object
Return the root plan object for this object.
100 |
# File 'lib/roby/plan-object.rb', line 100 def root_object; self end |
#root_object? ⇒ Boolean
True if this object is a root object in the plan.
102 |
# File 'lib/roby/plan-object.rb', line 102 def root_object?; root_object == self end |
#subscribed? ⇒ Boolean
True if we are explicitely subscribed to this object
44 45 46 47 48 49 50 51 52 |
# File 'lib/roby/plan-object.rb', line 44 def subscribed? if root_object? (plan && plan.subscribed?) || (!self_owned? && owners.any? { |peer| peer.subscribed_plan? }) || super else root_object.subscribed? end end |