spoonsix-ssm 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/ssm.rb +35 -47
  2. data/lib/state_machine.rb +8 -1
  3. metadata +2 -2
data/lib/ssm.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require File.join(File.dirname(__FILE__), 'state_machine')
2
+ require File.join(File.dirname(__FILE__), 'injection_strategies', 'base')
2
3
 
3
4
  # SSM - Simple State Machine mixin
4
5
  #
@@ -40,7 +41,7 @@ require File.join(File.dirname(__FILE__), 'state_machine')
40
41
  #--
41
42
  module SSM
42
43
 
43
- VERSION = '0.1.5';
44
+ VERSION = '0.1.6';
44
45
 
45
46
  class InvalidTransition < RuntimeError; end
46
47
  class UndefinedState < RuntimeError; end
@@ -63,6 +64,7 @@ module SSM
63
64
  # the hash will see it as a new key, even though if you inspect the hash you will see two keys whose string
64
65
  # representation is the same.
65
66
  def self.included(klass) #:nodoc:
67
+
66
68
  klass.extend SSM::ClassMethods
67
69
  SSM::TemplateStateMachines[klass] = SSM::StateMachine.new
68
70
 
@@ -81,18 +83,22 @@ module SSM
81
83
  end
82
84
 
83
85
  def klass.setup(instance)
86
+
84
87
  SSM::TemplateStateMachines[self].validate
85
88
 
86
89
  sm = SSM::TemplateStateMachines[self].clone_and_freeze
87
90
  instance.instance_variable_set(:@ssm_state_machine, sm)
88
-
89
- unless sm.property_name.nil?
90
- # This allows others to set up the object however they see fit, including mixing in setters.
91
- instance.instance_eval("def #{sm.property_name}; @#{sm.property_name}; end") unless instance.respond_to?(sm.property_name)
92
- instance.instance_eval("def #{sm.property_name}=(v); @#{sm.property_name} = v; end") unless instance.respond_to?("#{sm.property_name}=".to_sym)
93
-
94
- instance.send(:_synchronize_state)
91
+
92
+ begin
93
+ strategy_name = sm.injection_strategy.nil? ? "object" : sm.injection_strategy.to_s
94
+ module_name = "#{strategy_name.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }}Strategy" # from ActiveSupport
95
+ require File.join(File.dirname(__FILE__), 'injection_strategies', "#{strategy_name}_strategy.rb")
96
+ instance.extend(SSM::InjectionStrategies.const_get(module_name))
97
+ rescue
98
+ raise
95
99
  end
100
+
101
+ instance.ssm_setup
96
102
  end
97
103
 
98
104
  end
@@ -136,7 +142,7 @@ module SSM
136
142
  # class Door
137
143
  # include SSM
138
144
  #
139
- # ssm_property :state
145
+ # ssm_inject_state_into :state
140
146
  # ssm_initial_state :closed
141
147
  # end
142
148
  #
@@ -146,18 +152,18 @@ module SSM
146
152
  # class Door
147
153
  # include SSM
148
154
  #
149
- # ssm_property :state, :use_index
155
+ # ssm_inject_state_into :state, :use_index
150
156
  # ssm_initial_state :closed
151
157
  # end
152
158
  #
153
159
  # Door.new.state #=> 0
154
160
  #
155
- def ssm_property(name, use_index=nil)
161
+ def ssm_inject_state_into(name, options={}, &block)
156
162
  SSM::TemplateStateMachines[self].property_name = name
157
- SSM::TemplateStateMachines[self].use_property_index = use_index.nil? ? false : true
163
+ SSM::TemplateStateMachines[self].use_property_index = options[:map_to_index].nil? ? false : true
164
+ SSM::TemplateStateMachines[self].injection_strategy = options[:strategy] #SSM::InjectionStrategies::Base.factory(options[:strategy])
158
165
  end
159
166
 
160
-
161
167
  # Adds new States. This method takes a string or a symbol.
162
168
  #
163
169
  # class Door
@@ -258,6 +264,7 @@ module SSM
258
264
  # door = Door.new
259
265
  # door.open
260
266
  # door.is?(:opened) #=> true
267
+ #
261
268
  def is?(state_name_or_symbol)
262
269
  _synchronize_state
263
270
  @ssm_state_machine.current_state.name.to_sym == state_name_or_symbol.to_sym
@@ -284,11 +291,22 @@ module SSM
284
291
  # door = Door.new
285
292
  # door.open
286
293
  # door.is?(:closed) #=> false
294
+ #
287
295
  def is_not?(state_name_or_symbol)
288
296
  _synchronize_state
289
297
  @ssm_state_machine.current_state.name.to_sym != state_name_or_symbol.to_sym
290
298
  end
291
299
 
300
+ # Returns a symbol representing the current State
301
+ #
302
+ # door = Door.new
303
+ # door.ssm_state #=> :closed
304
+ #
305
+ def ssm_state
306
+ _synchronize_state
307
+ @ssm_state_machine.current_state.name
308
+ end
309
+
292
310
  private
293
311
 
294
312
  def _ssm_trigger_event(event_name_or_symbol, args)
@@ -296,21 +314,10 @@ module SSM
296
314
  event = @ssm_state_machine.get_event_by_name(event_name_or_symbol)
297
315
 
298
316
  @ssm_state_machine.transition(event.transition)
299
- _update_instance_state_property unless @ssm_state_machine.property_name.nil?
317
+ ssm_set(@ssm_state_machine.get_state_for_property) unless @ssm_state_machine.property_name.nil?
300
318
  instance_exec *args, &event.block
301
319
  end
302
320
 
303
- def _update_instance_state_property
304
- unless @ssm_state_machine.current_state.nil?
305
- if @ssm_state_machine.use_property_index == true
306
- value = @ssm_state_machine.get_state_index_by_name(@ssm_state_machine.current_state.name)
307
- else
308
- value = @ssm_state_machine.current_state.name
309
- end
310
- self.send("#{@ssm_state_machine.property_name}=".to_sym, value)
311
- end
312
- end
313
-
314
321
  # instance_exec for 1.8.x
315
322
  # http://groups.google.com/group/ruby-talk-google/browse_thread/thread/34bc4c9b2cac3424
316
323
  unless instance_methods.include? 'instance_exec' #:nodoc:
@@ -328,39 +335,20 @@ module SSM
328
335
  end
329
336
  end
330
337
 
331
-
332
338
  def _synchronize_state
333
-
334
- if instance_variable_get("@#{@ssm_state_machine.property_name}".to_sym).nil?
335
- state_value = @ssm_state_machine.use_property_index == true ?
336
- @ssm_state_machine.get_state_index_by_name(@ssm_state_machine.current_state.name) :
337
- @ssm_state_machine.current_state.name
338
- send("#{@ssm_state_machine.property_name}=".to_sym, state_value)
339
- else
340
- _update_ssm_state unless _state_up_to_date?
341
- end
339
+ ssm_get.nil? ? ssm_set(@ssm_state_machine.get_state_for_property) : _update_ssm_state unless _state_up_to_date?
342
340
  true
343
341
  end
344
342
 
345
343
  # Checks whether the StateMachine and the property in the instance are in sync
346
344
  def _state_up_to_date?
347
- unless @ssm_state_machine.property_name.nil?
348
- state_value = self.send("#{@ssm_state_machine.property_name}".to_sym)
349
- if @ssm_state_machine.use_property_index == true
350
- state_value == @ssm_state_machine.get_state_index_by_name(@ssm_state_machine.current_state.name)
351
- else
352
- state_value == @ssm_state_machine.current_state.name
353
- end
354
- else
355
- true
356
- end
345
+ @ssm_state_machine.property_name.nil? ? true : ssm_get == @ssm_state_machine.get_state_for_property
357
346
  end
358
347
 
359
348
  # Updates the StateMachine based on the value of the state property of the instance
360
349
  def _update_ssm_state
361
350
  unless @ssm_state_machine.property_name.nil?
362
- state_value = send("#{@ssm_state_machine.property_name}".to_sym)
363
- @ssm_state_machine.current_state = @ssm_state_machine.use_property_index == true ? @ssm_state_machine.get_state_by_index(state_value) : @ssm_state_machine.get_state_by_name(state_value)
351
+ @ssm_state_machine.current_state = @ssm_state_machine.use_property_index == true ? @ssm_state_machine.get_state_by_index(ssm_get) : @ssm_state_machine.get_state_by_name(ssm_get)
364
352
  end
365
353
  end
366
354
  end
data/lib/state_machine.rb CHANGED
@@ -6,10 +6,13 @@ module SSM
6
6
 
7
7
  class StateMachine
8
8
 
9
- attr_reader :initial_state
9
+ attr_reader :initial_state
10
10
  attr_accessor :current_state
11
+
11
12
  attr_accessor :property_name
12
13
  attr_accessor :use_property_index
14
+ attr_accessor :injection_strategy
15
+
13
16
  attr_reader :states
14
17
  attr_reader :events
15
18
 
@@ -66,6 +69,10 @@ module SSM
66
69
  @events.find { |existing_event| existing_event.equal(event_to_compare) }
67
70
  end
68
71
 
72
+ def get_state_for_property
73
+ @use_property_index == true ? get_state_index_by_name(@current_state.name) : @current_state.name
74
+ end
75
+
69
76
  def get_state_by_name(name)
70
77
  state = @states.find { |state| state.name == name}
71
78
  raise SSM::UndefinedState.new unless state.is_a?(SSM::State)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spoonsix-ssm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luis Correa d'Almeida
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-12 00:00:00 -07:00
12
+ date: 2009-07-13 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15