Class: Roby::AndGenerator
- Inherits:
-
EventGenerator
- Object
- DistributedObject
- PlanObject
- EventGenerator
- Roby::AndGenerator
- Defined in:
- lib/roby/and_generator.rb
Overview
Combine event generators using an AND. The generator will emit once all its source events have emitted, and become unreachable if any of its source events have become unreachable.
For instance,
a = task1.start_event
b = task2.start_event
(a & b) # will emit when both tasks have started
And events will emit only once, unless #reset is called:
a = task1.intermediate_event
b = task2.intermediate_event
and_ev = (a & b)
a.intermediate_event!
b.intermediate_event! # and_ev emits here
a.intermediate_event!
b.intermediate_event! # and_ev does *not* emit
and_ev.reset
a.intermediate_event!
b.intermediate_event! # and_ev emits here
The AndGenerator tracks its sources via the signalling relations, so
and_ev << c.intermediate_event
is equivalent to
c.intermediate_event.add_signal and_ev
Instance Attribute Summary
Attributes inherited from EventGenerator
#command, #event_model, #history, #unreachability_reason, #unreachable_handlers
Attributes inherited from PlanObject
#addition_time, #executable, #execution_engine, #finalization_handlers, #finalization_time, #model, #plan, #promise_executor, #removed_at
Attributes included from Transaction::Proxying::Cache
#transaction_forwarder_module, #transaction_proxy_module
Attributes included from Relations::DirectedRelationSupport
Attributes inherited from DistributedObject
Instance Method Summary collapse
-
#<<(generator) ⇒ Object
Add a new source to this generator.
-
#added_signal_parent(parent, info) ⇒ Object
Adds a new source to
events
when a source event is added. -
#emit_if_achieved(context) ⇒ Object
Helper method that will emit the event if all the sources are emitted.
-
#empty? ⇒ Boolean
True if the generator has no sources.
-
#events ⇒ Object
The set of source events.
-
#initialize ⇒ AndGenerator
constructor
A new instance of AndGenerator.
-
#removed_signal_parent(parent) ⇒ Object
Removes a source from
events
when the source is removed. -
#reset ⇒ Object
After this call, the AndGenerator will emit as soon as all its source events have been emitted again.
-
#waiting ⇒ Object
The set of generators that have not been emitted yet.
Methods inherited from EventGenerator
#&, #achieve_asynchronously, #achieve_with, #add_child_object, #call, #call_handlers, #call_unreachable_handlers, #call_without_propagation, #called, #calling, #cancel, #check_call_validity, #check_call_validity_after_calling, #check_emission_validity, #clear_pending, #controlable?, #create_transaction_proxy, #default_command, #delay, #each_precondition, #emit, #emit_failed, #emit_without_propagation, #emitting, #filter, #finalized!, #fire, #fired, #forward, #forward_once, #forward_to, #forward_to_once, #forwarded_to?, #garbage!, #happened?, #if_unreachable, #initialize_copy, #initialize_replacement, #last, #mark_unreachable!, match, #match, #model, #name, #new, #on, #once, #pending, #plan=, #precondition, #pretty_print, #realize_with, #related_events, #related_tasks, #replace_by, #signal, #signals, #signals_once, #to_event, #to_execution_exception, #to_execution_exception_matcher, #unreachable!, #unreachable_without_propagation, #until, #when_unreachable, #|
Methods included from DRoby::Identifiable
Methods included from DRoby::V5::DRobyConstant::Dump
#droby_dump, #droby_marshallable?
Methods included from DRoby::V5::EventGeneratorDumper
Methods included from GUI::RelationsCanvasEventGenerator
#display, #display_create, #display_name, #display_time_end, #display_time_start, priorities, style, styles
Methods included from GUI::RelationsCanvasPlanObject
#display, #display_create, #display_events, #display_name, #display_parent
Methods inherited from PlanObject
#add_child_object, #apply_relation_changes, #as_plan, #can_finalize?, #commit_transaction, #concrete_model, #connection_space, #each_finalization_handler, #each_in_neighbour_merged, #each_out_neighbour_merged, #each_plan_child, #engine, #executable?, #finalized!, #finalized?, #forget_peer, #fullfills?, #garbage!, #garbage?, #initialize_copy, #initialize_replacement, #merged_relations, #promise, #read_write?, #real_object, #remotely_useful?, #replace_by, #replace_subplan_by, #root_object, #root_object?, #subscribed?, #transaction_proxy?, #transaction_stack, #update_on?, #updated_by?, #when_finalized
Methods included from Models::PlanObject
#child_plan_object, #finalization_handler, #match, #when_finalized
Methods included from GUI::GraphvizPlanObject
#apply_layout, #dot_label, #to_dot
Methods included from Relations::DirectedRelationSupport
#[], #[]=, #add_child_object, #add_parent_object, #child_object?, #child_objects, #clear_vertex, #each_child_object, #each_in_neighbour, #each_out_neighbour, #each_parent_object, #each_relation, #each_relation_graph, #each_relation_sorted, #each_root_relation_graph, #enum_child_objects, #enum_parent_objects, #enum_relations, #leaf?, #parent_object?, #parent_objects, #related_object?, #related_objects, #relation_graph_for, #relations, #remove_child_object, #remove_children, #remove_parent_object, #remove_parents, #remove_relations, #root?, #sorted_relations
Methods inherited from DistributedObject
#add_owner, #clear_owners, #initialize_copy, #owned_by?, #remove_owner
Constructor Details
#initialize ⇒ AndGenerator
Returns a new instance of AndGenerator.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/roby/and_generator.rb', line 38 def initialize super do |context| emit_if_achieved(context) end # This hash is a event_generator => event mapping of the last # events of each event generator. We compare the event stored in # this hash with the last events of each source to know if the # source fired since it has been added to this AndGenerator @events = {} # This flag is true unless we are not waiting for the emission # anymore. @active = true end |
Instance Method Details
#<<(generator) ⇒ Object
Add a new source to this generator
129 130 131 132 |
# File 'lib/roby/and_generator.rb', line 129 def <<(generator) generator.add_signal self self end |
#added_signal_parent(parent, info) ⇒ Object
Adds a new source to events
when a source event is added
97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/roby/and_generator.rb', line 97 def added_signal_parent(parent, info) # :nodoc: super @events[parent] = parent.last # If the parent is unreachable, check that it has neither been # removed, nor it has been emitted parent.if_unreachable(cancel_at_emission: true) do |reason, event| if @events.has_key?(parent) && @events[parent] == parent.last @active = false unreachable!(reason || parent) end end end |
#emit_if_achieved(context) ⇒ Object
Helper method that will emit the event if all the sources are emitted.
81 82 83 84 85 86 87 88 89 |
# File 'lib/roby/and_generator.rb', line 81 def emit_if_achieved(context) # :nodoc: return if @events.empty? || !@active each_parent_object(EventStructure::Signal) do |source| return if @events[source] == source.last end @active = false emit(nil) end |
#empty? ⇒ Boolean
True if the generator has no sources
92 93 94 |
# File 'lib/roby/and_generator.rb', line 92 def empty? relation_graph_for(EventStructure::Signal).root?(self) end |
#events ⇒ Object
The set of source events
119 120 121 |
# File 'lib/roby/and_generator.rb', line 119 def events each_parent_object(EventStructure::Signal).to_set end |
#removed_signal_parent(parent) ⇒ Object
Removes a source from events
when the source is removed
112 113 114 115 116 |
# File 'lib/roby/and_generator.rb', line 112 def removed_signal_parent(parent) # :nodoc: super @events.delete(parent) emit_if_achieved(nil) end |
#reset ⇒ Object
After this call, the AndGenerator will emit as soon as all its source events have been emitted again.
Example:
a = task1.intermediate_event
b = task2.intermediate_event
and_ev = (a & b)
a.intermediate_event!
b.intermediate_event! # and_ev emits here
a.intermediate_event!
b.intermediate_event! # and_ev does *not* emit
and_ev.reset
a.intermediate_event!
b.intermediate_event! # and_ev emits here
70 71 72 73 74 75 76 77 78 |
# File 'lib/roby/and_generator.rb', line 70 def reset @active = true each_parent_object(EventStructure::Signal) do |source| @events[source] = source.last if source.respond_to?(:reset) source.reset end end end |
#waiting ⇒ Object
The set of generators that have not been emitted yet.
124 125 126 |
# File 'lib/roby/and_generator.rb', line 124 def waiting each_parent_object(EventStructure::Signal).find_all { |ev| @events[ev] == ev.last } end |