lib/simple_states.rb in simple_states-1.1.0.rc11 vs lib/simple_states.rb in simple_states-2.0.0
- old
+ new
@@ -1,90 +1,70 @@
-require 'active_support/core_ext/object/try'
+require 'simple_states/states'
module SimpleStates
- class TransitionException < RuntimeError; end
+ class Error < RuntimeError; end
- autoload :Event, 'simple_states/event'
- autoload :States, 'simple_states/states'
-
class << self
- def included(base)
- base.extend(SimpleStates::ClassMethods)
- define_accessors(base, :state_names, :state_options, :initial_state, :events)
- set_defaults(base)
+ def included(const)
+ states = const.const_set(:States, States.new)
+ const.send(:prepend, states) if const.respond_to?(:prepend)
+ const.extend(ClassMethods)
+ const.initial_state = :created
+ const.after_initialize(:init_state) if const.respond_to?(:after_initialize)
end
-
- def define_accessors(base, *names)
- base.singleton_class.send(:attr_accessor, *names)
- base.public_class_method(*names + names.map { |name| "#{name}=".to_sym })
- end
-
- def set_defaults(base)
- base.after_initialize(:init_state) if base.respond_to?(:after_initialize)
- base.initial_state = :created
- base.state_names = []
- base.state_options = {}
- base.events = []
- end
end
module ClassMethods
+ attr_accessor :initial_state
+
def new(*)
- super.tap { |object| States.init(object) }
+ super.tap { |object| object.init_state }
end
- def allocate
- super.tap { |object| States.init(object) }
+ def event(name, opts = {})
+ method = name == :all ? :update_events : :define_event
+ self::States.send(method, name, opts)
end
- def states(*args)
- options = args.last.is_a?(Hash) ? args.pop : {}
- self.initial_state = options.delete(:initial).to_sym if options.key?(:initial)
- self.state_options = options
- add_states(*[self.initial_state].concat(args))
+ def state?(state)
+ states.include?(state)
end
- def add_states(*names)
- self.state_names = self.state_names.concat(names.compact.map(&:to_sym)).uniq
+ def states
+ [initial_state] + self::States.states
end
-
- def event(name, options = {})
- add_states(options[:to], *options[:from])
- self.events << [name, options]
- end
-
- def states_module
- const_defined?(*args) ? self::StatesProxy : const_set(:StatesProxy, Module.new)
- end
end
- attr_reader :past_states
-
def init_state
- self.state = self.class.initial_state if state.nil?
+ singleton_class.send(:include, self.class::States) unless self.class.respond_to?(:prepend)
+ self.state = self.class.initial_state if self.state.nil?
end
def state=(state)
super(state.to_sym)
end
def state
- super.try(:to_sym)
+ state = super
+ state.to_sym if state
end
+ def state?(state)
+ self.state.to_sym == state.to_sym
+ end
+
def reset_state
self.state = self.class.initial_state
- self.class.events.map { |*args| Event.new(*args).reset(self) }
+ self.class::States.events.map { |_, event| event.reset(self) }
end
- def past_states
- @past_states ||= []
+ def respond_to?(name)
+ state = name.to_s[0..-2].to_sym
+ name.to_s[-1] == '?' && self.class.state?(state) || super
end
- def state?(state, include_past = false)
- include_past ? was_state?(state) : self.state.try(:to_sym) == state.to_sym
- end
-
- def was_state?(state)
- past_states.concat([self.state.try(:to_sym)]).compact.include?(state.to_sym)
+ def method_missing(name, *args)
+ state = name.to_s[0..-2].to_sym
+ return super unless name.to_s[-1] == '?' && self.class.state?(state)
+ state?(state)
end
end