inform-runtime 1.3.2 → 1.4.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/lib/story_teller/io.rb +7 -64
- data/lib/story_teller/library.rb +0 -1
- data/lib/story_teller/session.rb +95 -4
- data/lib/story_teller/stdlib.rb +1 -1
- data/lib/story_teller/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 474087cc0143425969470924c1fe5e944b06f2d17ee76a097551345c4ca1959e
|
|
4
|
+
data.tar.gz: 8f933a9f47d17a247d804d226a32f8ff7d57e38698d0b0a262e40a796efd7972
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 606603f0fa1048e8cf566204167646989a99b1fcc80746ec3c8a7490d737ced8cdfb09be0e0cc7b0674123ed96b8588b387f6ed010328963c700816c172167a1
|
|
7
|
+
data.tar.gz: 3bab288d8358fcf11ca366756a1e451f3cfab0b231aa7e35d144397b4cba04257b1a92f2406581611628c03521d986db01aa32501818fe059f85f439d2a34370
|
data/lib/story_teller/io.rb
CHANGED
|
@@ -27,7 +27,9 @@ module StoryTeller
|
|
|
27
27
|
return @session if defined?(@session) && !@session.nil?
|
|
28
28
|
return nil unless defined?(StoryTeller::IO::Session)
|
|
29
29
|
|
|
30
|
-
StoryTeller::IO::Session.of(self)
|
|
30
|
+
StoryTeller::IO::Session.of(self).tap do |session|
|
|
31
|
+
log.trace "self: #{self}, session: #{session.inspect}"
|
|
32
|
+
end
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def noop; end
|
|
@@ -40,13 +42,11 @@ module StoryTeller
|
|
|
40
42
|
subscribed_connections
|
|
41
43
|
end
|
|
42
44
|
|
|
43
|
-
def read
|
|
44
|
-
$stdin.gets(chomp: true)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
45
|
def out(s)
|
|
48
46
|
if defined?(Curses)
|
|
49
47
|
Curses.addstr s
|
|
48
|
+
elsif session
|
|
49
|
+
session.write_output(s)
|
|
50
50
|
else
|
|
51
51
|
$stdout.write(s)
|
|
52
52
|
end
|
|
@@ -64,13 +64,9 @@ module StoryTeller
|
|
|
64
64
|
alias update inform
|
|
65
65
|
|
|
66
66
|
def flush_io
|
|
67
|
-
|
|
68
|
-
end
|
|
67
|
+
return if session
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
s.gsub!(/^\n+/, "\n")
|
|
72
|
-
return s if s.length < columns || columns == 0
|
|
73
|
-
s.gsub(/(.{#{columns}}\S+)( +|$\n?)/, "\\1\n")
|
|
69
|
+
$stdout.flush
|
|
74
70
|
end
|
|
75
71
|
|
|
76
72
|
def new_line
|
|
@@ -128,59 +124,6 @@ module StoryTeller
|
|
|
128
124
|
DefaultLineLength
|
|
129
125
|
end
|
|
130
126
|
|
|
131
|
-
# def many_per_line(items)
|
|
132
|
-
# max = 0
|
|
133
|
-
|
|
134
|
-
# lines = []
|
|
135
|
-
# prefs = @player.linkto :preferences
|
|
136
|
-
# line_length = preferred_line_length
|
|
137
|
-
# buffer = ''
|
|
138
|
-
|
|
139
|
-
# items.each do |item|
|
|
140
|
-
# max = [item.length, max].max
|
|
141
|
-
# end
|
|
142
|
-
# max += MinimumColumnPadding
|
|
143
|
-
# width = (line_length - MinimumCellPadding) / max
|
|
144
|
-
# height = (items.length / width).ceil - 1
|
|
145
|
-
|
|
146
|
-
# return if width == 0
|
|
147
|
-
|
|
148
|
-
# columns = []
|
|
149
|
-
# i = 0
|
|
150
|
-
# loop do
|
|
151
|
-
# # Build a list of columns with nil padding
|
|
152
|
-
# column = items[i, height]
|
|
153
|
-
# columns << column + Array.new(height - column.length)
|
|
154
|
-
# i += height
|
|
155
|
-
# break if (i + height) >= (items.length + height)
|
|
156
|
-
# end
|
|
157
|
-
|
|
158
|
-
# m = []
|
|
159
|
-
# loop do
|
|
160
|
-
# m << []
|
|
161
|
-
# for column in columns
|
|
162
|
-
# m.last << column.shift
|
|
163
|
-
# end
|
|
164
|
-
# break if columns.last.empty?
|
|
165
|
-
# end
|
|
166
|
-
|
|
167
|
-
# m.each do |row|
|
|
168
|
-
# buffer = "\e[51m"
|
|
169
|
-
# row.each do |item|
|
|
170
|
-
# next unless item
|
|
171
|
-
# n = [max - item.length, MinimumColumnPadding].max
|
|
172
|
-
# padding = " " * n unless item == row.last
|
|
173
|
-
# buffer += format(ItemPaddingString, item: item, padding: padding)
|
|
174
|
-
# end
|
|
175
|
-
# buffer += "\e[56m"
|
|
176
|
-
# lines << buffer.strip
|
|
177
|
-
# buffer = ''
|
|
178
|
-
# end
|
|
179
|
-
|
|
180
|
-
# lines
|
|
181
|
-
# end
|
|
182
|
-
# # def many_per_line
|
|
183
|
-
|
|
184
127
|
# rubocop: disable Metrics/AbcSize
|
|
185
128
|
# rubocop: disable Metrics/CyclomaticComplexity
|
|
186
129
|
# rubocop: disable Metrics/MethodLength
|
data/lib/story_teller/library.rb
CHANGED
|
@@ -65,7 +65,6 @@ module StoryTeller
|
|
|
65
65
|
library_methods.merge(mod.instance_methods(false))
|
|
66
66
|
end
|
|
67
67
|
@methods_index.concat(library_methods.to_a).sort
|
|
68
|
-
log.trace "Loaded library methods: #{@methods_index}"
|
|
69
68
|
end
|
|
70
69
|
# rubocop: enable Metrics/AbcSize
|
|
71
70
|
# rubocop: enable Metrics/MethodLength
|
data/lib/story_teller/session.rb
CHANGED
|
@@ -144,6 +144,33 @@ end
|
|
|
144
144
|
module StoryTeller
|
|
145
145
|
# module IO
|
|
146
146
|
module IO
|
|
147
|
+
# The OutputBuffer class
|
|
148
|
+
class OutputBuffer
|
|
149
|
+
def initialize
|
|
150
|
+
@content = String.new # rubocop: disable Style/EmptyLiteral
|
|
151
|
+
@mutex = Mutex.new
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def write(value)
|
|
155
|
+
return if value.nil?
|
|
156
|
+
|
|
157
|
+
@mutex.synchronize { @content << value.to_s }
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def drain
|
|
161
|
+
@mutex.synchronize do
|
|
162
|
+
content = @content.dup
|
|
163
|
+
@content.clear
|
|
164
|
+
content.strip.length.positive? ? content : ''
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def reset
|
|
169
|
+
@mutex.synchronize { @content.clear }
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
# class OutputBuffer
|
|
173
|
+
|
|
147
174
|
# The Session class
|
|
148
175
|
# TODO: Refactor method implementations into modules
|
|
149
176
|
# rubocop: disable Metrics/ClassLength
|
|
@@ -170,6 +197,7 @@ class Session
|
|
|
170
197
|
@settings = settings
|
|
171
198
|
@status = nil
|
|
172
199
|
@last_activity = Time.now
|
|
200
|
+
@outbound = OutputBuffer.new
|
|
173
201
|
|
|
174
202
|
self.class.register(channel, self) unless channel.nil?
|
|
175
203
|
control(player) unless player.nil?
|
|
@@ -178,11 +206,73 @@ class Session
|
|
|
178
206
|
|
|
179
207
|
alias preferences settings
|
|
180
208
|
|
|
209
|
+
def write_output(value)
|
|
210
|
+
@outbound.write(value)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def drain_output
|
|
214
|
+
tidy_output(@outbound.drain)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def tidy_output(value, columns = word_wrap_column)
|
|
218
|
+
output = value.to_s
|
|
219
|
+
return '' if output.empty?
|
|
220
|
+
|
|
221
|
+
columns = columns.to_i
|
|
222
|
+
return output if columns <= 0
|
|
223
|
+
|
|
224
|
+
# output = output.gsub(/^\n+/, "\n")
|
|
225
|
+
output.each_line.map do |line|
|
|
226
|
+
newline = line.end_with?("\n") ? "\n" : ''
|
|
227
|
+
wrap_line(line.chomp, columns) + newline
|
|
228
|
+
end.join
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# rubocop: disable Metrics/AbcSize
|
|
232
|
+
# rubocop: disable Metrics/MethodLength
|
|
233
|
+
def wrap_line(line, columns)
|
|
234
|
+
return line if line.length <= columns
|
|
235
|
+
|
|
236
|
+
indentation = line[/\A[ \t]*/].to_s
|
|
237
|
+
words = line.strip.split(/[ \t]+/)
|
|
238
|
+
return line if words.empty?
|
|
239
|
+
|
|
240
|
+
lines = []
|
|
241
|
+
current = indentation.dup
|
|
242
|
+
|
|
243
|
+
words.each do |word|
|
|
244
|
+
candidate = current == indentation ? "#{current}#{word}" : "#{current} #{word}"
|
|
245
|
+
|
|
246
|
+
if candidate.length <= columns || current == indentation
|
|
247
|
+
current = candidate
|
|
248
|
+
else
|
|
249
|
+
lines << current.rstrip
|
|
250
|
+
current = "#{indentation}#{word}"
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
lines << current.rstrip
|
|
255
|
+
lines.join("\n")
|
|
256
|
+
end
|
|
257
|
+
# rubocop: enable Metrics/AbcSize
|
|
258
|
+
# rubocop: enable Metrics/MethodLength
|
|
259
|
+
|
|
260
|
+
def word_wrap_column
|
|
261
|
+
value = preferences[:word_wrap]
|
|
262
|
+
return 76 if value.nil?
|
|
263
|
+
|
|
264
|
+
value.to_i
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def reset_output
|
|
268
|
+
@outbound.reset
|
|
269
|
+
end
|
|
270
|
+
|
|
181
271
|
def init_channel_session(channel)
|
|
182
272
|
Session[channel] = self
|
|
183
273
|
@channel = channel
|
|
184
|
-
@inbound = Inbound.new(self)
|
|
185
|
-
@outbound =
|
|
274
|
+
@inbound = Inbound.new(self) if defined?(Inbound)
|
|
275
|
+
@outbound = OutputBuffer.new
|
|
186
276
|
@last_activity = Time.now
|
|
187
277
|
end
|
|
188
278
|
|
|
@@ -230,7 +320,7 @@ class Session
|
|
|
230
320
|
end
|
|
231
321
|
|
|
232
322
|
def process(message, machine = @machine)
|
|
233
|
-
raise ArgumentError, '
|
|
323
|
+
raise ArgumentError, 'Session machine is required' if machine.nil?
|
|
234
324
|
|
|
235
325
|
@machine = machine
|
|
236
326
|
@buffer = sanitize(message)
|
|
@@ -239,10 +329,11 @@ class Session
|
|
|
239
329
|
|
|
240
330
|
expose_to(machine)
|
|
241
331
|
update(machine)
|
|
332
|
+
drain_output
|
|
242
333
|
end
|
|
243
334
|
|
|
244
335
|
def respond
|
|
245
|
-
|
|
336
|
+
drain_output
|
|
246
337
|
end
|
|
247
338
|
|
|
248
339
|
def safely_progress(machine = self)
|
data/lib/story_teller/stdlib.rb
CHANGED
data/lib/story_teller/version.rb
CHANGED