Module: AlterEgo::ClassMethods

Includes:
FailFast::Assertions
Defined in:
lib/alter_ego.rb

Instance Method Summary collapse

Instance Method Details

#add_request_filter(state_pattern, request_pattern, new_state_pattern, action) ⇒ Object



298
299
300
301
302
303
# File 'lib/alter_ego.rb', line 298

def add_request_filter(state_pattern, request_pattern, new_state_pattern, action)
  @request_filters << RequestFilter.new(state_pattern,
                                        request_pattern,
                                        new_state_pattern,
                                        action)
end

#add_state(new_state, identifier = new_state.identifier, options = {}) ⇒ Object



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/alter_ego.rb', line 262

def add_state(new_state, identifier=new_state.identifier, options = {})
  assert_only_keys(options, :default)

  self.states[identifier] = new_state.new

  if options[:default]
    if @default_state
      raise InvalidDefinitionError, "Cannot have more than one default state"
    end
    @default_state = identifier
  end

  new_requests = (new_state.handled_requests - all_handled_requests)
  new_requests.each do |request|
    @state_proxy.send(:define_method, request) do |*args|
      args.unshift(self)
      begin
        continue = execute_request_filters(current_state.identifier,
                                           request,
                                           nil)
        return false unless continue
        current_state.send(request, *args)
      rescue NoMethodError => error
        if error.name.to_s == request.to_s
          raise WrongStateError,
                "Request '#{request}' not supported by state #{current_state}"
        else
          raise
        end
      end
    end
  end

  self.request_filters += new_state.request_filters
end

#all_handled_requestsObject



248
249
250
251
252
# File 'lib/alter_ego.rb', line 248

def all_handled_requests
  methods = @state_proxy.public_instance_methods(false)
  methods -= ["identifier", "on_enter", "on_exit"]
  methods.map{|m| m.to_sym}
end

#default_stateObject



305
306
307
# File 'lib/alter_ego.rb', line 305

def default_state
  @default_state
end

#request_filter(options, &block) ⇒ Object



235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/alter_ego.rb', line 235

def request_filter(options, &block)
  assert_only_keys(options, :state, :request, :new_state, :action)
  options = {
    :state     => not_nil,
    :request   => not_nil,
    :new_state => nil
  }.merge(options)
  add_request_filter(options[:state],
                     options[:request],
                     options[:new_state],
                     AlterEgo.proc_from_symbol_or_block(options[:method], &block))
end

#request_filtersObject



309
310
311
# File 'lib/alter_ego.rb', line 309

def request_filters
  (@request_filters ||= [])
end

#state(identifier, options = {}, &block) ⇒ Object



223
224
225
226
227
228
229
230
231
232
233
# File 'lib/alter_ego.rb', line 223

def state(identifier, options={}, &block)
  if states.has_key?(identifier)
    raise InvalidDefinitionError, "State #{identifier.inspect} already defined"
  end
  new_state = Class.new(State)
  new_state_eigenclass = class << new_state; self; end
  new_state_eigenclass.send(:define_method, :identifier) { identifier }
  new_state.instance_eval(&block) if block

  add_state(new_state, identifier, options)
end

#statesObject



254
255
256
# File 'lib/alter_ego.rb', line 254

def states
  (@states ||= {})
end

#states=(value) ⇒ Object



258
259
260
# File 'lib/alter_ego.rb', line 258

def states=(value)
  @states = value
end