Class: Card::StageDirector
- Includes:
- Stage
- Defined in:
- lib/card/stage_director.rb
Overview
A ‘StageDirector’ executes the stages of a card when the card gets created, updated or deleted. For subcards, i.e. other cards that are changed in the same act, a StageDirector has StageSubdirectors that take care of the stages for those cards
In general a stage is executed for all involved cards before the StageDirector proceeds with the next stage. Only exception is the finalize stage. The finalize stage of a subcard is executed immediately after its store stage. When all subcards are finalized the supercard’s finalize stage is executed.
If a subcard is added in a stage then it catches up at the end of the stage to the current stage. For example if you add a subcard in a card’s :prepare_to_store stage then after that stage the stages :initialize, :prepare_to_validate, :validate and :prepare_to_store are executed for the subcard.
Stages are executed with pre-order depth-first search. That means if A has subcards AA and AB; AAA is subcard of AA and ABA subcard of AB then the order of execution is A -> AA -> AAA -> AB -> ABA
A special case can happen in the store phase. If the id of a subcard is needed for a supercard (for example as left_id or as type_id) and the subcard doesn’t have an id yet (because it gets created in the same act) then the subcard’s store stage is executed before the supercard’s store stage
Direct Known Subclasses
Constant Summary
Constants included from Stage
Card::Stage::STAGES, Card::Stage::STAGE_INDEX
Instance Attribute Summary collapse
-
#act ⇒ Object
Returns the value of attribute act.
-
#card ⇒ Object
Returns the value of attribute card.
-
#main ⇒ Object
(also: #main?)
Returns the value of attribute main.
-
#parent ⇒ Object
Returns the value of attribute parent.
-
#prior_store ⇒ Object
Returns the value of attribute prior_store.
-
#running ⇒ Object
(also: #running?)
readonly
Returns the value of attribute running.
-
#stage ⇒ Object
Returns the value of attribute stage.
-
#subdirectors ⇒ Object
Returns the value of attribute subdirectors.
Instance Method Summary collapse
- #call_after_store(&block) ⇒ Object
- #catch_up_to_stage(next_stage) ⇒ Object
- #delete ⇒ Object
-
#initialize(card, opts = {}, main = true) ⇒ StageDirector
constructor
A new instance of StageDirector.
-
#integration_phase ⇒ Object
dirty marks are gone in this phase.
- #main_director ⇒ Object
- #need_act ⇒ Object
- #prepare_for_phases ⇒ Object
- #register ⇒ Object
-
#storage_phase(&block) ⇒ Object
everything in here can use dirty marks.
- #to_s ⇒ Object
- #unregister ⇒ Object
- #validation_phase ⇒ Object
Methods included from Stage
#after?, #before?, #in?, #stage_index, #stage_ok?, #stage_symbol
Constructor Details
#initialize(card, opts = {}, main = true) ⇒ StageDirector
Returns a new instance of StageDirector.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/card/stage_director.rb', line 42 def initialize card, opts={}, main=true @card = card @card.director = self # for read actions there is no validation phase # so we have to set the action here @card.identify_action @stage = nil @running = false @prepared = false @parent = opts[:parent] # has card to be stored before the supercard? @prior_store = opts[:priority] @main = main @subdirectors = SubdirectorArray.initialize_with_subcards(self) register end |
Instance Attribute Details
#act ⇒ Object
Returns the value of attribute act.
36 37 38 |
# File 'lib/card/stage_director.rb', line 36 def act @act end |
#card ⇒ Object
Returns the value of attribute card.
36 37 38 |
# File 'lib/card/stage_director.rb', line 36 def card @card end |
#main ⇒ Object Also known as: main?
Returns the value of attribute main.
36 37 38 |
# File 'lib/card/stage_director.rb', line 36 def main @main end |
#parent ⇒ Object
Returns the value of attribute parent.
36 37 38 |
# File 'lib/card/stage_director.rb', line 36 def parent @parent end |
#prior_store ⇒ Object
Returns the value of attribute prior_store.
36 37 38 |
# File 'lib/card/stage_director.rb', line 36 def prior_store @prior_store end |
#running ⇒ Object (readonly) Also known as: running?
Returns the value of attribute running.
38 39 40 |
# File 'lib/card/stage_director.rb', line 38 def running @running end |
#stage ⇒ Object
Returns the value of attribute stage.
36 37 38 |
# File 'lib/card/stage_director.rb', line 36 def stage @stage end |
#subdirectors ⇒ Object
Returns the value of attribute subdirectors.
36 37 38 |
# File 'lib/card/stage_director.rb', line 36 def subdirectors @subdirectors end |
Instance Method Details
#call_after_store(&block) ⇒ Object
117 118 119 120 |
# File 'lib/card/stage_director.rb', line 117 def call_after_store &block @call_after_store ||= [] @call_after_store << block end |
#catch_up_to_stage(next_stage) ⇒ Object
110 111 112 113 114 115 |
# File 'lib/card/stage_director.rb', line 110 def catch_up_to_stage next_stage @stage ||= -1 (@stage + 1).upto(stage_index(next_stage)) do |i| run_single_stage stage_symbol(i) end end |
#delete ⇒ Object
68 69 70 71 72 73 |
# File 'lib/card/stage_director.rb', line 68 def delete @card.director = nil @subdirectors.clear @stage = nil @action = nil end |
#integration_phase ⇒ Object
dirty marks are gone in this phase
101 102 103 104 105 106 107 108 |
# File 'lib/card/stage_director.rb', line 101 def integration_phase run_single_stage :integrate run_single_stage :integrate_with_delay rescue => e # don't rollback Card::Error.current = e @card.notable_exception_raised return false end |
#main_director ⇒ Object
131 132 133 134 135 136 137 |
# File 'lib/card/stage_director.rb', line 131 def main_director if main? self else DirectorRegister.act_director || (@parent && @parent.main_director) end end |
#need_act ⇒ Object
122 123 124 125 126 127 128 129 |
# File 'lib/card/stage_director.rb', line 122 def need_act act_director = main_director unless act_director raise Card::Error, 'act requested without a main stage director' end act_director.act ||= Card::Act.create(ip_address: Env.ip) @card.current_act = @act = act_director.act end |
#prepare_for_phases ⇒ Object
75 76 77 78 79 |
# File 'lib/card/stage_director.rb', line 75 def prepare_for_phases @card.prepare_for_phases unless @prepared @prepared = true @subdirectors.each(&:prepare_for_phases) end |
#register ⇒ Object
60 61 62 |
# File 'lib/card/stage_director.rb', line 60 def register Card::DirectorRegister.add self end |
#storage_phase(&block) ⇒ Object
everything in here can use dirty marks
90 91 92 93 94 95 96 97 98 |
# File 'lib/card/stage_director.rb', line 90 def storage_phase &block # for a subcard :prepare_to_store was already executed # don't execute it twice catch_up_to_stage :prepare_to_store run_single_stage :store, &block run_single_stage :finalize ensure @from_trash = nil end |
#to_s ⇒ Object
139 140 141 142 143 144 145 146 147 |
# File 'lib/card/stage_director.rb', line 139 def to_s str = @card.name.to_s.clone if @subdirectors subs = subdirectors.map(&:card) .map { |card| " #{card.name}" }.join "\n" str << "\n#{subs}" end str end |
#unregister ⇒ Object
64 65 66 |
# File 'lib/card/stage_director.rb', line 64 def unregister Card::DirectorRegister.delete self end |
#validation_phase ⇒ Object
81 82 83 84 85 86 87 |
# File 'lib/card/stage_director.rb', line 81 def validation_phase run_single_stage :initialize run_single_stage :prepare_to_validate run_single_stage :validate @card.expire_pieces if @card.errors.any? @card.errors.empty? end |