Sha256: 74b1ffe561d114d16a91a31081d8cd328df16450d24b8b6aa38e2974242a3730

Contents?: true

Size: 1.53 KB

Versions: 1

Compression:

Stored size: 1.53 KB

Contents

module Metacosm
  class Simulation
    attr_accessor :running
    def watch(model)
      Frappuccino::Stream.new(model).on_value(&method(:receive))
    end

    def fire(command)
      command_queue.push(command)
    end

    def command_queue
      @command_queue ||= Queue.new
    end

    def conduct!
      @running = true
      @conductor_thread = Thread.new { execute }
    end

    def execute
      while @running
        if (command=command_queue.pop)
          # p [ :applying!, command: command ]
          apply(command)
        end
        sleep 0.01
      end
    end

    def halt!
      @running = false
      @conductor_thread.terminate
    end

    def apply(command)
      handler_for(command).handle(command.attrs)
    end

    def receive(event, record: true)
      events.push(event) if record

      listener = listener_for(event)
      if event.attrs.any?
        listener.receive(event.attrs)
      else
        listener.receive
      end
    end

    def events
      @events ||= []
    end

    def self.current
      @current ||= new
    end

    def clear!
      @events = []
    end

    protected
    def handler_for(command)
      @handlers ||= {}
      @handlers[command] ||= Object.const_get(command.class.name.split('::').last + "Handler").new
    end

    def listener_for(event)
      @listeners ||= {}
      @listeners[event] ||= construct_listener_for(event)
    end

    def construct_listener_for(event)
      listener = Object.const_get(event.class.name.split('::').last + "Listener").new(self)
      listener
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
metacosm-0.2.0 lib/metacosm/simulation.rb