Class: Card::ActManager::StageDirector

Inherits:
Object
  • Object
show all
Includes:
Stage, Phases
Defined in:
lib/card/act_manager/stage_director.rb,
lib/card/act_manager/stage_director/phases.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

StageSubdirector

Defined Under Namespace

Modules: Phases

Constant Summary

Constants included from Stage

Card::ActManager::Stage::STAGES, Card::ActManager::Stage::STAGE_INDEX

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Phases

#integration_phase, #storage_phase, #validation_phase

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.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/card/act_manager/stage_director.rb', line 58

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]
  @call_after_store = []
  @main = main
  @subdirectors = SubdirectorArray.initialize_with_subcards(self)
  register
end

Instance Attribute Details

#actObject

Returns the value of attribute act.



52
53
54
# File 'lib/card/act_manager/stage_director.rb', line 52

def act
  @act
end

#cardObject

Returns the value of attribute card.



52
53
54
# File 'lib/card/act_manager/stage_director.rb', line 52

def card
  @card
end

#mainObject Also known as: main?

Returns the value of attribute main.



52
53
54
# File 'lib/card/act_manager/stage_director.rb', line 52

def main
  @main
end

#parentObject

Returns the value of attribute parent.



52
53
54
# File 'lib/card/act_manager/stage_director.rb', line 52

def parent
  @parent
end

#prior_storeObject

Returns the value of attribute prior_store.



52
53
54
# File 'lib/card/act_manager/stage_director.rb', line 52

def prior_store
  @prior_store
end

#runningObject (readonly) Also known as: running?

Returns the value of attribute running.



54
55
56
# File 'lib/card/act_manager/stage_director.rb', line 54

def running
  @running
end

#stageObject

Returns the value of attribute stage.



52
53
54
# File 'lib/card/act_manager/stage_director.rb', line 52

def stage
  @stage
end

#subdirectorsObject

Returns the value of attribute subdirectors.



52
53
54
# File 'lib/card/act_manager/stage_director.rb', line 52

def subdirectors
  @subdirectors
end

#transact_in_stageObject

Returns the value of attribute transact_in_stage.



52
53
54
# File 'lib/card/act_manager/stage_director.rb', line 52

def transact_in_stage
  @transact_in_stage
end

Instance Method Details

#abortObject



134
135
136
# File 'lib/card/act_manager/stage_director.rb', line 134

def abort
  @abort = true
end

#call_after_store(&block) ⇒ Object



138
139
140
# File 'lib/card/act_manager/stage_director.rb', line 138

def call_after_store &block
  @call_after_store << block
end

#catch_up_to_stage(next_stage) ⇒ Object



98
99
100
101
102
103
104
105
106
107
# File 'lib/card/act_manager/stage_director.rb', line 98

def catch_up_to_stage next_stage
  if @transact_in_stage
    return if @transact_in_stage != next_stage

    next_stage = :integrate_with_delay
  end
  upto_stage(next_stage) do |stage|
    run_single_stage stage
  end
end

#deleteObject



85
86
87
88
89
90
# File 'lib/card/act_manager/stage_director.rb', line 85

def delete
  @card.director = nil
  @subdirectors.clear
  @stage = nil
  @action = nil
end

#finished_stage?(stage) ⇒ Boolean

Returns:

  • (Boolean)


174
175
176
# File 'lib/card/act_manager/stage_director.rb', line 174

def finished_stage? stage
  @stage > stage_index(stage)
end

#main_directorObject



151
152
153
154
155
156
157
# File 'lib/card/act_manager/stage_director.rb', line 151

def main_director
  if main?
    self
  else
    ActManager.act_director || (@parent&.main_director)
  end
end

#need_actObject



142
143
144
145
146
147
148
149
# File 'lib/card/act_manager/stage_director.rb', line 142

def need_act
  act_director = main_director
  unless act_director
    raise Card::Error, "act requested without a main stage director"
  end

  @act = act_director.act ||= ActManager.need_act
end

#prepare_for_phasesObject



92
93
94
95
96
# File 'lib/card/act_manager/stage_director.rb', line 92

def prepare_for_phases
  @card.prepare_for_phases unless @prepared
  @prepared = true
  @subdirectors.each(&:prepare_for_phases)
end

#registerObject



77
78
79
# File 'lib/card/act_manager/stage_director.rb', line 77

def register
  ActManager.add self
end

#replace_card(card) ⇒ Object



123
124
125
126
127
128
# File 'lib/card/act_manager/stage_director.rb', line 123

def replace_card card
  card.action = @card.action
  card.director = self
  @card = card
  rerun_up_to_current_stage
end

#rerun_up_to_current_stageObject



117
118
119
120
121
# File 'lib/card/act_manager/stage_director.rb', line 117

def rerun_up_to_current_stage
  old_stage = @stage
  reset_stage
  catch_up_to_stage old_stage if old_stage
end

#reset_stageObject



130
131
132
# File 'lib/card/act_manager/stage_director.rb', line 130

def reset_stage
  @stage = -1
end

#run_delayed_event(act) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/card/act_manager/stage_director.rb', line 109

def run_delayed_event act
  @running = true
  @act = act
  @stage = stage_index(:integrate_with_delay)
  yield
  run_subdirector_stages :integrate_with_delay
end

#to_s(level = 1) ⇒ Object



159
160
161
162
163
164
165
166
# File 'lib/card/act_manager/stage_director.rb', line 159

def to_s level=1
  str = @card.name.to_s.clone
  if @subdirectors.present?
    subs = subdirectors.map { |d| "  " * level + d.to_s(level + 1) }.join "\n"
    str << "\n#{subs}"
  end
  str
end

#unregisterObject



81
82
83
# File 'lib/card/act_manager/stage_director.rb', line 81

def unregister
  ActManager.delete self
end

#update_card(card) ⇒ Object



168
169
170
171
172
# File 'lib/card/act_manager/stage_director.rb', line 168

def update_card card
  old_card = @card
  @card = card
  ActManager.card_changed old_card
end