Class: StoryTeller::IO::Session
- Extended by:
- SessionManagementMethods
- Includes:
- SessionStateManagementMethods
- Defined in:
- lib/story_teller/session.rb
Overview
The Session class TODO: Refactor method implementations into modules rubocop: disable Metrics/ClassLength
Constant Summary collapse
- Promiscuous =
These states accept any input, including no input
Set.new
- ExitCommandPattern =
/^(exit|quit|q)$/i.freeze
Constants included from SessionManagementMethods
SessionManagementMethods::SessionsByChannel, SessionManagementMethods::SessionsByPlayer
Instance Attribute Summary collapse
-
#channel ⇒ Object
Returns the value of attribute channel.
-
#inbound ⇒ Object
readonly
Returns the value of attribute inbound.
-
#last_activity ⇒ Object
readonly
Returns the value of attribute last_activity.
-
#last_good_state ⇒ Object
readonly
Returns the value of attribute last_good_state.
-
#machine ⇒ Object
Returns the value of attribute machine.
-
#outbound ⇒ Object
readonly
Returns the value of attribute outbound.
-
#player ⇒ Object
Returns the value of attribute player.
-
#previous ⇒ Object
readonly
Returns the value of attribute previous.
-
#settings ⇒ Object
(also: #preferences)
readonly
Returns the value of attribute settings.
-
#state ⇒ Object
Returns the value of attribute state.
-
#status ⇒ Object
Returns the value of attribute status.
Instance Method Summary collapse
- #after_update ⇒ Object
- #confused ⇒ Object
- #control(player) ⇒ Object
- #drain_output ⇒ Object
- #exit_command?(message) ⇒ Boolean
- #expose_to(machine) ⇒ Object
- #init_channel_session(channel) ⇒ Object
-
#initialize(channel = nil, machine: nil, player: nil, state: :playing, settings: {}) ⇒ Session
constructor
rubocop: disable Metrics/MethodLength.
- #process(message, machine = @machine) ⇒ Object
- #receive(message) ⇒ Object
- #reset_output ⇒ Object
- #respond ⇒ Object
- #safely_progress(machine = self) ⇒ Object
- #sanitize(message) ⇒ Object
- #session ⇒ Object
- #tidy_output(value, columns = word_wrap_column) ⇒ Object
- #update(machine = @machine) ⇒ Object
- #valid_state?(machine = self) ⇒ Boolean
-
#word_wrap_column ⇒ Object
rubocop: enable Metrics/AbcSize rubocop: enable Metrics/MethodLength.
-
#wrap_line(line, columns) ⇒ Object
rubocop: disable Metrics/AbcSize rubocop: disable Metrics/MethodLength.
- #write_output(value) ⇒ Object
Methods included from SessionManagementMethods
[], []=, add_promiscuous_states, channels, get, include?, of, players, register, register_player, release_player, sessions_by_channel, sessions_by_player, unregister
Methods included from SessionStateManagementMethods
#[], #[]=, #delete, #include?, #keys, #values
Constructor Details
#initialize(channel = nil, machine: nil, player: nil, state: :playing, settings: {}) ⇒ Session
rubocop: disable Metrics/MethodLength
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/story_teller/session.rb', line 190 def initialize(channel = nil, machine: nil, player: nil, state: :playing, settings: {}) @channel = channel @machine = machine @player = nil @state = state @last_good_state = state @session_data = {} @settings = settings @status = nil @last_activity = Time.now @outbound = OutputBuffer.new self.class.register(channel, self) unless channel.nil? control(player) unless player.nil? end |
Instance Attribute Details
#channel ⇒ Object
Returns the value of attribute channel.
183 184 185 |
# File 'lib/story_teller/session.rb', line 183 def channel @channel end |
#inbound ⇒ Object (readonly)
Returns the value of attribute inbound.
184 185 186 |
# File 'lib/story_teller/session.rb', line 184 def inbound @inbound end |
#last_activity ⇒ Object (readonly)
Returns the value of attribute last_activity.
184 185 186 |
# File 'lib/story_teller/session.rb', line 184 def last_activity @last_activity end |
#last_good_state ⇒ Object (readonly)
Returns the value of attribute last_good_state.
184 185 186 |
# File 'lib/story_teller/session.rb', line 184 def last_good_state @last_good_state end |
#machine ⇒ Object
Returns the value of attribute machine.
183 184 185 |
# File 'lib/story_teller/session.rb', line 183 def machine @machine end |
#outbound ⇒ Object (readonly)
Returns the value of attribute outbound.
184 185 186 |
# File 'lib/story_teller/session.rb', line 184 def outbound @outbound end |
#player ⇒ Object
Returns the value of attribute player.
183 184 185 |
# File 'lib/story_teller/session.rb', line 183 def player @player end |
#previous ⇒ Object (readonly)
Returns the value of attribute previous.
184 185 186 |
# File 'lib/story_teller/session.rb', line 184 def previous @previous end |
#settings ⇒ Object (readonly) Also known as: preferences
Returns the value of attribute settings.
184 185 186 |
# File 'lib/story_teller/session.rb', line 184 def settings @settings end |
#state ⇒ Object
Returns the value of attribute state.
183 184 185 |
# File 'lib/story_teller/session.rb', line 183 def state @state end |
#status ⇒ Object
Returns the value of attribute status.
183 184 185 |
# File 'lib/story_teller/session.rb', line 183 def status @status end |
Instance Method Details
#after_update ⇒ Object
299 300 301 |
# File 'lib/story_teller/session.rb', line 299 def after_update # Override for application implementations end |
#confused ⇒ Object
357 358 359 360 361 362 363 |
# File 'lib/story_teller/session.rb', line 357 def confused println "The session is in an unknown state: #{@state}" println "The last known good session state was: #{@last_good_state}" println "Reverting the session to its last known good state, for better or worse." prompt @last_good_state end |
#control(player) ⇒ Object
279 280 281 282 283 284 |
# File 'lib/story_teller/session.rb', line 279 def control(player) self.class.release_player(@player, self) @player = player self.class.register_player(player, self) unless player.nil? self end |
#drain_output ⇒ Object
213 214 215 |
# File 'lib/story_teller/session.rb', line 213 def drain_output tidy_output(@outbound.drain) end |
#exit_command?(message) ⇒ Boolean
318 319 320 |
# File 'lib/story_teller/session.rb', line 318 def exit_command?() !Promiscuous.include?(@state) && ExitCommandPattern.match?() end |
#expose_to(machine) ⇒ Object
311 312 313 314 |
# File 'lib/story_teller/session.rb', line 311 def expose_to(machine) machine.instance_variable_set(:@buffer, @buffer) machine.instance_variable_set(:@session, self) end |
#init_channel_session(channel) ⇒ Object
271 272 273 274 275 276 277 |
# File 'lib/story_teller/session.rb', line 271 def init_channel_session(channel) Session[channel] = self @channel = channel @inbound = Inbound.new(self) if defined?(Inbound) @outbound = OutputBuffer.new @last_activity = Time.now end |
#process(message, machine = @machine) ⇒ Object
322 323 324 325 326 327 328 329 330 331 332 333 |
# File 'lib/story_teller/session.rb', line 322 def process(, machine = @machine) raise ArgumentError, 'Session machine is required' if machine.nil? @machine = machine @buffer = sanitize() @last_activity = Time.now @status = :active expose_to(machine) update(machine) drain_output end |
#receive(message) ⇒ Object
286 287 288 289 290 291 |
# File 'lib/story_teller/session.rb', line 286 def receive() return if .nil? # It is okay if the message parameter is an empty string return disconnected if @channel.nil? return disconnected unless @channel.isActive() && @channel.isOpen() process(sanitize()) end |
#reset_output ⇒ Object
267 268 269 |
# File 'lib/story_teller/session.rb', line 267 def reset_output @outbound.reset end |
#respond ⇒ Object
335 336 337 |
# File 'lib/story_teller/session.rb', line 335 def respond drain_output end |
#safely_progress(machine = self) ⇒ Object
339 340 341 342 343 344 345 346 |
# File 'lib/story_teller/session.rb', line 339 def safely_progress(machine = self) @state = machine.public_send(@state) raise 'Bad state machine implementation: nil state' if @state.nil? rescue StandardError => e log.error "Error updating state: #{e.}", e log.warn "Reverting to last known good state #{@last_good_state}" @state = @last_good_state end |
#sanitize(message) ⇒ Object
303 304 305 |
# File 'lib/story_teller/session.rb', line 303 def sanitize() .to_s.strip.scan(/[[:print:]]/).join end |
#session ⇒ Object
307 308 309 |
# File 'lib/story_teller/session.rb', line 307 def session self end |
#tidy_output(value, columns = word_wrap_column) ⇒ Object
217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/story_teller/session.rb', line 217 def tidy_output(value, columns = word_wrap_column) output = value.to_s return '' if output.empty? columns = columns.to_i return output if columns <= 0 # output = output.gsub(/^\n+/, "\n") output.each_line.map do |line| newline = line.end_with?("\n") ? "\n" : '' wrap_line(line.chomp, columns) + newline end.join end |
#update(machine = @machine) ⇒ Object
293 294 295 296 297 |
# File 'lib/story_teller/session.rb', line 293 def update(machine = @machine) safely_progress(machine) after_update if self.respond_to?(:after_update) @last_good_state = @state unless @state == :confused end |
#valid_state?(machine = self) ⇒ Boolean
348 349 350 351 352 353 354 355 |
# File 'lib/story_teller/session.rb', line 348 def valid_state?(machine = self) case @state when String, Symbol machine.respond_to?(@state) else false end end |
#word_wrap_column ⇒ Object
rubocop: enable Metrics/AbcSize rubocop: enable Metrics/MethodLength
260 261 262 263 264 265 |
# File 'lib/story_teller/session.rb', line 260 def word_wrap_column value = preferences[:word_wrap] return 76 if value.nil? value.to_i end |
#wrap_line(line, columns) ⇒ Object
rubocop: disable Metrics/AbcSize rubocop: disable Metrics/MethodLength
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/story_teller/session.rb', line 233 def wrap_line(line, columns) return line if line.length <= columns indentation = line[/\A[ \t]*/].to_s words = line.strip.split(/[ \t]+/) return line if words.empty? lines = [] current = indentation.dup words.each do |word| candidate = current == indentation ? "#{current}#{word}" : "#{current} #{word}" if candidate.length <= columns || current == indentation current = candidate else lines << current.rstrip current = "#{indentation}#{word}" end end lines << current.rstrip lines.join("\n") end |
#write_output(value) ⇒ Object
209 210 211 |
# File 'lib/story_teller/session.rb', line 209 def write_output(value) @outbound.write(value) end |