diff --git a/lib/em-bitcoin.rb b/lib/em-bitcoin.rb index 40e277e..e6d01e8 100644 --- a/lib/em-bitcoin.rb +++ b/lib/em-bitcoin.rb @@ -1,4 +1,5 @@ require 'eventmachine' +require 'stringio' require 'btc_wire_proto' module EventMachine @@ -26,10 +27,11 @@ module EventMachine # Sets up the variables required to manage the state machine. Should be # called before you try to push a state - in post_init, say. def init_state! + @stream = StringIO.new("") @state_m = Mutex.new # Synchronize around @states and @working @state_m.synchronize do @states = [] - @working = false + @current_state = nil end end @@ -41,6 +43,20 @@ module EventMachine [false, "configuration check not implemented yet"] 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. def state(new_state, data = nil) @state_m.synchronize { @states.push(new_state, data) } @@ -50,6 +66,24 @@ module EventMachine def state!(new_state, data = nil) @state_m.synchronize { @states.unshift(new_state, data) } 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. @@ -85,6 +119,10 @@ module EventMachine def post_init state(:send_ver) end + + def connection_completed + advance_state + end end # EventMachine protocol class that handles an *incoming* connection from