Sha256: 36b140428d7d341dab2d42daf4810a5e61015cb8c0f43b7ad032dcebd595ca9d

Contents?: true

Size: 1.52 KB

Versions: 1

Compression:

Stored size: 1.52 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!
      @conductor_thread = Thread.new { execute }
    end

    def execute
      while true
        if (command=command_queue.pop)
          apply(command)
        end
        sleep 0.01
      end
    end

    def halt!
      @conductor_thread.terminate
    end

    def mutex
      @mutex = Mutex.new
    end

    def apply(command)
      mutex.synchronize do
        handler_for(command).handle(command.attrs)
      end
    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.2 lib/metacosm/simulation.rb