inform-runtime 1.2.3 → 1.3.1
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 +33 -41
- data/lib/story_teller/articles.rb +2 -1
- data/lib/story_teller/builtins.rb +63 -10
- data/lib/story_teller/color.rb +2 -1
- data/lib/story_teller/command.rb +2 -1
- data/lib/story_teller/context.rb +23 -27
- data/lib/story_teller/daemon.rb +2 -2
- data/lib/story_teller/engine.rb +45 -10
- data/lib/story_teller/events.rb +1 -1
- data/lib/story_teller/experimental/handler_dsl.rb +1 -16
- data/lib/story_teller/experimental/reverse_engineer_class.rb +1 -1
- data/lib/story_teller/grammar_parser.rb +60 -13
- data/lib/story_teller/helpers.rb +8 -4
- data/lib/story_teller/history.rb +1 -1
- data/lib/story_teller/inflector.rb +4 -2
- data/lib/story_teller/inform/ephemeral/link.rb +63 -31
- data/lib/story_teller/inform/ephemeral/module.rb +6 -5
- data/lib/story_teller/inform/ephemeral/object.rb +223 -236
- data/lib/story_teller/inform/ephemeral/tag.rb +27 -14
- data/lib/story_teller/io.rb +99 -49
- data/lib/story_teller/kernel.rb +2 -2
- data/lib/story_teller/library/bootstrap.rb +2 -2
- data/lib/story_teller/library/declarations.rb +1 -1
- data/lib/story_teller/library/directives.rb +1 -1
- data/lib/story_teller/library/loader.rb +3 -20
- data/lib/story_teller/library/location.rb +9 -3
- data/lib/story_teller/library.rb +1 -1
- data/lib/story_teller/logging.rb +1 -1
- data/lib/story_teller/mixins.rb +11 -4
- data/lib/story_teller/plurals.rb +2 -1
- data/lib/story_teller/privileges.rb +89 -6
- data/lib/story_teller/prototype.rb +150 -32
- data/lib/story_teller/publication.rb +2 -1
- data/lib/story_teller/session.rb +115 -25
- data/lib/story_teller/stdlib.rb +231 -1
- data/lib/story_teller/subscription.rb +2 -1
- data/lib/story_teller/tree.rb +2 -1
- data/lib/story_teller/version.rb +2 -2
- data/lib/story_teller/world_tree.rb +21 -23
- data/lib/story_teller.rb +18 -5
- metadata +6 -10
- data/lib/story_teller/core.rb +0 -39
- data/lib/story_teller/ephemeral_adapter.rb +0 -40
- data/lib/story_teller/inform/base.rb +0 -160
- data/lib/story_teller/model_adapter.rb +0 -132
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# lib/story_teller/object.rb
|
|
1
|
+
# lib/story_teller/inform/object.rb
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
# frozen_string_literal: false
|
|
4
4
|
|
|
5
|
-
# Copyright Nels Nelson 2008-
|
|
5
|
+
# Copyright Nels Nelson 2008-2026 but freely usable (see license)
|
|
6
6
|
#
|
|
7
7
|
# This file is part of the StoryTeller.
|
|
8
8
|
#
|
|
@@ -13,11 +13,11 @@
|
|
|
13
13
|
#
|
|
14
14
|
# The StoryTeller is distributed in the hope that it will be useful,
|
|
15
15
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
16
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17
17
|
# GNU General Public License for more details.
|
|
18
18
|
#
|
|
19
19
|
# You should have received a copy of the GNU General Public License
|
|
20
|
-
# along with the StoryTeller.
|
|
20
|
+
# along with the StoryTeller. If not, see <http://www.gnu.org/licenses/>.
|
|
21
21
|
|
|
22
22
|
# Object
|
|
23
23
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# obj
|
|
29
29
|
# end
|
|
30
30
|
|
|
31
|
-
def Object(name, klass = Inform::Object, &block)
|
|
31
|
+
def Object(name, klass = Inform::Ephemeral::Object, &block)
|
|
32
32
|
obj = if klass.respond_to?(:fetch_or_create_by_name)
|
|
33
33
|
klass.fetch_or_create_by_name(name)
|
|
34
34
|
else
|
|
@@ -39,291 +39,278 @@ def Object(name, klass = Inform::Object, &block)
|
|
|
39
39
|
obj
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
#
|
|
42
|
+
# module Inform
|
|
43
43
|
module Inform
|
|
44
|
-
# module Ephemeral
|
|
45
|
-
module Ephemeral
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
44
|
+
# module Ephemeral
|
|
45
|
+
module Ephemeral
|
|
46
|
+
# class Object
|
|
47
|
+
# rubocop: disable Metrics/ClassLength
|
|
48
|
+
class Object
|
|
49
|
+
DefaultShortNameTemplate = '(%<short_name>s)'.freeze
|
|
50
|
+
|
|
51
|
+
attr_accessor :short_name, :display_name, :inflib,
|
|
52
|
+
:properties, :links, :modules, :tags, :created_at, :modified_at,
|
|
53
|
+
:visited
|
|
54
|
+
|
|
55
|
+
alias values properties
|
|
56
|
+
|
|
57
|
+
# rubocop: disable Metrics/AbcSize
|
|
58
|
+
# rubocop: disable Metrics/MethodLength
|
|
59
|
+
def initialize(textual_name = nil, *args, &block)
|
|
60
|
+
super(*args)
|
|
61
|
+
@name = textual_name || self.class.name
|
|
62
|
+
@short_name = textual_name || format(
|
|
63
|
+
DefaultShortNameTemplate, short_name: self.class.name)
|
|
64
|
+
@display_name = textual_name
|
|
65
|
+
@description = nil
|
|
66
|
+
@adjectives = []
|
|
67
|
+
@properties = {}
|
|
68
|
+
@links = []
|
|
69
|
+
@modules = []
|
|
70
|
+
@tags = []
|
|
71
|
+
@children = []
|
|
72
|
+
@visited = []
|
|
73
|
+
@created_at = @modified_at = Time.now
|
|
74
|
+
index_words if respond_to?(:index_words)
|
|
75
|
+
EphemeralObjects[self.identity] = self
|
|
76
|
+
EphemeralObjects[@display_name.to_s] = self unless @display_name.nil?
|
|
77
|
+
self.with(&block) unless block.nil?
|
|
78
|
+
end
|
|
79
|
+
# rubocop: enable Metrics/AbcSize
|
|
80
|
+
# rubocop: enable Metrics/MethodLength
|
|
81
|
+
|
|
82
|
+
def self.fetch_or_create_by_name(name)
|
|
83
|
+
key = name.to_s
|
|
84
|
+
object = EphemeralObjects[key]
|
|
85
|
+
return object if object.is_a?(self)
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
Inform::EphemeralObjects.fetch(object_name) do
|
|
82
|
-
Inform::EphemeralObjects[object_name] = klass.create(object_name)
|
|
87
|
+
new(key).tap { |created| EphemeralObjects[key] = created }
|
|
83
88
|
end
|
|
84
|
-
end
|
|
85
89
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
obj.object_type = object_type
|
|
89
|
-
obj.parent_id = parent_id
|
|
90
|
-
obj.properties.merge!(properties)
|
|
90
|
+
def self.all
|
|
91
|
+
EphemeralObjects.values.select { |object| object.is_a?(self) }.uniq
|
|
91
92
|
end
|
|
92
|
-
end
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
description: @description,
|
|
99
|
-
properties: @properties
|
|
100
|
-
}
|
|
101
|
-
end
|
|
94
|
+
def self.clear
|
|
95
|
+
EphemeralObjects.clear
|
|
96
|
+
EphemeralObjectsChildren.clear if defined?(EphemeralObjectsChildren)
|
|
97
|
+
end
|
|
102
98
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
99
|
+
def self.[](id)
|
|
100
|
+
object = EphemeralObjects[id]
|
|
101
|
+
return object if object.is_a?(self)
|
|
102
|
+
|
|
103
|
+
all.find { |candidate| candidate.id == id || candidate.identity == id }
|
|
108
104
|
end
|
|
109
|
-
end
|
|
110
105
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
106
|
+
def [](property)
|
|
107
|
+
return description if property == :description
|
|
108
|
+
return name if property == :name
|
|
109
|
+
return short_name if property == :short_name
|
|
114
110
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
end
|
|
111
|
+
properties[property]
|
|
112
|
+
end
|
|
118
113
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
114
|
+
def to_hash
|
|
115
|
+
properties.merge(
|
|
116
|
+
id: id,
|
|
117
|
+
name: name,
|
|
118
|
+
short_name: short_name,
|
|
119
|
+
description: description
|
|
120
|
+
)
|
|
121
|
+
end
|
|
125
122
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
name: name,
|
|
130
|
-
short_name: short_name,
|
|
131
|
-
description: description
|
|
132
|
-
)
|
|
133
|
-
end
|
|
123
|
+
def <=>(other)
|
|
124
|
+
self.name <=> other.name
|
|
125
|
+
end
|
|
134
126
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
end
|
|
127
|
+
def parse(s)
|
|
128
|
+
return if inflib.nil?
|
|
138
129
|
|
|
139
|
-
|
|
140
|
-
return if inflib.nil?
|
|
141
|
-
inflib.semaphore.synchronize do
|
|
142
|
-
inflib.println(inflib.parse(s))
|
|
130
|
+
inflib.semaphore.synchronize { inflib.parse(s) }
|
|
143
131
|
end
|
|
144
|
-
end
|
|
145
132
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
133
|
+
def id
|
|
134
|
+
self.object_id
|
|
135
|
+
end
|
|
149
136
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
137
|
+
def object_type
|
|
138
|
+
self.class
|
|
139
|
+
end
|
|
153
140
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
@name = ([@name] | args).flatten.uniq
|
|
158
|
-
index_words if respond_to?(:index_words)
|
|
159
|
-
@name
|
|
160
|
-
end
|
|
141
|
+
def name(*args)
|
|
142
|
+
return args.first.object_name if args.first.respond_to?(:object_name)
|
|
143
|
+
return @name if args.empty?
|
|
161
144
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
index_words if respond_to?(:index_words)
|
|
167
|
-
return
|
|
168
|
-
end
|
|
145
|
+
@name = ([@name] | args).flatten.uniq
|
|
146
|
+
index_words if respond_to?(:index_words)
|
|
147
|
+
@name
|
|
148
|
+
end
|
|
169
149
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
@description = args.length > 1 ? args.join(' ') : args.first
|
|
173
|
-
@description
|
|
174
|
-
end
|
|
150
|
+
def description(description = nil)
|
|
151
|
+
return @description if description.nil?
|
|
175
152
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
end
|
|
153
|
+
@description = description
|
|
154
|
+
end
|
|
179
155
|
|
|
180
|
-
|
|
181
|
-
@name.split(/[,\s]+/).join(', ')
|
|
182
|
-
end
|
|
156
|
+
alias description= description
|
|
183
157
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
o.parent = self
|
|
188
|
-
@children << o
|
|
189
|
-
end
|
|
158
|
+
def object_name
|
|
159
|
+
@display_name || @short_name || @name
|
|
160
|
+
end
|
|
190
161
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
162
|
+
def name_words
|
|
163
|
+
name_words = @name
|
|
164
|
+
name_words = name_words.split(/[,\s]+/) if name_words.respond_to?(:split)
|
|
165
|
+
name_words.join(', ') if name_words.respond_to?(:join)
|
|
166
|
+
name_words
|
|
167
|
+
end
|
|
195
168
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
169
|
+
def <<(o)
|
|
170
|
+
return if self == o
|
|
171
|
+
return unless o.object?
|
|
199
172
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
o.children.length
|
|
204
|
-
end
|
|
173
|
+
o.parent = self
|
|
174
|
+
@children << o
|
|
175
|
+
end
|
|
205
176
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
177
|
+
def remove
|
|
178
|
+
@children.clear
|
|
179
|
+
@parent = nil
|
|
180
|
+
end
|
|
210
181
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
182
|
+
def empty?(...)
|
|
183
|
+
self.children.empty?(...)
|
|
184
|
+
end
|
|
214
185
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
186
|
+
def children(o = nil, prop = :@children)
|
|
187
|
+
return @children if o.nil?
|
|
188
|
+
return o.instance_variable_get(prop).length if o.instance_variable_defined?(prop)
|
|
218
189
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
end
|
|
190
|
+
o.children.length
|
|
191
|
+
end
|
|
222
192
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
193
|
+
def location
|
|
194
|
+
self.parent
|
|
195
|
+
end
|
|
226
196
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
|
197
|
+
def list_together
|
|
198
|
+
linkto :list_together
|
|
199
|
+
end
|
|
236
200
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
end
|
|
241
|
-
# rubocop: enable Style/TrivialAccessors
|
|
201
|
+
def ancestors
|
|
202
|
+
self.parent.nil? ? [] : self.parent.ancestors + [self.parent]
|
|
203
|
+
end
|
|
242
204
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
205
|
+
def descendants
|
|
206
|
+
@children + @children.map(&:descendants).flatten
|
|
207
|
+
end
|
|
246
208
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
209
|
+
def root
|
|
210
|
+
self.parent.nil? ? self : self.parent.root
|
|
211
|
+
end
|
|
250
212
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
end
|
|
213
|
+
def parent(o = nil, &block)
|
|
214
|
+
return @parent if o.nil?
|
|
254
215
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
links << link
|
|
258
|
-
link
|
|
259
|
-
end
|
|
216
|
+
o.safe_refresh if o.respond_to? :safe_refresh
|
|
217
|
+
return unless o.respond_to? :parent
|
|
260
218
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
end
|
|
264
|
-
alias _key? linked?
|
|
219
|
+
obj_parent = block_given? ? parent_selector(o, &block) : o.parent
|
|
220
|
+
return nil if obj_parent.nil?
|
|
265
221
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
alias _unset_object unlink
|
|
222
|
+
obj_parent.safe_refresh if obj_parent.respond_to? :safe_refresh
|
|
223
|
+
obj_parent
|
|
224
|
+
end
|
|
270
225
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
226
|
+
# rubocop: disable Style/TrivialAccessors
|
|
227
|
+
def parent=(o)
|
|
228
|
+
@parent = o
|
|
229
|
+
end
|
|
230
|
+
# rubocop: enable Style/TrivialAccessors
|
|
274
231
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
links.select { |x| x.to == self }.map(&:from)
|
|
278
|
-
else
|
|
279
|
-
links.select { |x| x.name == link_name && x.to == self }.map(&:from)
|
|
232
|
+
def _set_object(link_name, obj = nil)
|
|
233
|
+
link(link_name, obj).to
|
|
280
234
|
end
|
|
281
|
-
end
|
|
282
235
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
alias safe_init init
|
|
236
|
+
def _get_object(link_name)
|
|
237
|
+
find_link(link_name)&.to
|
|
238
|
+
end
|
|
287
239
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
alias safe_refresh refresh
|
|
240
|
+
def find_link(link_name)
|
|
241
|
+
links.find { |x| x.name == link_name }
|
|
242
|
+
end
|
|
292
243
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
244
|
+
def link(link_name, obj = nil)
|
|
245
|
+
link = Inform::System::Link.new(name: link_name, to: obj, from: self)
|
|
246
|
+
links << link
|
|
247
|
+
link
|
|
248
|
+
end
|
|
297
249
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
250
|
+
def linked?(link_name)
|
|
251
|
+
links.count { |x| x.name == link_name } > 0
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
alias _key? linked?
|
|
301
255
|
|
|
302
|
-
|
|
303
|
-
|
|
256
|
+
def unlink(link_name)
|
|
257
|
+
links.delete_at(links.index { |x| x.name == link_name })
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
alias _unset_object unlink
|
|
261
|
+
|
|
262
|
+
def linkto(link_name)
|
|
263
|
+
_get_object(link_name)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def linksfrom(link_name = nil)
|
|
267
|
+
if link_name.nil?
|
|
268
|
+
links.select { |x| x.to == self }.map(&:from)
|
|
269
|
+
else
|
|
270
|
+
links.select { |x| x.name == link_name && x.to == self }.map(&:from)
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def init
|
|
275
|
+
self
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
alias safe_init init
|
|
279
|
+
|
|
280
|
+
def refresh
|
|
281
|
+
self
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
alias safe_refresh refresh
|
|
285
|
+
|
|
286
|
+
def save(*_args)
|
|
287
|
+
self
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
alias safe_save save
|
|
304
291
|
end
|
|
292
|
+
# rubocop: enable Metrics/ClassLength
|
|
293
|
+
# class Object
|
|
305
294
|
end
|
|
306
|
-
#
|
|
307
|
-
# class Inform::Ephemeral::Object
|
|
308
|
-
end
|
|
309
|
-
# module Inform::Ephemeral
|
|
295
|
+
# module Ephemeral
|
|
310
296
|
end
|
|
311
297
|
# module Inform
|
|
312
298
|
|
|
313
299
|
# The Inform module
|
|
314
300
|
module Inform
|
|
315
|
-
unless defined?(Inform::EphemeralObjects)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
301
|
+
unless defined?(Inform::EphemeralObjects)
|
|
302
|
+
EphemeralObjects = if defined?(Java)
|
|
303
|
+
java.util.concurrent.ConcurrentHashMap.new
|
|
304
|
+
else
|
|
305
|
+
{}
|
|
306
|
+
end
|
|
320
307
|
end
|
|
321
|
-
|
|
322
|
-
unless defined?(Inform::EphemeralObjectsChildren)
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
308
|
+
|
|
309
|
+
unless defined?(Inform::EphemeralObjectsChildren)
|
|
310
|
+
EphemeralObjectsChildren = if defined?(Java)
|
|
311
|
+
java.util.concurrent.ConcurrentHashMap.new
|
|
312
|
+
else
|
|
313
|
+
{}
|
|
314
|
+
end
|
|
327
315
|
end
|
|
328
316
|
end
|
|
329
|
-
end
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
# lib/story_teller/inform/tag.rb
|
|
1
2
|
# encoding: utf-8
|
|
2
3
|
# frozen_string_literal: false
|
|
3
4
|
|
|
4
|
-
# Copyright Nels Nelson 2008-
|
|
5
|
+
# Copyright Nels Nelson 2008-2026 but freely usable (see license)
|
|
5
6
|
#
|
|
6
7
|
# This file is part of StoryTeller.
|
|
7
8
|
#
|
|
@@ -25,7 +26,7 @@ module Inform
|
|
|
25
26
|
# module Ephemeral
|
|
26
27
|
module Ephemeral
|
|
27
28
|
# class Tag
|
|
28
|
-
class Tag
|
|
29
|
+
class Tag
|
|
29
30
|
attr_accessor :created_at, :modified_at, :name
|
|
30
31
|
|
|
31
32
|
def initialize(name)
|
|
@@ -94,7 +95,7 @@ end
|
|
|
94
95
|
end
|
|
95
96
|
# module Inform
|
|
96
97
|
|
|
97
|
-
#
|
|
98
|
+
# module Inform
|
|
98
99
|
module Inform
|
|
99
100
|
# The TagRegistry class
|
|
100
101
|
class TagRegistry < Set
|
|
@@ -106,8 +107,8 @@ module Inform
|
|
|
106
107
|
end
|
|
107
108
|
|
|
108
109
|
def all_persisted_tags
|
|
109
|
-
return [] unless Inform
|
|
110
|
-
Inform
|
|
110
|
+
return [] unless Inform.tag_klass.respond_to?(:map)
|
|
111
|
+
Inform.tag_klass.map { |a| a.name.to_sym }
|
|
111
112
|
rescue Sequel::DatabaseError => e
|
|
112
113
|
log.warn e.message
|
|
113
114
|
return []
|
|
@@ -121,8 +122,18 @@ module Inform
|
|
|
121
122
|
end
|
|
122
123
|
alias reset init
|
|
123
124
|
end
|
|
125
|
+
end
|
|
126
|
+
# module Inform
|
|
127
|
+
|
|
128
|
+
# module Inform
|
|
129
|
+
module Inform
|
|
130
|
+
module_function
|
|
124
131
|
|
|
125
|
-
def
|
|
132
|
+
def tag_klass
|
|
133
|
+
Inform::Ephemeral::Tag
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def attributes
|
|
126
137
|
TagRegistry::SINGLETON.memo ||= TagRegistry.new
|
|
127
138
|
end
|
|
128
139
|
end
|
|
@@ -134,10 +145,9 @@ module Inform
|
|
|
134
145
|
# module Ephemeral
|
|
135
146
|
module Ephemeral
|
|
136
147
|
# The Inform::Tagged class
|
|
137
|
-
class Tagged
|
|
148
|
+
class Tagged; end
|
|
138
149
|
end
|
|
139
150
|
end
|
|
140
|
-
# module Inform
|
|
141
151
|
|
|
142
152
|
# Taggable
|
|
143
153
|
|
|
@@ -155,33 +165,36 @@ module Inform
|
|
|
155
165
|
end
|
|
156
166
|
end
|
|
157
167
|
|
|
158
|
-
#
|
|
168
|
+
# module Inform
|
|
159
169
|
module Inform
|
|
160
|
-
#
|
|
170
|
+
# module Taggable
|
|
161
171
|
module Taggable
|
|
162
172
|
include TagHelpers
|
|
163
173
|
|
|
164
174
|
# rubocop: disable Metrics/AbcSize
|
|
175
|
+
# rubocop: disable Metrics/MethodLength
|
|
165
176
|
def tag(*args)
|
|
166
177
|
# TODO: Generalize workflag to system flags
|
|
167
178
|
workflags.add(self.identity) if args.delete(:workflag)
|
|
168
179
|
a = self.tag_names args
|
|
169
180
|
(a - (self.nil_safe_tags & a)).each do |tag|
|
|
170
|
-
if Inform
|
|
171
|
-
add_tag(Inform
|
|
181
|
+
if Inform.tag_klass.respond_to?(:find_or_create)
|
|
182
|
+
add_tag(Inform.tag_klass.find_or_create(name: tag.to_s))
|
|
172
183
|
else
|
|
173
|
-
|
|
184
|
+
tag = tags.find { |tag| tag.name == tag.to_s } || Inform.tag_klass.new(tag.to_s)
|
|
185
|
+
add_tag(tag)
|
|
174
186
|
end
|
|
175
187
|
end
|
|
176
188
|
self.save_changes if self.respond_to?(:save_changes)
|
|
177
189
|
end
|
|
178
190
|
# rubocop: enable Metrics/AbcSize
|
|
191
|
+
# rubocop: enable Metrics/MethodLength
|
|
179
192
|
|
|
180
193
|
def untag(*args)
|
|
181
194
|
# TODO: Generalize workflag to system flags
|
|
182
195
|
workflags.delete(self.identity) if args.delete(:workflag)
|
|
183
196
|
(self.nil_safe_tags & tag_names(args)).each do |tag|
|
|
184
|
-
remove_tag
|
|
197
|
+
remove_tag(Inform.tag_klass.find(name: tag.to_s))
|
|
185
198
|
end
|
|
186
199
|
self.save_changes if self.respond_to?(:save_changes)
|
|
187
200
|
end
|