State machine gubbins. We need tests.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
require 'eventmachine'
|
require 'eventmachine'
|
||||||
|
require 'stringio'
|
||||||
require 'btc_wire_proto'
|
require 'btc_wire_proto'
|
||||||
|
|
||||||
module EventMachine
|
module EventMachine
|
||||||
@@ -26,10 +27,11 @@ module EventMachine
|
|||||||
# Sets up the variables required to manage the state machine. Should be
|
# Sets up the variables required to manage the state machine. Should be
|
||||||
# called before you try to push a state - in post_init, say.
|
# called before you try to push a state - in post_init, say.
|
||||||
def init_state!
|
def init_state!
|
||||||
|
@stream = StringIO.new("")
|
||||||
@state_m = Mutex.new # Synchronize around @states and @working
|
@state_m = Mutex.new # Synchronize around @states and @working
|
||||||
@state_m.synchronize do
|
@state_m.synchronize do
|
||||||
@states = []
|
@states = []
|
||||||
@working = false
|
@current_state = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -41,6 +43,20 @@ module EventMachine
|
|||||||
[false, "configuration check not implemented yet"]
|
[false, "configuration check not implemented yet"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Grabs the state that we're currently working on.
|
||||||
|
# @return[Array[Symbol,Object]] state symbol + data
|
||||||
|
def get_state
|
||||||
|
@state_m.synchronize do
|
||||||
|
@current_state ||= @states.shift
|
||||||
|
@current_state
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Call this when we've completed the actions required by the current state
|
||||||
|
def finished_state
|
||||||
|
@state_m.synchronize { @current_state = nil }
|
||||||
|
end
|
||||||
|
|
||||||
# Push a state to the end of the state queue.
|
# Push a state to the end of the state queue.
|
||||||
def state(new_state, data = nil)
|
def state(new_state, data = nil)
|
||||||
@state_m.synchronize { @states.push(new_state, data) }
|
@state_m.synchronize { @states.push(new_state, data) }
|
||||||
@@ -50,6 +66,24 @@ module EventMachine
|
|||||||
def state!(new_state, data = nil)
|
def state!(new_state, data = nil)
|
||||||
@state_m.synchronize { @states.unshift(new_state, data) }
|
@state_m.synchronize { @states.unshift(new_state, data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Do some work on the state machine
|
||||||
|
def state_tick
|
||||||
|
state, data = get_state
|
||||||
|
return unless state
|
||||||
|
if respond_to?(state)
|
||||||
|
send(state, data)
|
||||||
|
else
|
||||||
|
raise NotImplementedError.new("Unknown state: #{state} with #{data}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Receiving data mostly drives the state machine. Where something wants
|
||||||
|
# to send data, it gets queued straight onto the I/O/
|
||||||
|
def receive_data(io)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# State machine behaviours now.
|
# State machine behaviours now.
|
||||||
|
|
||||||
@@ -85,6 +119,10 @@ module EventMachine
|
|||||||
def post_init
|
def post_init
|
||||||
state(:send_ver)
|
state(:send_ver)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def connection_completed
|
||||||
|
advance_state
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# EventMachine protocol class that handles an *incoming* connection from
|
# EventMachine protocol class that handles an *incoming* connection from
|
||||||
|
Reference in New Issue
Block a user