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