require '../lib/legs'
# this is a work in progress, api's will change and break, one day there will be a functional matching
# client in shoes or something
Legs.start do
def initialize
@rooms = Hash.new { {'users' => [], 'messages' => [], 'topic' => 'No topic set'} }
@rooms['Lobby'] = {'topic' => 'General Chit Chat', 'messages' => [], 'users' => []}
end
# returns a list of available rooms
def rooms
room_list = Hash.new
@rooms.keys.each { |rn| room_list[rn] = room_object rn, :remote, :topic, :users, :messages }
room_list
end
# joins/creates a room
def join(room_name)
unless @rooms.keys.include?(room_name)
@rooms[room_name.to_s] = @rooms[room_name]
broadcast :room_created, room_name
end
# room = room_object(room_name)
#
# unless room['users'].include?(caller)
# broadcast room['users'], 'user_joined', room_name, user_object(caller)
# room['users'].push(caller)
# end
room_object room_name, :remote
end
# leaves a room
def leave(room_name)
room = @rooms[room_name.to_s]
room['users'].delete(caller)
broadcast room['users'], 'user_left', room_name, user_object(caller)
true
end
# sets the room topic message
def topic=(room, message)
room = @rooms[room.to_s]
room['topic'] = message.to_s
broadcast room['users'], 'room_changed', room_object(room, :remote, :name, :topic)
end
# sets the user's name
def name=(name)
caller.meta[:name] = name.to_s
user_rooms(caller).each do |room_name|
broadcast @rooms[room_name]['users'], 'user_changed', user_object(caller)
end
true
end
# returns information about ones self, clients thusly can find out their user 'id' number
def user(object_id = nil)
user = user_object( object_id.nil? ? caller : find_user_by_object_id(object_id) }.first )
user['rooms'] = user_rooms(user)
return user
end
# posts a message to a room
def post_message(room_name, message)
room = room_object(room_name)
room['messages'].push(msg = {'user' => user_object(caller), 'time' => Time.now.to_i, 'message' => message.to_s} )
trim_messages room
broadcast room['users'], 'message', room_name.to_s, msg
return msg
end
private
# trims the message backlog
def trim_messages room
room = room_object(room) if room.is_a?(String)
while room['messages'].length > 250
room['messages'].shift
end
end
# makes a user object suitable for sending back with meta info and stuff
def user_object user
object = {'id' => user.object_id}
user.meta.each_pair do |key, value|
object[key.to_s] = value
end
return object
end
def room_object room_name, target = :local, *only
object = @rooms[room_name.to_s].dup
object['users'].delete_if {|user| user.connected? == false }
object['users'] = object['users'].map { |user| user_object(user) } if target == :remote
object['topic'] = 'No topic set' if object['topic'].nil? or object['topic'].empty?
object['name'] = room_name.to_s if target == :remote
object.delete_if { |key, value| only.include?(key.to_sym) == false } unless only.empty?
object
end
# returns all the room names the user is in.
def user_rooms user
@rooms.values.select { |room| room['users'].include?(user) }.map { |room| @rooms.index(room) }
end
end
sleep