inform-runtime 1.0.4 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +10 -12
- data/Rakefile +26 -16
- data/lib/{runtime → story_teller}/articles.rb +14 -10
- data/lib/{runtime → story_teller}/builtins.rb +50 -22
- data/lib/{runtime → story_teller}/color.rb +8 -8
- data/lib/{runtime → story_teller}/command.rb +26 -28
- data/lib/{runtime → story_teller}/context.rb +23 -24
- data/lib/story_teller/core.rb +38 -0
- data/lib/{runtime → story_teller}/daemon.rb +35 -36
- data/lib/story_teller/engine.rb +151 -0
- data/lib/story_teller/ephemeral_adapter.rb +42 -0
- data/lib/{runtime → story_teller}/events.rb +8 -9
- data/lib/{runtime → story_teller}/experimental/handler_dsl.rb +7 -18
- data/lib/story_teller/experimental/reverse_engineer_class.rb +37 -0
- data/lib/{runtime → story_teller}/grammar_parser.rb +24 -40
- data/lib/{runtime → story_teller}/helpers.rb +21 -7
- data/lib/{runtime → story_teller}/history.rb +5 -5
- data/lib/{runtime → story_teller}/inflector.rb +4 -5
- data/lib/story_teller/inform/base.rb +160 -0
- data/lib/{runtime → story_teller/inform/ephemeral}/link.rb +27 -45
- data/lib/{runtime → story_teller/inform/ephemeral}/module.rb +17 -58
- data/lib/story_teller/inform/ephemeral/object.rb +329 -0
- data/lib/{runtime → story_teller/inform/ephemeral}/tag.rb +54 -81
- data/lib/story_teller/inform/models.rb +25 -0
- data/lib/{runtime → story_teller}/io.rb +10 -10
- data/lib/{runtime → story_teller}/kernel.rb +21 -31
- data/lib/story_teller/library/bootstrap.rb +66 -0
- data/lib/story_teller/library/declarations.rb +53 -0
- data/lib/story_teller/library/directives.rb +91 -0
- data/lib/story_teller/library/loader.rb +104 -0
- data/lib/story_teller/library/location.rb +73 -0
- data/lib/{runtime → story_teller}/library.rb +27 -12
- data/lib/{runtime → story_teller}/logging.rb +47 -24
- data/lib/{runtime → story_teller}/mixins.rb +6 -6
- data/lib/story_teller/model_adapter.rb +132 -0
- data/lib/{runtime → story_teller}/plurals.rb +11 -11
- data/lib/{runtime → story_teller}/prototype.rb +11 -10
- data/lib/{runtime → story_teller}/publication.rb +9 -9
- data/lib/{runtime → story_teller}/session.rb +6 -8
- data/lib/{runtime → story_teller}/stdlib.rb +13 -11
- data/lib/{runtime → story_teller}/subscription.rb +8 -8
- data/lib/{runtime → story_teller}/tree.rb +6 -6
- data/lib/{runtime → story_teller}/version.rb +16 -6
- data/lib/story_teller/world_tree.rb +54 -0
- data/lib/story_teller.rb +26 -0
- metadata +59 -99
- data/config/database.yml +0 -37
- data/exe/inform.rb +0 -6
- data/game/config.yml +0 -5
- data/game/example.inf +0 -76
- data/game/example.rb +0 -90
- data/game/forms/example_form.rb +0 -2
- data/game/grammar/game_grammar.inf.rb +0 -11
- data/game/languages/english.rb +0 -2
- data/game/models/example_model.rb +0 -2
- data/game/modules/example_module.rb +0 -9
- data/game/rules/example_state.rb +0 -2
- data/game/scripts/example_script.rb +0 -2
- data/game/topics/example_topic.rb +0 -2
- data/game/verbs/game_verbs.rb +0 -15
- data/game/verbs/metaverbs.rb +0 -2028
- data/lib/runtime/config.rb +0 -48
- data/lib/runtime/database.rb +0 -500
- data/lib/runtime/game.rb +0 -74
- data/lib/runtime/game_loader.rb +0 -132
- data/lib/runtime/library_loader.rb +0 -135
- data/lib/runtime/object.rb +0 -761
- data/lib/runtime/options.rb +0 -104
- data/lib/runtime/persistence.rb +0 -292
- data/lib/runtime/runtime.rb +0 -321
- data/lib/runtime/world_tree.rb +0 -69
- data/lib/runtime.rb +0 -35
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# lib/story_teller/object.rb
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
# frozen_string_literal: false
|
|
4
|
+
|
|
5
|
+
# Copyright Nels Nelson 2008-2025 but freely usable (see license)
|
|
6
|
+
#
|
|
7
|
+
# This file is part of the StoryTeller.
|
|
8
|
+
#
|
|
9
|
+
# The StoryTeller is free software: you can redistribute it and/or
|
|
10
|
+
# modify it under the terms of the GNU General Public License as published
|
|
11
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
# (at your option) any later version.
|
|
13
|
+
#
|
|
14
|
+
# The StoryTeller is distributed in the hope that it will be useful,
|
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
# GNU General Public License for more details.
|
|
18
|
+
#
|
|
19
|
+
# You should have received a copy of the GNU General Public License
|
|
20
|
+
# along with the StoryTeller. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
|
|
22
|
+
# Object
|
|
23
|
+
|
|
24
|
+
# def Object(name, klass = Inform::Object, &block)
|
|
25
|
+
# obj = klass == Inform::Object ? Inform::Object.build(name) : klass.new(name)
|
|
26
|
+
# obj.with(&block) if block_given?
|
|
27
|
+
# obj.save_changes if obj.respond_to?(:save_changes)
|
|
28
|
+
# obj
|
|
29
|
+
# end
|
|
30
|
+
|
|
31
|
+
def Object(name, klass = Inform::Object, &block)
|
|
32
|
+
obj = if klass.respond_to?(:fetch_or_create_by_name)
|
|
33
|
+
klass.fetch_or_create_by_name(name)
|
|
34
|
+
else
|
|
35
|
+
klass.new(name)
|
|
36
|
+
end
|
|
37
|
+
obj.with(&block) if block_given?
|
|
38
|
+
obj.save_changes if obj.respond_to?(:save_changes)
|
|
39
|
+
obj
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# The Inform module
|
|
43
|
+
module Inform
|
|
44
|
+
# module Ephemeral
|
|
45
|
+
module Ephemeral
|
|
46
|
+
# The Inform::Ephemeral::Object class
|
|
47
|
+
# rubocop: disable Metrics/ClassLength
|
|
48
|
+
class Object < Inform::Object
|
|
49
|
+
Instances = Struct.new(:memo).new(defined?(Java) ? java.util.concurrent.CopyOnWriteArrayList.new : [])
|
|
50
|
+
attr_accessor :short_name, :display_name, :inflib, :properties, :links,
|
|
51
|
+
:modules, :tags, :created_at, :modified_at, :visited
|
|
52
|
+
|
|
53
|
+
attr_writer :description
|
|
54
|
+
attr_reader :original_description_method
|
|
55
|
+
|
|
56
|
+
# rubocop: disable Metrics/AbcSize
|
|
57
|
+
# rubocop: disable Metrics/MethodLength
|
|
58
|
+
def initialize(textual_name = nil, *args, &block)
|
|
59
|
+
super(*args)
|
|
60
|
+
@name = textual_name
|
|
61
|
+
@short_name = textual_name || format('(%<short_name>s)', short_name: self.class.name)
|
|
62
|
+
@display_name = textual_name
|
|
63
|
+
@description = nil
|
|
64
|
+
@adjectives = []
|
|
65
|
+
@properties = {}
|
|
66
|
+
@links = []
|
|
67
|
+
@modules = []
|
|
68
|
+
@tags = []
|
|
69
|
+
@children = []
|
|
70
|
+
@visited = []
|
|
71
|
+
@created_at = @modified_at = Time.now
|
|
72
|
+
index_words if respond_to?(:index_words)
|
|
73
|
+
index_obj(self)
|
|
74
|
+
@original_description_method = self.class.instance_method(:description)
|
|
75
|
+
self.with(&block) if block_given?
|
|
76
|
+
end
|
|
77
|
+
# rubocop: enable Metrics/AbcSize
|
|
78
|
+
# rubocop: enable Metrics/MethodLength
|
|
79
|
+
|
|
80
|
+
def self.fetch_or_create_by_name(object_name, klass = self)
|
|
81
|
+
Inform::EphemeralObjects.fetch(object_name) do
|
|
82
|
+
Inform::EphemeralObjects[object_name] = klass.create(object_name)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.create(name = nil, object_type: nil, parent_id: nil, properties: {}, klass: self)
|
|
87
|
+
klass.new(name).tap do |obj|
|
|
88
|
+
obj.object_type = object_type
|
|
89
|
+
obj.parent_id = parent_id
|
|
90
|
+
obj.properties.merge!(properties)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def values
|
|
95
|
+
{
|
|
96
|
+
name: @name,
|
|
97
|
+
short_name: @short_name,
|
|
98
|
+
description: @description,
|
|
99
|
+
properties: @properties
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def index_obj(obj)
|
|
104
|
+
if Instances.memo.respond_to?(:add)
|
|
105
|
+
Instances.memo.add(obj)
|
|
106
|
+
else
|
|
107
|
+
Instances.memo << obj
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def self.all
|
|
112
|
+
Instances.memo.dup
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def self.clear
|
|
116
|
+
Instances.memo.clear
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def [](property)
|
|
120
|
+
return description if property == :description
|
|
121
|
+
return name if property == :name
|
|
122
|
+
return short_name if property == :short_name
|
|
123
|
+
properties[property]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def to_hash
|
|
127
|
+
properties.merge(
|
|
128
|
+
id: id,
|
|
129
|
+
name: name,
|
|
130
|
+
short_name: short_name,
|
|
131
|
+
description: description
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def <=>(other)
|
|
136
|
+
self.name <=> other.name
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def parse(s)
|
|
140
|
+
return if inflib.nil?
|
|
141
|
+
inflib.semaphore.synchronize do
|
|
142
|
+
inflib.println(inflib.parse(s))
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def id
|
|
147
|
+
self.object_id
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def object_type
|
|
151
|
+
self.class
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def name(*args)
|
|
155
|
+
return args.first.object_name if args.first.respond_to?(:object_name)
|
|
156
|
+
return @name if args.empty?
|
|
157
|
+
@name = ([@name] | args).flatten.uniq
|
|
158
|
+
index_words if respond_to?(:index_words)
|
|
159
|
+
@name
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def name=(*args)
|
|
163
|
+
return if args.empty?
|
|
164
|
+
@name = args.first.object_name if args.first.respond_to?(:object_name)
|
|
165
|
+
@name = ([@name] | args).flatten.uniq
|
|
166
|
+
index_words if respond_to?(:index_words)
|
|
167
|
+
return
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def description(*args)
|
|
171
|
+
return @description if args.nil? || args.empty?
|
|
172
|
+
@description = args.length > 1 ? args.join(' ') : args.first
|
|
173
|
+
@description
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def object_name
|
|
177
|
+
@display_name || @short_name || @name
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def name_words
|
|
181
|
+
@name.split(/[,\s]+/).join(', ')
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def <<(o)
|
|
185
|
+
return if self == o
|
|
186
|
+
return unless o.object?
|
|
187
|
+
o.parent = self
|
|
188
|
+
@children << o
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def remove
|
|
192
|
+
@children.clear
|
|
193
|
+
@parent = nil
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def empty?(*args, &block)
|
|
197
|
+
self.children.empty?(*args, &block)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def children(o = nil, prop = :@children)
|
|
201
|
+
return @children if o.nil?
|
|
202
|
+
return o.instance_variable_get(prop).length if o.instance_variable_defined?(prop)
|
|
203
|
+
o.children.length
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# TODO: Remove if possible after unit test implementation
|
|
207
|
+
def location
|
|
208
|
+
self.parent
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def list_together
|
|
212
|
+
linkto :list_together
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def ancestors
|
|
216
|
+
self.parent.nil? ? [] : self.parent.ancestors + [self.parent]
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def descendants
|
|
220
|
+
@children + @children.map(&:descendants).flatten
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def root
|
|
224
|
+
self.parent.nil? ? self : self.parent.root
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def parent(o = nil, &block)
|
|
228
|
+
return @parent if o.nil?
|
|
229
|
+
o.safe_refresh if o.respond_to? :safe_refresh
|
|
230
|
+
return unless o.respond_to? :parent
|
|
231
|
+
obj_parent = block_given? ? parent_selector(o, &block) : o.parent
|
|
232
|
+
return nil if obj_parent.nil?
|
|
233
|
+
obj_parent.safe_refresh if obj_parent.respond_to? :safe_refresh
|
|
234
|
+
obj_parent
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# rubocop: disable Style/TrivialAccessors
|
|
238
|
+
def parent=(o)
|
|
239
|
+
@parent = o
|
|
240
|
+
end
|
|
241
|
+
# rubocop: enable Style/TrivialAccessors
|
|
242
|
+
|
|
243
|
+
def _set_object(link_name, obj = nil)
|
|
244
|
+
link(link_name, obj).to
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def _get_object(link_name)
|
|
248
|
+
find_link(link_name)&.to
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def find_link(link_name)
|
|
252
|
+
links.find { |x| x.name == link_name }
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def link(link_name, obj = nil)
|
|
256
|
+
link = Inform::Ephemeral::Link.new(name: link_name, to: obj, from: self)
|
|
257
|
+
links << link
|
|
258
|
+
link
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def linked?(link_name)
|
|
262
|
+
links.count { |x| x.name == link_name } > 0
|
|
263
|
+
end
|
|
264
|
+
alias _key? linked?
|
|
265
|
+
|
|
266
|
+
def unlink(link_name)
|
|
267
|
+
links.delete_at(links.index { |x| x.name == link_name })
|
|
268
|
+
end
|
|
269
|
+
alias _unset_object unlink
|
|
270
|
+
|
|
271
|
+
def linkto(link_name)
|
|
272
|
+
_get_object(link_name)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def linksfrom(link_name = nil)
|
|
276
|
+
if link_name.nil?
|
|
277
|
+
links.select { |x| x.to == self }.map(&:from)
|
|
278
|
+
else
|
|
279
|
+
links.select { |x| x.name == link_name && x.to == self }.map(&:from)
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def init
|
|
284
|
+
self
|
|
285
|
+
end
|
|
286
|
+
alias safe_init init
|
|
287
|
+
|
|
288
|
+
def refresh
|
|
289
|
+
self
|
|
290
|
+
end
|
|
291
|
+
alias safe_refresh refresh
|
|
292
|
+
|
|
293
|
+
def save(*_args)
|
|
294
|
+
self
|
|
295
|
+
end
|
|
296
|
+
alias safe_save save
|
|
297
|
+
|
|
298
|
+
def to_s
|
|
299
|
+
self.name
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def inspect
|
|
303
|
+
identity
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
# rubocop: enable Metrics/ClassLength
|
|
307
|
+
# class Inform::Ephemeral::Object
|
|
308
|
+
end
|
|
309
|
+
# module Inform::Ephemeral
|
|
310
|
+
end
|
|
311
|
+
# module Inform
|
|
312
|
+
|
|
313
|
+
# The Inform module
|
|
314
|
+
module Inform
|
|
315
|
+
unless defined?(Inform::EphemeralObjects)
|
|
316
|
+
EphemeralObjects = if defined?(Java)
|
|
317
|
+
java.util.concurrent.ConcurrentHashMap.new
|
|
318
|
+
else
|
|
319
|
+
{}
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
unless defined?(Inform::EphemeralObjectsChildren)
|
|
323
|
+
EphemeralObjectsChildren = if defined?(Java)
|
|
324
|
+
java.util.concurrent.ConcurrentHashMap.new
|
|
325
|
+
else
|
|
326
|
+
{}
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
@@ -1,57 +1,37 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: false
|
|
3
3
|
|
|
4
|
-
# Copyright Nels Nelson 2008-
|
|
4
|
+
# Copyright Nels Nelson 2008-2025 but freely usable (see license)
|
|
5
5
|
#
|
|
6
|
-
# This file is part of
|
|
6
|
+
# This file is part of StoryTeller.
|
|
7
7
|
#
|
|
8
|
-
#
|
|
8
|
+
# StoryTeller is free software: you can redistribute it and/or
|
|
9
9
|
# modify it under the terms of the GNU General Public License as published
|
|
10
10
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
11
11
|
# (at your option) any later version.
|
|
12
12
|
#
|
|
13
|
-
#
|
|
13
|
+
# StoryTeller is distributed in the hope that it will be useful,
|
|
14
14
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
15
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
16
|
# GNU General Public License for more details.
|
|
17
17
|
#
|
|
18
18
|
# You should have received a copy of the GNU General Public License
|
|
19
|
-
# along with
|
|
19
|
+
# along with StoryTeller. If not, see <http://www.gnu.org/licenses/>.
|
|
20
20
|
|
|
21
21
|
# Tag
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
# The TagSetup class
|
|
25
|
-
class TagSetup < Sequel::Migration
|
|
26
|
-
def up
|
|
27
|
-
# return if table_exists? :tag
|
|
28
|
-
log.debug "#up"
|
|
29
|
-
create_table? :tag do
|
|
30
|
-
primary_key :id
|
|
31
|
-
index :name
|
|
32
|
-
index :created_at
|
|
33
|
-
|
|
34
|
-
String :name, unique: true, null: false
|
|
35
|
-
DateTime :created_at
|
|
36
|
-
DateTime :modified_at
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def down
|
|
41
|
-
drop_table(:tag, cascade: true) if table_exists? :tag
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
# class TagSetup
|
|
45
|
-
end
|
|
46
|
-
# defined?(Sequel::Migration)
|
|
47
|
-
|
|
48
|
-
# The Inform module
|
|
23
|
+
# module Inform
|
|
49
24
|
module Inform
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
25
|
+
# module Ephemeral
|
|
26
|
+
module Ephemeral
|
|
27
|
+
# class Tag
|
|
28
|
+
class Tag < Inform::Tag
|
|
29
|
+
attr_accessor :created_at, :modified_at, :name
|
|
30
|
+
|
|
31
|
+
def initialize(name)
|
|
32
|
+
super()
|
|
33
|
+
@name = name
|
|
34
|
+
end
|
|
55
35
|
|
|
56
36
|
def before_create
|
|
57
37
|
self.created_at ||= Time.now
|
|
@@ -108,6 +88,9 @@ from tag a, tagged b where b.tag_id = a.id group by a.id, a.name)
|
|
|
108
88
|
end
|
|
109
89
|
# rubocop: enable Style/FormatStringToken
|
|
110
90
|
end
|
|
91
|
+
# class Tag
|
|
92
|
+
end
|
|
93
|
+
# module Ephemeral
|
|
111
94
|
end
|
|
112
95
|
# module Inform
|
|
113
96
|
|
|
@@ -132,7 +115,7 @@ module Inform
|
|
|
132
115
|
|
|
133
116
|
def init
|
|
134
117
|
self.clear
|
|
135
|
-
self.merge(
|
|
118
|
+
self.merge(StoryTeller::Library.declarations.attributes)
|
|
136
119
|
self.merge(all_persisted_tags)
|
|
137
120
|
self
|
|
138
121
|
end
|
|
@@ -146,32 +129,13 @@ end
|
|
|
146
129
|
|
|
147
130
|
# Tagged
|
|
148
131
|
|
|
149
|
-
if defined?(Sequel::Migration)
|
|
150
|
-
# The TaggedSetup class
|
|
151
|
-
class TaggedSetup < Sequel::Migration
|
|
152
|
-
def up
|
|
153
|
-
log.debug "#up"
|
|
154
|
-
create_table? :tagged do
|
|
155
|
-
primary_key :id
|
|
156
|
-
foreign_key :object_id, :object, on_delete: :cascade
|
|
157
|
-
foreign_key :tag_id, :tag, on_delete: :cascade
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def down
|
|
162
|
-
drop_table(:tagged, cascade: true) if table_exists? :tagged
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
# class TaggedSetup
|
|
166
|
-
end
|
|
167
|
-
# defined?(Sequel::Migration)
|
|
168
|
-
|
|
169
132
|
# The Inform module
|
|
170
133
|
module Inform
|
|
134
|
+
# module Ephemeral
|
|
135
|
+
module Ephemeral
|
|
171
136
|
# The Inform::Tagged class
|
|
172
|
-
class Tagged <
|
|
173
|
-
|
|
174
|
-
end
|
|
137
|
+
class Tagged < Inform::Tagged; end
|
|
138
|
+
end
|
|
175
139
|
end
|
|
176
140
|
# module Inform
|
|
177
141
|
|
|
@@ -197,15 +161,21 @@ module Inform
|
|
|
197
161
|
module Taggable
|
|
198
162
|
include TagHelpers
|
|
199
163
|
|
|
164
|
+
# rubocop: disable Metrics/AbcSize
|
|
200
165
|
def tag(*args)
|
|
201
166
|
# TODO: Generalize workflag to system flags
|
|
202
167
|
workflags.add(self.identity) if args.delete(:workflag)
|
|
203
168
|
a = self.tag_names args
|
|
204
169
|
(a - (self.nil_safe_tags & a)).each do |tag|
|
|
205
|
-
|
|
170
|
+
if Inform::Tag.respond_to?(:find_or_create)
|
|
171
|
+
add_tag(Inform::Tag.find_or_create(name: tag.to_s))
|
|
172
|
+
else
|
|
173
|
+
add_tag(tags.find { |tag| tag.name == tag.to_s } || Inform::Tag.new(tag.to_s))
|
|
174
|
+
end
|
|
206
175
|
end
|
|
207
176
|
self.save_changes if self.respond_to?(:save_changes)
|
|
208
177
|
end
|
|
178
|
+
# rubocop: enable Metrics/AbcSize
|
|
209
179
|
|
|
210
180
|
def untag(*args)
|
|
211
181
|
# TODO: Generalize workflag to system flags
|
|
@@ -237,7 +207,7 @@ module Inform
|
|
|
237
207
|
# TODO: Generalize workflag to system flags
|
|
238
208
|
# puts "workflags: #{workflags}" if args.include?(:workflag)
|
|
239
209
|
return false if args.delete(:workflag) && workflags.include?(self.identity)
|
|
240
|
-
(
|
|
210
|
+
!nil_safe_tags.intersect?(tag_names(args))
|
|
241
211
|
end
|
|
242
212
|
|
|
243
213
|
def tag_names(a)
|
|
@@ -259,29 +229,32 @@ end
|
|
|
259
229
|
|
|
260
230
|
# The Inform module
|
|
261
231
|
module Inform
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
end
|
|
271
|
-
self
|
|
232
|
+
# The Inform::Ephemeral module
|
|
233
|
+
module Ephemeral
|
|
234
|
+
# The Inform::Ephemeral::Object class
|
|
235
|
+
class Object
|
|
236
|
+
def tag(*args)
|
|
237
|
+
workflags.add self.identity if args.delete :workflag
|
|
238
|
+
tag_names(args).each do |tag|
|
|
239
|
+
tags << tag.to_sym
|
|
272
240
|
end
|
|
241
|
+
self
|
|
242
|
+
end
|
|
273
243
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
end
|
|
279
|
-
self
|
|
244
|
+
def untag(*args)
|
|
245
|
+
workflags.delete self.identity if args.delete :workflag
|
|
246
|
+
(nil_safe_tags & tag_names(args)).each do |tag|
|
|
247
|
+
tags.delete tag
|
|
280
248
|
end
|
|
249
|
+
self
|
|
250
|
+
end
|
|
281
251
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
end
|
|
252
|
+
def tags
|
|
253
|
+
@tags ||= []
|
|
285
254
|
end
|
|
286
255
|
end
|
|
256
|
+
# class Object
|
|
287
257
|
end
|
|
258
|
+
# module Ephemeral
|
|
259
|
+
end
|
|
260
|
+
# module Inform
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# lib/story_teller/inform/models.rb
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
# frozen_string_literal: false
|
|
4
|
+
|
|
5
|
+
# Copyright Nels Nelson 2008-2026 but freely usable (see license)
|
|
6
|
+
#
|
|
7
|
+
# This file is part of StoryTeller.
|
|
8
|
+
#
|
|
9
|
+
# The StoryTeller is free software: you can redistribute it and/or
|
|
10
|
+
# modify it under the terms of the GNU General Public License as published
|
|
11
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
|
12
|
+
# (at your option) any later version.
|
|
13
|
+
#
|
|
14
|
+
# The StoryTeller is distributed in the hope that it will be useful,
|
|
15
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
|
+
# GNU General Public License for more details.
|
|
18
|
+
#
|
|
19
|
+
# You should have received a copy of the GNU General Public License
|
|
20
|
+
# along with the StoryTeller. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
|
|
22
|
+
require_relative 'ephemeral/link'
|
|
23
|
+
require_relative 'ephemeral/module'
|
|
24
|
+
require_relative 'ephemeral/object'
|
|
25
|
+
require_relative 'ephemeral/tag'
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
# frozen_string_literal: false
|
|
3
3
|
|
|
4
|
-
# Copyright Nels Nelson 2008-
|
|
4
|
+
# Copyright Nels Nelson 2008-2025 but freely usable (see license)
|
|
5
5
|
#
|
|
6
|
-
# This file is part of the
|
|
6
|
+
# This file is part of the StoryTeller.
|
|
7
7
|
#
|
|
8
|
-
# The
|
|
8
|
+
# The StoryTeller is free software: you can redistribute it and/or
|
|
9
9
|
# modify it under the terms of the GNU General Public License as published
|
|
10
10
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
11
11
|
# (at your option) any later version.
|
|
12
12
|
#
|
|
13
|
-
# The
|
|
13
|
+
# The StoryTeller is distributed in the hope that it will be useful,
|
|
14
14
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
15
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
16
|
# GNU General Public License for more details.
|
|
17
17
|
#
|
|
18
18
|
# You should have received a copy of the GNU General Public License
|
|
19
|
-
# along with the
|
|
19
|
+
# along with the StoryTeller. If not, see <http://www.gnu.org/licenses/>.
|
|
20
20
|
|
|
21
|
-
# The
|
|
22
|
-
module
|
|
21
|
+
# The StoryTeller module
|
|
22
|
+
module StoryTeller
|
|
23
23
|
# The IO module
|
|
24
24
|
module IO
|
|
25
25
|
def session
|
|
26
|
-
return unless defined?(
|
|
27
|
-
@session ||=
|
|
26
|
+
return unless defined?(StoryTeller::IO::Session) && StoryTeller::IO::Session.respond_to?(:of)
|
|
27
|
+
@session ||= StoryTeller::IO::Session.of(self)
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def noop; end
|
|
@@ -171,4 +171,4 @@ module Inform
|
|
|
171
171
|
end
|
|
172
172
|
# module IO
|
|
173
173
|
end
|
|
174
|
-
# module
|
|
174
|
+
# module StoryTeller
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
+
# lib/story_teller/kernel.rb
|
|
1
2
|
# encoding: utf-8
|
|
2
3
|
# frozen_string_literal: false
|
|
3
4
|
|
|
4
|
-
# Copyright Nels Nelson 2008-
|
|
5
|
+
# Copyright Nels Nelson 2008-2025 but freely usable (see license)
|
|
5
6
|
#
|
|
6
|
-
# This file is part of
|
|
7
|
+
# This file is part of StoryTeller.
|
|
7
8
|
#
|
|
8
|
-
#
|
|
9
|
+
# StoryTeller is free software: you can redistribute it and/or
|
|
9
10
|
# modify it under the terms of the GNU General Public License as published
|
|
10
11
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
11
12
|
# (at your option) any later version.
|
|
12
13
|
#
|
|
13
|
-
#
|
|
14
|
+
# StoryTeller is distributed in the hope that it will be useful,
|
|
14
15
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
16
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
17
|
# GNU General Public License for more details.
|
|
17
18
|
#
|
|
18
19
|
# You should have received a copy of the GNU General Public License
|
|
19
|
-
# along with
|
|
20
|
+
# along with StoryTeller. If not, see <http://www.gnu.org/licenses/>.
|
|
20
21
|
|
|
21
22
|
# Define a class inheriting from StandardError to raise when
|
|
22
23
|
# a method is already defined
|
|
@@ -29,45 +30,34 @@ end
|
|
|
29
30
|
|
|
30
31
|
# The Kernel module
|
|
31
32
|
module Kernel
|
|
32
|
-
def import_global(symbol)
|
|
33
|
-
Inform::Runtime.import_global(symbol)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def Link(link)
|
|
37
|
-
Inform::Runtime.Link(link)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
33
|
def Include(inclusion)
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
StoryTeller::Engine.main_object = self if inclusion == "Parser"
|
|
35
|
+
StoryTeller::Library::Directives.Include(inclusion)
|
|
43
36
|
end
|
|
44
37
|
|
|
45
38
|
def Attribute(attribute)
|
|
46
|
-
|
|
39
|
+
StoryTeller::Library::Directives.Attribute(attribute)
|
|
47
40
|
end
|
|
48
41
|
|
|
49
42
|
def Property(property_or_modifier, modifier = nil, value = nil)
|
|
50
|
-
|
|
43
|
+
StoryTeller::Library::Directives.Property(property_or_modifier, modifier, value)
|
|
51
44
|
end
|
|
52
45
|
|
|
53
46
|
def Default(property, value)
|
|
54
|
-
|
|
47
|
+
StoryTeller::Library::Directives.Default(property, value)
|
|
55
48
|
end
|
|
56
49
|
|
|
57
50
|
def Constant(property, value)
|
|
58
|
-
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
# self.save if self.respond_to?(:save)
|
|
69
|
-
# self
|
|
70
|
-
# end
|
|
51
|
+
StoryTeller::Library::Directives.Constant(property, value)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def Link(link)
|
|
55
|
+
StoryTeller::Library::Directives.Link(link)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def import_global(symbol)
|
|
59
|
+
StoryTeller::Library::Directives.import_global(symbol)
|
|
60
|
+
end
|
|
71
61
|
|
|
72
62
|
def return_after(*args, &block)
|
|
73
63
|
block.call
|