<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -2,13 +2,13 @@ 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
-class User; attr_accessor :id, :name; end
 
 Legs.start do
   def initialize
     @rooms = Hash.new { {'users' =&gt; [], 'messages' =&gt; [], 'topic' =&gt; 'No topic set'} }
     @rooms['Lobby'] = {'topic' =&gt; 'General Chit Chat', 'messages' =&gt; [], 'users' =&gt; []}
   end
+  
   # returns a list of available rooms
   def rooms
     room_list = Hash.new
@@ -20,13 +20,13 @@ Legs.start do
   def join(room_name)
     unless @rooms.keys.include?(room_name)
       @rooms[room_name.to_s] = @rooms[room_name]
-      server.broadcast :room_created, room_name
+      broadcast :room_created, room_name
     end
     
 #     room = room_object(room_name)
 #     
 #     unless room['users'].include?(caller)
-#       broadcast_to room, 'user_joined', room_name, user_object(caller)
+#       broadcast room['users'], 'user_joined', room_name, user_object(caller)
 #       room['users'].push(caller)
 #     end
     
@@ -37,28 +37,29 @@ Legs.start do
   def leave(room_name)
     room = @rooms[room_name.to_s]
     room['users'].delete(caller)
-    broadcast_to room, 'user_left', room_name, user_object(caller)
+    broadcast room['users'], 'user_left', room_name, user_object(caller)
     true
   end
   
   # sets the room topic message
-  def set_topic(room, message)
-    @rooms[room.to_s]['topic'] = message.to_s
-    broadcast_to room, 'room_changed', room_object(room, :remote, :name, :topic)
+  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 set_name(name)
+  def name=(name)
     caller.meta[:name] = name.to_s
     user_rooms(caller).each do |room_name|
-      broadcast_to room_name, 'user_changed', user_object(caller)
+      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 get_user(object_id = nil)
-    user = user_object( object_id.nil? ? caller : users.select { |u| u.object_id == object_id.to_i }.first )
+  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
@@ -68,7 +69,7 @@ Legs.start do
     room = room_object(room_name)
     room['messages'].push(msg = {'user' =&gt; user_object(caller), 'time' =&gt; Time.now.to_i, 'message' =&gt; message.to_s} )
     trim_messages room
-    broadcast_to room, 'message', room_name.to_s, msg
+    broadcast room['users'], 'message', room_name.to_s, msg
     return msg
   end
   
@@ -82,15 +83,6 @@ Legs.start do
     end
   end
   
-  # sends a notification to members of a room
-  def broadcast_to room, *args
-    room = @rooms[room.to_s] if room.is_a? String
-    room['users'].each do |user|
-      user.notify! *args
-    end
-    return true
-  end
-  
   # makes a user object suitable for sending back with meta info and stuff
   def user_object user
     object = {'id' =&gt; user.object_id}</diff>
      <filename>examples/chat-server.rb</filename>
    </modified>
    <modified>
      <diff>@@ -13,11 +13,20 @@ class Legs
   def initialize(host = 'localhost', port = 30274)
     self.class.start(port) if self.class != Legs &amp;&amp; !self.class.started?
     ObjectSpace.define_finalizer(self) { self.close! }
-    @socket = TCPSocket.new(host, port) and @parent = false if host.instance_of?(String)
-    @socket = host and @parent = port if host.instance_of?(TCPSocket)
-    @responses = Hash.new; @meta = {}; @closed = false
+    @parent = false; @responses = Hash.new; @meta = {}; @closed = false
     @responses_mutex = Mutex.new; @socket_mutex = Mutex.new
     
+    if host.instance_of?(TCPSocket)
+      @socket = host
+      @parent = port unless port.instance_of?(Numeric)
+    elsif host.instance_of?(String)
+      @socket = TCPSocket.new(host, port)
+      self.class.outgoing_mutex.synchronize { self.class.outgoing.push self }
+    else
+      raise &quot;First argument needs to be a hostname, ip, or socket&quot;
+    end
+    
+    
     @handle_data = Proc.new do |data|
       data = self.__json_restore(JSON.parse(data))
       
@@ -59,14 +68,18 @@ class Legs
   def close!
     @closed = true
     puts &quot;User #{self.inspect} disconnecting&quot; if self.class.log?
-    @parent.event(:disconnect, self) if @parent
     
     # notify the remote side
     notify!('**remote__disconnecting**') rescue nil
     
-    @parent.users_mutex.synchronize { @parent.users.delete(self) } if @parent
+    if @parent
+      @parent.event(:disconnect, self)
+      @parent.incomming_mutex.synchronize { @parent.incomming.delete(self) }
+    else
+      self.class.outgoing_mutex.synchronize { self.class.outgoing.delete(self) }
+    end
     
-    @socket.close rescue nil
+    Thread.new { sleep(1); @socket.close rescue nil }
   end
   
   # send a notification to this user
@@ -203,13 +216,14 @@ end
 # the server is started by subclassing Legs, then SubclassName.start
 class &lt;&lt; Legs
   attr_accessor :terminator, :log
-  attr_reader :users, :server_object, :users_mutex, :messages_mutex
+  attr_reader :incomming, :outgoing, :server_object, :incomming_mutex, :outgoing_mutex, :messages_mutex
   alias_method :log?, :log
+  alias_method :users, :incomming
   
   def initializer
     ObjectSpace.define_finalizer(self) { self.stop! }
-    @users = []; @messages = Queue.new; @terminator = &quot;\n&quot;; @log = true
-    @users_mutex = Mutex.new
+    @incomming = []; @outgoing = []; @messages = Queue.new; @terminator = &quot;\n&quot;; @log = true
+    @incomming_mutex = Mutex.new; @outgoing_mutex = Mutex.new
   end
   
   
@@ -222,7 +236,38 @@ class &lt;&lt; Legs
     
     # make the fake class
     @server_class = Class.new
-    @server_class.module_eval { private; attr_reader :server, :caller; public }
+    @server_class.module_eval do
+      private
+      attr_reader :server, :caller
+      
+      # sends a notification message to all connected clients
+      def broadcast *args
+        if args.first.is_a?(Array)
+          arr = args.shift; method = args.shift
+        elsif args.first.is_a?(String) or args.first.is_a?(Symbol)
+          arr = server.incomming; method = args.shift
+        else
+          raise &quot;You need to specify a 'method' to broadcast out to&quot;
+        end
+        
+        server.incomming.each { |user| user.notify!(method, *args) }
+      end
+      
+      # Finds a user by the value of a certain property... like find_user_by :object_id, 12345
+      def find_user_by_object_id value
+        server.incomming.find { |user| user.__object_id == value }
+      end
+      
+      # finds user's with the specified meta keys matching the specified values, can use regexps and stuff, like a case block
+      def find_users_by_meta hash = nil
+        raise &quot;You need to give find_users_by_meta a hash to check the user's meta hash against&quot; if hash.nil?
+        server.incomming.select do |user|
+          hash.all? { |key, value| value === user.meta[key] }
+        end
+      end
+      
+      public # makes it public again for the user code
+    end
     @server_class.module_eval(&amp;blk)
     @server_object = @server_class.allocate
     @server_object.instance_variable_set(:@server, self)
@@ -246,7 +291,7 @@ class &lt;&lt; Legs
           
           result = nil
           
-          @users_mutex.synchronize do
+          @incomming_mutex.synchronize do
             if methods.include?(method.to_s)
               result = @server_object.__send__(method.to_s, *params)
             else
@@ -271,8 +316,8 @@ class &lt;&lt; Legs
       @acceptor_thread = Thread.new do
         while started?
           user = Legs.new(@listener.accept, self)
-          @users_mutex.synchronize { @users.push user }
-          puts &quot;User #{user.object_id} connected, number of users: #{@users.length}&quot; if log?
+          @incomming_mutex.synchronize { @incomming.push user }
+          puts &quot;User #{user.object_id} connected, number of users: #{@incomming.length}&quot; if log?
           self.event :connect, user
         end
       end
@@ -282,34 +327,12 @@ class &lt;&lt; Legs
   # stops the server, disconnects the clients
   def stop
     @started = false
-    @users.each { |user| user.close! }
-  end
-  
-  # sends a notification message to all connected clients
-  def broadcast(method, *args)
-    @users.each { |user| user.notify!(method, *args) }
-  end
-  
-  # Finds a user by the value of a certain property... like find_user_by :object_id, 12345
-  def find_user_by property, value
-    @users.find { |user| user.__send(property) == value }
+    @incomming.each { |user| user.close! }
   end
   
-  def find_users_by property, *values
-    @users.select { |user| user.__send(property) == value }
-  end
-  
-  # gives you an array of all the instances of Legs which are still connected
-  # direction can be :both, :in, or :out
-  def connections direction = :both
-    return @users if direction == :in
-    list = Array.new
-    ObjectSpace.each_object(self) do |leg|
-      next if list.include?(leg) unless leg.connected?
-      next unless leg.parent == false if direction == :out
-      list.push leg
-    end
-    return list
+  # returns an array of all connections
+  def connections
+    @incomming + @outgoing
   end
   
   # add an event call to the server's message queue
@@ -333,6 +356,15 @@ class &lt;&lt; Legs
     blk[client]
     client.close!
   end
+  
+  # hooks up these methods so you can use them off the main object too!
+  [:broadcast, :find_user_by_object_id, :find_users_by_meta].each do |name|
+    define_method name do |*args|
+      @incomming_mutex.synchronize do
+        @server_object.__send__(name, *args)
+      end
+    end
+  end
 end
 
 Legs.initializer</diff>
      <filename>lib/legs.rb</filename>
    </modified>
    <modified>
      <diff>@@ -96,13 +96,10 @@ m = i.marshal
 puts m.a == 1 &amp;&amp; m.b == 2 &amp;&amp; m.c == 3 ?'Success':'Failure'
 
 puts &quot;Testing Legs.connections&quot;
-puts (Legs.connections(:out) == i and Legs.connections.length == 2 and Legs.connections(:in) == Legs.users.first) ?'Success':'Failure'
-puts &quot;:in =&gt; #{Legs.connections(:in).map{ |l| l.inspect }}&quot;
-puts &quot;:out =&gt; #{Legs.connections(:out).map{ |l| l.inspect }}&quot;
-puts &quot;:both =&gt; #{Legs.connections.map{ |l| l.inspect }}&quot;
+puts (Legs.outgoing.first == i and Legs.connections.length == 2 and Legs.incomming.length == 1) ?'Success':'Failure'
 
-puts &quot;All: &quot;
-ObjectSpace.each_object(Legs) { |l| puts &quot;  #{l.inspect}&quot; }
+puts &quot;Testing the synced wrapping to the find_by... and broadcast methods in the server object&quot;
+puts (Legs.find_user_by_object_id(Legs.incomming.first.__object_id) == Legs.incomming.first) ?'Success':'Failure'
 
 puts
 puts &quot;Done&quot;</diff>
      <filename>test/tester.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>12afd10b94ea6b48810fb640aa1e9f0fea9688b5</id>
    </parent>
  </parents>
  <author>
    <name>Jenna Fox</name>
    <email>blueberry@creativepony.com</email>
  </author>
  <url>http://github.com/Bluebie/legs/commit/e51248e6b356957cac5f52b8fb2b6c4714aacb11</url>
  <id>e51248e6b356957cac5f52b8fb2b6c4714aacb11</id>
  <committed-date>2008-07-14T05:48:29-07:00</committed-date>
  <authored-date>2008-07-14T05:48:29-07:00</authored-date>
  <message>This gets the 'Legs.connections' method working, which returns an array of all the outgoing and incomming legs instances, deprecates Legs.users in favour of Legs.incomming, and if you just want an array of outgoing legs, there's now Legs.outgoing too. This is working correctly as far as I can tell, which means everything about legs is working correctly as far as I know.</message>
  <tree>47c93874112dca8b621204e0e810d6c2a2390740</tree>
  <committer>
    <name>Jenna Fox</name>
    <email>blueberry@creativepony.com</email>
  </committer>
</commit>
