Module: Card::Set::Abstract::Machine

Extended by:
Card::Set
Defined in:
tmpsets/set/mod011-machines/abstract/machine.rb

Defined Under Namespace

Modules: MachineClassMethods

Constant Summary

Constants included from Format

Format::TEMPLATE_DIR

Class Method Summary collapse

Instance Method Summary collapse

Methods included from I18nScope

#mod_name, #scope

Methods included from Loader

#clean_empty_module_from_hash, #clean_empty_modules, #extended, #process_base_modules, #register_set

Methods included from Helpers

#abstract_set?, #all_set?, #num_set_parts, #shortname

Methods included from Card::Set::AdvancedApi

#attachment, #ensure_set, #stage_method

Methods included from Format

#all_set_format_mod!, #before, #define_on_format, #format, #register_set_format, #view, #view_for_override

Methods included from Inheritance

#include_set, #include_set_formats

Methods included from Basket

#abstract_basket, #add_to_basket, #basket

Methods included from Trait

#card_accessor, #card_reader, #card_writer

Methods included from Event::Api

#event

Class Method Details

.define_machine_events(host_class) ⇒ Object



76
77
78
79
80
81
82
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 76

def define_machine_events host_class
  event_suffix = host_class.name.tr ":", "_"
  event_name = "reset_machine_output_#{event_suffix}".to_sym
  host_class.event event_name, after: :expire_related, on: :save do
    reset_machine_output
  end
end

.define_machine_views(host_class) ⇒ Object



84
85
86
87
88
89
90
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 84

def define_machine_views host_class
  host_class.format do
    view :machine_output_url do |_args|
      machine_output_url
    end
  end
end

.included(host_class) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 61

def included host_class
  host_class.extend(MachineClassMethods)
  host_class.output_config = { filetype: "txt" }

  # for compatibility with old migrations
  return unless  Codename[:machine_output]

  host_class.card_accessor :machine_output, type: :file
  host_class.card_accessor :machine_input, type: :pointer

  set_default_machine_behaviour host_class
  define_machine_views host_class
  define_machine_events host_class
end

.set_default_input_collection_method(host_class) ⇒ Object



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
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 119

def set_default_input_collection_method host_class
  host_class.collect_input_cards do
    # traverse through all levels of pointers and
    # collect all item cards as input
    items = [self]
    new_input = []
    already_extended = {} # avoid loops
    loop_limit = 5
    until items.empty?
      item = items.shift
      next if item.trash || already_extended[item.id].to_i > loop_limit
      if item.item_cards == [item] # no pointer card
        new_input << item
      else
        # item_cards instantiates non-existing cards
        # we don't want those
        items.insert(0, item.item_cards.reject(&:unknown?))
        items.flatten!

        new_input << item if item != self && item.known?
        already_extended[item] = already_extended[item].to_i + 1
      end
    end
    new_input
  end
end

.set_default_input_preparation_method(host_class) ⇒ Object



99
100
101
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 99

def set_default_input_preparation_method host_class
  host_class.prepare_machine_input {}
end

.set_default_machine_behaviour(host_class) ⇒ Object



92
93
94
95
96
97
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 92

def set_default_machine_behaviour host_class
  set_default_input_collection_method host_class
  set_default_input_preparation_method host_class
  set_default_output_storage_method host_class
  host_class.machine_engine { |input| input }
end

.set_default_output_storage_method(host_class) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 103

def set_default_output_storage_method host_class
  host_class.store_machine_output do |output|
    filetype = host_class.output_config[:filetype]
    file = Tempfile.new [id.to_s, ".#{filetype}"]
    file.write output
    file.rewind
    Card::Auth.as_bot do
      p = machine_output_card
      p.file = file
      p.save!
    end
    file.close
    file.unlink
  end
end

Instance Method Details

#cache_output_part(input_card, output) ⇒ Object



177
178
179
180
181
182
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 177

def cache_output_part input_card, output
  Auth.as_bot do
    cache_card = fetch_cache_card(input_card, true)
    cache_card.update_attributes! content: output
  end
end

#ensure_machine_outputObject



269
270
271
272
273
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 269

def ensure_machine_output
  output = fetch trait: :machine_output
  return if output && output.selected_content_action_id
  update_machine_output
end

#fetch_cache_card(input_card, new = nil) ⇒ Object



172
173
174
175
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 172

def fetch_cache_card input_card, new=nil
  new &&= { type_id: PlainTextID }
  Card.fetch input_card.name, name, :machine_cache, new: new
end

#input_item_cardsObject



254
255
256
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 254

def input_item_cards
  machine_input_card.item_cards
end

#lockObject



217
218
219
220
221
222
223
224
225
226
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 217

def lock
  if ok?(:read) && !(was_already_locked = locked?)
    Auth.as_bot do
      lock!
      yield
    end
  end
ensure
  unlock! unless was_already_locked
end

#lock!Object



236
237
238
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 236

def lock!
  Card.cache.write lock_cache_key, true
end

#lock_cache_keyObject



228
229
230
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 228

def lock_cache_key
  "UPDATE-LOCK:#{key}"
end

#locked?Boolean

Returns:

  • (Boolean)


232
233
234
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 232

def locked?
  Card.cache.read lock_cache_key
end

#machine_output_pathObject



264
265
266
267
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 264

def machine_output_path
  ensure_machine_output
  machine_output_card.file.path
end

#machine_output_urlObject



258
259
260
261
262
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 258

def machine_output_url
  ensure_machine_output
  machine_output_card.file.url # (:default, timestamp: false)
  # to get rid of additional number in url
end

#make_machine_output_coded(mod = :machines) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 198

def make_machine_output_coded mod=:machines
  update_machine_output
  Auth.as_bot do
    output_codename =
      machine_output_card.cardname.parts.map do |part|
        Card[part].codename || Card[part].cardname.safe_key
      end.join '_'
    machine_output_card.update_attributes! codename: output_codename,
                                           storage_type: :coded,
                                           mod: mod
  end
end

#regenerate_machine_outputObject



211
212
213
214
215
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 211

def regenerate_machine_output
  lock do
    run_machine
  end
end

#reset_machine_outputObject



184
185
186
187
188
189
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 184

def reset_machine_output
  Auth.as_bot do
    (moc = machine_output_card) && moc.real? && moc.delete!
    update_input_card
  end
end

#run_engine(input_card) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 156

def run_engine input_card
  return if input_card.is_a? Card::Set::Type::Pointer
  if (cached = fetch_cache_card(input_card))
    return cached.content
  end

  input = if input_card.respond_to? :machine_input
            input_card.machine_input
          else
            input_card.format._render_raw
          end
  output = engine(input)
  cache_output_part input_card, output
  output
end

#run_machine(joint = "\n") ⇒ Object



147
148
149
150
151
152
153
154
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 147

def run_machine joint="\n"
  before_engine
  output =
    input_item_cards.map do |input_card|
      run_engine input_card
    end.select(&:present?).join(joint)
  after_engine output
end

#unlock!Object



240
241
242
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 240

def unlock!
  Card.cache.write lock_cache_key, false
end

#update_input_cardObject



244
245
246
247
248
249
250
251
252
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 244

def update_input_card
  if DirectorRegister.running_act?
    input_card = attach_subcard! machine_input_card
    input_card.content = ""
    engine_input.each { |input| input_card << input }
  else
    machine_input_card.items = engine_input
  end
end

#update_machine_outputObject



191
192
193
194
195
196
# File 'tmpsets/set/mod011-machines/abstract/machine.rb', line 191

def update_machine_output
  lock do
    update_input_card
    run_machine
  end
end