24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'lib/multiflow.rb', line 24
def stateflow(&block)
@machines ||= []
machine = Multiflow::Machine.new(&block)
@machines << machine
reader = :"machine_#{machine.state_column}"
state = :"current_#{machine.state_column}"
mach_ivar = :"@#{reader}"
state_ivar = :"@#{state}"
if respond_to?(reader)
raise ArgumentError, "Machine for #{machine.state_column} is already defined"
end
define_method(reader) do
self.class.send reader
end
define_singleton_method(reader) do
instance_variable_get(mach_ivar)
end
instance_variable_set(mach_ivar, machine)
define_method(state) do
state = instance_variable_get(state_ivar)
if state.nil?
loaded = load_from_persistence(machine)
if loaded.nil?
state = machine.initial_state
else
state = machine.states[loaded.to_sym]
end
instance_variable_set(state_ivar, state)
end
state
end
define_method("set_#{state}") do |state, options = {}|
save_to_persistence(machine, state.name.to_s, options)
instance_variable_set(state_ivar, state)
end
machine.states.values.each do |state|
state_name = state.name
define_method(:"#{state_name}?") do
state_name == send(:"current_#{machine.state_column}").name
end
if machine.create_scopes?
add_scope(machine, state)
end
end
machine.events.keys.each do |key|
define_method(key.to_sym) do
fire_event(machine, key, :save => false)
end
define_method(:"#{key}!") do
fire_event(machine, key, :save => true)
end
end
end
|