Class: Inform::IO::Session

Inherits:
Object show all
Extended by:
SessionManagementMethods
Includes:
SessionStateManagementMethods
Defined in:
lib/runtime/session.rb

Overview

TODO: Refactor method implementations into modules

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::Registry, SessionManagementMethods::SessionsByChannel

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SessionManagementMethods

[], []=, add_promiscuous_states, get, include?, register, sessions_by_channel, unregister

Methods included from SessionStateManagementMethods

#[], #[]=, #delete, #include?, #keys, #values

Constructor Details

#initialize(channel = nil) ⇒ Session

Returns a new instance of Session.



104
105
106
107
108
109
110
# File 'lib/runtime/session.rb', line 104

def initialize(channel = nil)
  init_channel_session(channel) unless channel.nil?
  @status = nil
  @last_good_state = @state = default if respond_to? :default
  @session_data = {}
  @settings = {}
end

Instance Attribute Details

#channelObject

Returns the value of attribute channel.



101
102
103
# File 'lib/runtime/session.rb', line 101

def channel
  @channel
end

#inboundObject (readonly)

Returns the value of attribute inbound.



102
103
104
# File 'lib/runtime/session.rb', line 102

def inbound
  @inbound
end

#last_activityObject (readonly)

Returns the value of attribute last_activity.



102
103
104
# File 'lib/runtime/session.rb', line 102

def last_activity
  @last_activity
end

#last_good_stateObject (readonly)

Returns the value of attribute last_good_state.



102
103
104
# File 'lib/runtime/session.rb', line 102

def last_good_state
  @last_good_state
end

#outboundObject (readonly)

Returns the value of attribute outbound.



102
103
104
# File 'lib/runtime/session.rb', line 102

def outbound
  @outbound
end

#previousObject (readonly)

Returns the value of attribute previous.



102
103
104
# File 'lib/runtime/session.rb', line 102

def previous
  @previous
end

#settingsObject (readonly)

Returns the value of attribute settings.



102
103
104
# File 'lib/runtime/session.rb', line 102

def settings
  @settings
end

#stateObject

Returns the value of attribute state.



101
102
103
# File 'lib/runtime/session.rb', line 101

def state
  @state
end

#statusObject

Returns the value of attribute status.



101
102
103
# File 'lib/runtime/session.rb', line 101

def status
  @status
end

Instance Method Details

#after_updateObject



133
134
135
# File 'lib/runtime/session.rb', line 133

def after_update
  # Override for application implementations
end

#confusedObject



187
188
189
190
191
192
193
# File 'lib/runtime/session.rb', line 187

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

#exit_command?(message) ⇒ Boolean

Returns:

  • (Boolean)


147
148
149
# File 'lib/runtime/session.rb', line 147

def exit_command?(message)
  !Promiscuous.include?(@state) && ExitCommandPattern.match?(message)
end

#init_channel_session(channel) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/runtime/session.rb', line 112

def init_channel_session(channel)
  Session[channel] = self
  @channel = channel
  @inbound = Inbound.new(self)
  @outbound = Outbound.new(self)
  @last_activity = Time.now
end

#process(message) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/runtime/session.rb', line 151

def process(message)
  return disconnect if exit_command?(message)
  @buffer = message
  @last_activity = Time.now
  @status = :active
  if valid_state?
    update
  else
    @inbound.publish @buffer
  end

  respond
end

#receive(message) ⇒ Object



120
121
122
123
124
125
# File 'lib/runtime/session.rb', line 120

def receive(message)
  return if message.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(message))
end

#respondObject



165
166
167
# File 'lib/runtime/session.rb', line 165

def respond
  flush_io
end

#safely_progress(machine = self) ⇒ Object



169
170
171
172
173
174
175
176
# File 'lib/runtime/session.rb', line 169

def safely_progress(machine = self)
  @state = machine.send(@state)
  raise 'Bad state machine implementation: nil state' if @state.nil?
rescue StandardError => e
  log.error "Error updating state: #{e.message}", e
  log.warn "Reverting to last known good state #{@last_good_state}"
  @state = @last_good_state
end

#sanitize(message) ⇒ Object



137
138
139
# File 'lib/runtime/session.rb', line 137

def sanitize(message)
  message.to_s.strip.scan(/[[:print:]]/).join
end

#sessionObject



141
142
143
# File 'lib/runtime/session.rb', line 141

def session
  self
end

#update(machine = self) ⇒ Object



127
128
129
130
131
# File 'lib/runtime/session.rb', line 127

def update(machine = self)
  safely_progress(machine)
  after_update if self.respond_to?(:after_update)
  @last_good_state = @state unless @state == :confused
end

#valid_state?(machine = self) ⇒ Boolean

Returns:

  • (Boolean)


178
179
180
181
182
183
184
185
# File 'lib/runtime/session.rb', line 178

def valid_state?(machine = self)
  case @state
  when String, Symbol
    machine.respond_to? @state
  else
    false
  end
end