Class: Inform::Object
- Inherits:
-
Sequel::Model
show all
- Includes:
- Context, Events, Genealogical, Linkable, Modular, Prototypical, Taggable, StoryTeller::Builtins, StoryTeller::Daemons, StoryTeller::IO, StoryTeller::Publisher
- Defined in:
- lib/story_teller/inform/models.rb,
lib/story_teller/inform/relational/object.rb
Overview
The Inform::Object class rubocop: disable Metrics/ClassLength
Constant Summary
collapse
- Visited =
defined?(ConcurrentHashMap) ? ConcurrentHashMap.new : {}
- ExportFileNameTemplate =
'%<name>s-%<id>s.%<ext>s'.freeze
- JsonOptions =
{
include: %i[tagged modularized]
}.freeze
- XmlOptions =
{
except: :id,
include: {
tagged: {
except: :id
},
modularized: {
except: :id
}
}
}.freeze
- XmlFileNameTemplate =
'%<name>s-%<id>s.json'.freeze
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Modular
#after_initialize, #apply_modules, #mod, #modules, #modules_semaphore, #nil_safe_modules, #reset_modules, #unmod
Methods included from Linkable
#_set_object, #find_link, #link, #linked?, #links, #linksfrom, #linkto, #unlink
implicit_table_name
included
Constructor Details
#initialize(*args, &block) ⇒ Object
rubocop: disable Metrics/MethodLength
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
# File 'lib/story_teller/inform/relational/object.rb', line 103
def initialize(*args, &block)
if args.empty?
super(&nil)
elsif args.first.is_a?(String)
short_name = args.first
super({ name: short_name, short_name: short_name }, &nil)
else
super(*args, &nil)
end
save
@tags_semaphore = Mutex.new
@semaphore = Mutex.new
self.with(&block) unless block.nil?
log.debug "Initializing #{self}"
end
|
Class Method Details
.fetch_or_create_by_name(name) ⇒ Object
rubocop: enable Metrics/MethodLength
120
121
122
123
124
125
|
# File 'lib/story_teller/inform/relational/object.rb', line 120
def self.fetch_or_create_by_name(name)
key = name.to_s
object = first(name: key)
object ||= all.find { |candidate| candidate.name_values.include?(key) }
object || new(key)
end
|
Instance Method Details
rubocop: disable Metrics/AbcSize rubocop: disable Metrics/CyclomaticComplexity rubocop: disable Metrics/MethodLength rubocop: disable Metrics/PerceivedComplexity TODO: Implement a unit test for this
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
# File 'lib/story_teller/inform/relational/object.rb', line 355
def <<(o)
return if o.nil?
return if o == self
if o.ephemeral?
o.parent = self
ephemeral_children << o
else
self.add_child o if self.respond_to?(:add_child)
o.parent_id = self.id if o.respond_to?(:parent_id=)
o.save_changes if o.respond_to?(:save_changes)
self.save
self.associations.delete(:children) if self.respond_to?(:associations)
self.refresh
end
end
|
#<=>(other) ⇒ Object
226
227
228
|
# File 'lib/story_teller/inform/relational/object.rb', line 226
def <=>(other)
self.name <=> other.name
end
|
#==(other) ⇒ Object
230
231
232
|
# File 'lib/story_teller/inform/relational/object.rb', line 230
def ==(other)
other.respond_to?(:values) ? self.values[:id] == other.values[:id] : super
end
|
#__invoke(a, *args) ⇒ Object
254
255
256
257
258
|
# File 'lib/story_teller/inform/relational/object.rb', line 254
def __invoke(a, *args)
return if inflib.nil?
inflib.__invoke(a, *args)
end
|
#_invoke(a, *args) ⇒ Object
248
249
250
251
252
|
# File 'lib/story_teller/inform/relational/object.rb', line 248
def _invoke(a, *args)
return if inflib.nil?
inflib._invoke(a, *args)
end
|
#after_clone(copy) ⇒ Object
438
439
440
|
# File 'lib/story_teller/inform/relational/object.rb', line 438
def after_clone(copy)
copy.untag :prized
end
|
#after_create ⇒ Object
287
288
289
290
291
|
# File 'lib/story_teller/inform/relational/object.rb', line 287
def after_create
super
index_words if respond_to?(:index_words)
init
end
|
#after_destroy ⇒ Object
427
428
429
|
# File 'lib/story_teller/inform/relational/object.rb', line 427
def after_destroy
super
end
|
#after_save ⇒ Object
431
432
433
434
|
# File 'lib/story_teller/inform/relational/object.rb', line 431
def after_save
super
self.modified_at = Time.now
end
|
#before_clone(copy) ⇒ Object
436
|
# File 'lib/story_teller/inform/relational/object.rb', line 436
def before_clone(copy); end
|
#before_create ⇒ Object
416
417
418
419
|
# File 'lib/story_teller/inform/relational/object.rb', line 416
def before_create
self.created_at ||= Time.now
super
end
|
#before_destroy ⇒ Object
421
422
423
424
425
|
# File 'lib/story_teller/inform/relational/object.rb', line 421
def before_destroy
self.safe_refresh if self.respond_to? :safe_refresh
self.children.each { |x| x.destroy unless x.has? :prized }
super
end
|
#child(o = nil) ⇒ Object
def empty?
begin
n = db.fetch("select count(*) from object where parent_id = #{self.id}").first[:count].to_i
rescue StandardError => e
log.error "Unexpected error getting children count for #{self.class} #{self.id}: #{e.message}", $ERROR_INFO
n = children.length
end
n == 0
end
401
402
403
404
405
406
|
# File 'lib/story_teller/inform/relational/object.rb', line 401
def child(o = nil)
return o.child unless o.nil?
return self.children_dataset.first if self.respond_to?(:children_dataset)
self.children.first
end
|
#classify_as(klass) ⇒ Object
315
316
317
318
319
320
321
322
323
324
325
|
# File 'lib/story_teller/inform/relational/object.rb', line 315
def classify_as(klass)
return if klass.nil?
klass = find_class klass unless klass.is_a? Class
self.object_type = klass.name
self.safe_save
self.safe_init
o = Inform::Object[self.id]
log.debug "o.object_type: #{o.object_type}"
return o
end
|
rubocop: disable Metrics/AbcSize rubocop: disable Metrics/MethodLength
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
|
# File 'lib/story_teller/inform/relational/object.rb', line 444
def clone
return if Session.players.include? self
data = self.values.dup
data.delete :id
data.delete :attributes
data.delete :properties
copy = self.class.new(data)
before_clone(copy) if respond_to? :before_clone
copy.properties = self.properties
copy.save
copy.untag(*copy.tags)
copy.tag(*self.tags)
copy.mod(*self.modules)
copy.link(:original, self)
self.children.each { |x| copy << x.clone }
after_clone(copy) if respond_to? :after_clone
copy
end
|
#description(*args) ⇒ Object
alias description= description
194
195
196
197
198
199
200
201
|
# File 'lib/story_teller/inform/relational/object.rb', line 194
def description(*args)
return self[:description] if args.empty?
value = args.length > 1 ? args.join : args.first
self[:description] = value
save_changes if respond_to?(:save_changes)
value
end
|
#description=(value) ⇒ Object
203
204
205
206
|
# File 'lib/story_teller/inform/relational/object.rb', line 203
def description=(value)
self[:description] = value
save_changes if respond_to?(:save_changes)
end
|
#empty? ⇒ Boolean
382
383
384
385
386
387
388
389
390
|
# File 'lib/story_teller/inform/relational/object.rb', line 382
def empty?
return false if ephemeral_children.any?
return children_dataset.count.zero? if self.respond_to?(:children_dataset)
children.empty?
rescue StandardError => e
log.error "Unexpected error getting children count for #{self.class} #{self.id}: #{e.message}", $ERROR_INFO
children.empty?
end
|
#encode_with(coder) ⇒ Object
518
519
520
521
522
|
# File 'lib/story_teller/inform/relational/object.rb', line 518
def encode_with(coder)
%w[id name short_name description properties links modularized tagged].each do |v|
coder[v] = self.send(v) if self.respond_to? v
end
end
|
#ephemeral_children ⇒ Object
if o.ephemeral?
o.parent = self
ephemeral_children << o
else
self.add_child o
self.save
self.refresh
end
end
346
347
348
|
# File 'lib/story_teller/inform/relational/object.rb', line 346
def ephemeral_children
EphemeralObjectsChildren[identity] ||= []
end
|
#export_json ⇒ Object
481
482
483
484
485
486
487
|
# File 'lib/story_teller/inform/relational/object.rb', line 481
def export_json
return unless respond_to? :to_json
self.to_json(**JsonOptions).save(
format(ExportFileNameTemplate, name: self.to_s, id: self.id, ext: :json)
)
end
|
#export_xml ⇒ Object
510
511
512
513
514
515
516
|
# File 'lib/story_teller/inform/relational/object.rb', line 510
def export_xml
return unless self.respond_to? :to_xml
self.to_xml(**XmlOptions).save(
format(ExportFileNameTemplate, name: self.to_s, id: self.id, ext: :xml)
)
end
|
#export_yaml ⇒ Object
489
490
491
492
493
494
495
|
# File 'lib/story_teller/inform/relational/object.rb', line 489
def export_yaml
return unless self.respond_to? :to_yaml
self.to_yaml.save(
format(ExportFileNameTemplate, name: self.to_s, id: self.id, ext: :yaml)
)
end
|
260
261
262
263
264
265
|
# File 'lib/story_teller/inform/relational/object.rb', line 260
def inflib
return InformLibrary[self] if self.has?(:animate) ||
defined?(Character) && self.is_a?(Character)
@inflib
end
|
#inflib=(inflib) ⇒ Object
rubocop: disable Style/TrivialAccessors
268
269
270
|
# File 'lib/story_teller/inform/relational/object.rb', line 268
def inflib=(inflib)
@inflib = inflib
end
|
293
294
295
|
# File 'lib/story_teller/inform/relational/object.rb', line 293
def init
end
|
#invoke(a, *args) ⇒ Object
242
243
244
245
246
|
# File 'lib/story_teller/inform/relational/object.rb', line 242
def invoke(a, *args)
return if inflib.nil?
inflib.invoke(a, *args)
end
|
#list_together ⇒ Object
412
413
414
|
# File 'lib/story_teller/inform/relational/object.rb', line 412
def list_together
linkto :list_together
end
|
408
409
410
|
# File 'lib/story_teller/inform/relational/object.rb', line 408
def location
linkto(:location) || self.parent
end
|
#name(*args) ⇒ Object
self.values = args.length > 1 ? args.join(‘ ’) : args
self.save
self.values[:name]
end
139
140
141
142
143
144
145
146
147
|
# File 'lib/story_teller/inform/relational/object.rb', line 139
def name(*args)
return args.first.object_name if args.first.respond_to?(:object_name)
return self.values[:name] if args.empty?
names = args.flatten
self.values[:name] = names
self.save
self.values[:name] = names
end
|
#name=(value) ⇒ Object
149
150
151
|
# File 'lib/story_teller/inform/relational/object.rb', line 149
def name=(value)
name(value)
end
|
#name_values ⇒ Object
127
128
129
|
# File 'lib/story_teller/inform/relational/object.rb', line 127
def name_values
Array(self.values[:name]).flatten.map(&:to_s)
end
|
#name_words ⇒ Object
def name_words
self.values[:name].split(/[,\s]+/).join(', ')
end
156
157
158
|
# File 'lib/story_teller/inform/relational/object.rb', line 156
def name_words
name_values.join(', ')
end
|
#object_name ⇒ Object
rubocop: enable Metrics/MethodLength
179
180
181
|
# File 'lib/story_teller/inform/relational/object.rb', line 179
def object_name
self.values[:display_name] || self.values[:short_name] || self.values[:name]
end
|
234
235
236
237
238
239
240
|
# File 'lib/story_teller/inform/relational/object.rb', line 234
def parse(s)
return if inflib.nil?
semaphore.synchronize do
inflib.parse s
end
end
|
#print_evented_zmachine_result(s, isolate: false) ⇒ Object
277
278
279
|
# File 'lib/story_teller/inform/relational/object.rb', line 277
def print_evented_zmachine_result(s, isolate: false)
inflib&.print_evented_zmachine_result(s, isolate: isolate)
end
|
#print_zmachine_result(s, should_prompt: true) ⇒ Object
rubocop: enable Style/TrivialAccessors
273
274
275
|
# File 'lib/story_teller/inform/relational/object.rb', line 273
def print_zmachine_result(s, should_prompt: true)
inflib&.print_zmachine_result(s, should_prompt:)
end
|
rubocop: enable Metrics/AbcSize rubocop: enable Metrics/CyclomaticComplexity rubocop: enable Metrics/MethodLength rubocop: enable Metrics/PerceivedComplexity
376
377
378
379
380
|
# File 'lib/story_teller/inform/relational/object.rb', line 376
def remove
self.parent.remove_child(self.id) if self.parent&.children&.include?(self)
rescue StandardError => e
log.error e
end
|
222
223
224
|
# File 'lib/story_teller/inform/relational/object.rb', line 222
def routines
((self.methods - Object.instance_methods) - Inform::Object.instance_methods).sort.uniq
end
|
#safe_init ⇒ Object
309
310
311
312
313
|
# File 'lib/story_teller/inform/relational/object.rb', line 309
def safe_init
self.init if self.respond_to? :init
rescue Sequel::NoExistingObject => e
log.warn "Object initialization failure: #{e.message}; ignoring"
end
|
#safe_refresh ⇒ Object
297
298
299
300
301
|
# File 'lib/story_teller/inform/relational/object.rb', line 297
def safe_refresh
self.refresh
rescue Sequel::NoExistingObject => e
log.warn "Object refresh failure: #{e.message}; ignoring"
end
|
#safe_save ⇒ Object
303
304
305
306
307
|
# File 'lib/story_teller/inform/relational/object.rb', line 303
def safe_save
self.save
rescue Sequel::NoExistingObject => e
log.warn "Object save failure: #{e.message}; ignoring"
end
|
#semaphore ⇒ Object
208
209
210
|
# File 'lib/story_teller/inform/relational/object.rb', line 208
def semaphore
@semaphore ||= Mutex.new
end
|
#short_name(*args) ⇒ Object
rubocop: disable Metrics/MethodLength
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# File 'lib/story_teller/inform/relational/object.rb', line 161
def short_name(*args)
unless args.empty?
self.short_name = args.first
return
end
textual_name = self.values[:short_name]
synonyms = self.values[:name]
if textual_name.nil? || (textual_name.respond_to?(:empty?) && textual_name.empty?)
self.values[:short_name] = synonyms
self.save
self.values[:short_name]
else
textual_name
end
end
|
#sysclone(klass = Inform::System::Object) ⇒ Object
rubocop: enable Metrics/AbcSize rubocop: enable Metrics/MethodLength
466
467
468
469
470
471
472
473
474
|
# File 'lib/story_teller/inform/relational/object.rb', line 466
def sysclone(klass = Inform::System::Object)
copy = klass.new self.short_name
copy.name = self.name
copy.properties[:source_id] = self.id
copy.properties = self.properties
copy.tags = self.nil_safe_tags
after_clone(copy) if respond_to? :after_clone
copy
end
|
218
219
220
|
# File 'lib/story_teller/inform/relational/object.rb', line 218
def tags
tags_semaphore.synchronize { tags_original }
end
|
216
|
# File 'lib/story_teller/inform/relational/object.rb', line 216
alias tags_original tags
|
212
213
214
|
# File 'lib/story_teller/inform/relational/object.rb', line 212
def tags_semaphore
@tags_semaphore ||= Mutex.new
end
|
283
284
285
|
# File 'lib/story_teller/inform/relational/object.rb', line 283
def visited
Visited[self] ||= []
end
|