Class: Seh::Event
- Inherits:
-
OpenStruct
- Object
- OpenStruct
- Seh::Event
- Defined in:
- lib/seh/event.rb
Instance Method Summary collapse
-
#abort ⇒ Object
Abort this Event.
-
#aborted? ⇒ Boolean
True if #abort has been called, false otherwise.
-
#add_stage(new_stage, &stage_decision_block) ⇒ Object
Add the passed new stage to this event.
-
#bind(stage, &block) ⇒ Object
Bind the passed block as a callback for the passed stage.
-
#dispatch ⇒ Object
Dispatch this event, notifying all targets of the event and executing any callbacks.
-
#finish(&block) ⇒ Object
Bind the passed block as a finish callback.
-
#initialize {|_self| ... } ⇒ Event
constructor
A new instance of Event.
-
#match_type?(event_type) ⇒ Boolean
Return true if this event's types match the passed EventType.
-
#start(&block) ⇒ Object
Bind the passed block as a start callback.
-
#target(*targets) ⇒ Object
Add targets to this event.
-
#type(*event_types) ⇒ Object
Add event types to this event.
Constructor Details
#initialize {|_self| ... } ⇒ Event
Returns a new instance of Event.
6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/seh/event.rb', line 6 def initialize super @state = :ready @types = Set.new @targets = Set.new @start_callbacks = [] @finish_callbacks = [] @stage_callbacks = {} @stage_decision_blocks = {} @stages = Set.new @abort = false yield self if block_given? end |
Instance Method Details
#abort ⇒ Object
Abort this Event. After #abort is called, some in-progress work may still be completed. Abort semantics:
- if #abort is called before #dispatch, #dispatch return immediately, no target will know the event occurred, and no callbacks will be executed
- if #abort is called by a target while visiting the set of targets, each target will still receive the event but no stage callbacks will be exewcuted
- if #abort is called during start callbacks, start will complete and no stage or finish callbacks will be run
- if #abort is called during a stage callback, the current stage will complete and no other stage or finish callbacks will be run
- if #abort is called during a finish callback, finish will complete, i.e. calling #abort during a finish callbacks is fairly pointless
50 51 52 53 |
# File 'lib/seh/event.rb', line 50 def abort @abort = true nil end |
#aborted? ⇒ Boolean
Returns true if #abort has been called, false otherwise.
56 57 58 |
# File 'lib/seh/event.rb', line 56 def aborted? @abort end |
#add_stage(new_stage, &stage_decision_block) ⇒ Object
Add the passed new stage to this event
82 83 84 85 86 87 88 |
# File 'lib/seh/event.rb', line 82 def add_stage new_stage, &stage_decision_block raise "Event#add_stage is disallowed after Event#dispatch is called" unless @state == :ready @stages << new_stage @stage_callbacks[new_stage] ||= [] @stage_decision_blocks[new_stage] = stage_decision_block if block_given? nil end |
#bind(stage, &block) ⇒ Object
Bind the passed block as a callback for the passed stage
102 103 104 105 |
# File 'lib/seh/event.rb', line 102 def bind stage, &block @stage_callbacks[stage] << block if block_given? nil end |
#dispatch ⇒ Object
Dispatch this event, notifying all targets of the event and executing any callbacks. #dispatch may only be called once Dispatch algorithm:
-
determine the full set of targets affected by this event
-
run callbacks on targets which match this event's types
-
run stage callbacks contained in this event; typically targets will append stage callbacks to this event using Event#bind, #start, #finish Callback execution order:
start callbacks stage callabcks - in the order stages were added finish callbacksCallbacks in the same stage have arbitrary execution order
32 33 34 35 36 37 38 39 40 |
# File 'lib/seh/event.rb', line 32 def dispatch raise "Event#dispatch may only be called once" unless @state == :ready @state = :inflight return if @abort run_target_callbacks run_stage_callbacks @state = :done nil end |
#finish(&block) ⇒ Object
Bind the passed block as a finish callback
118 119 120 121 |
# File 'lib/seh/event.rb', line 118 def finish &block @finish_callbacks << block if block_given? nil end |
#match_type?(event_type) ⇒ Boolean
Return true if this event's types match the passed EventType
93 94 95 96 |
# File 'lib/seh/event.rb', line 93 def match_type? event_type event_type = EventType.new event_type unless event_type.is_a? EventType event_type.match @types end |
#start(&block) ⇒ Object
Bind the passed block as a start callback
110 111 112 113 |
# File 'lib/seh/event.rb', line 110 def start &block @start_callbacks << block if block_given? nil end |
#target(*targets) ⇒ Object
Add targets to this event. May not be called after or during #dispatch
63 64 65 66 67 |
# File 'lib/seh/event.rb', line 63 def target *targets raise "Event#target is disallowed after Event#dispatch is called" unless @state == :ready targets.each { |target| @targets << target } nil end |
#type(*event_types) ⇒ Object
Add event types to this event. May not be called after or during #dispatch
72 73 74 75 76 |
# File 'lib/seh/event.rb', line 72 def type *event_types raise "Event#type is disallowed after Event#dispatch is called" unless @state == :ready event_types.each { |type| @types << type } nil end |