Saturday, January 15, 2011

Active Objects with Ruby & Revactor

I wanted to try going back to basics by writing a MUD in Ruby. MUDs are simple, but are also good candidates for testing concurrency in a language. Handling multiple connections, persisting state, and handling events that happen asynchronously seems like a good job for Active Objects. Here's a simple implementation using Revactor:
#
# Revactor requires Ruby >= 1.9.0
#

require 'revactor'

class ActiveObject

  def initialize( klass )
    @actor = Actor.spawn( klass.new(), &method( :actor_run ) )
  end

  def actor_run( object )
    loop do
      Actor.receive do |filter|
        filter.when( Case[Symbol, Array] ) do |method_name, arguments|
          object.send( method_name, arguments )
        end
      end
    end
  end

  def method_missing( method_name, *arguments, &block )
    @actor << [method_name, arguments]
  end

end

class MudPlayer

  def foo( bar )
    puts bar
  end

end

actor = ActiveObject.new( MudPlayer )
actor.foo( 10 )
actor.foo( 20 )

Actor.reschedule()