module Startback module Websocket module Hub class Builder def initialize(context, default_handler = nil, *bl_args, &bl) @context = context @default_handler = default_handler @middlewares = [] @commands = {} @rooms = {} @bl_args instance_exec *bl_args, &bl end def use(middleware, *opts) @middlewares << proc { |app| middleware.new(app, *opts) } end def command(name, &bl) cname = name.to_sym raise "Command #{name} already defined: #{name}" if @commands[cname] @commands[cname] = proc { |app| Middleware::CommandHandler.new(app, { :name => name }, &bl) } @middlewares << @commands[cname] end def room(name, &bl) raise "Room names must be strings" unless name.is_a? String raise "Room '#{name}' already defined" if @rooms[name] @rooms[name] ||= Room.new(name) handler = Builder.new(@context, nil, @rooms[name], &bl).to_handler middleware = proc { |app| Middleware::RoomHandler.new(app, @rooms[name], handler) } @middlewares << middleware end def to_handler default_handler = @default_handler || proc {} @middlewares .reverse .reduce(default_handler) do |handler, mw| mw.call(handler) end end def to_websocket_app App.new(@context, @rooms, to_handler) end end # class Builder end # module Hub end # module Websocket end # module Startback