1 #ifndef ERIS_ROOM_H
2 #define ERIS_ROOM_H
3 
4 #include <Eris/Router.h>
5 
6 #include <sigc++/trackable.h>
7 #include <sigc++/signal.h>
8 
9 #include <vector>
10 #include <map>
11 #include <string>
12 
13 namespace Eris
14 {
15 
16 // forward decls
17 class Person;
18 class Lobby;
19 
20 /** The out-of-game (OOG) heirarchy is composed of Rooms, containing Persons and other
21 Rooms. Generally rooms corespond to chanels in IRC, and the interface and commands should
22 be clear if you are familiar with that medium.
23 */
24 class Room : public sigc::trackable, public Router
25 {
26 public:
27     virtual ~Room();
28 
29     /// Send a piece of text to this room
30     void say(const std::string &tk);
31 
32     /** Send an emote ( /me ) to the room. This is transmitted as an IMAGINARY op
33     in Atlas, with args[0]["id"] = "emote". */
34     void emote(const std::string &em);
35 
36     /** Leave the room - no more signals will be emitted for this room again
37     (validity of Room pointer after this call?) */
38     void leave();
39 
40     /** create a child room of this one, with the specified name. Note that most attributes,
41     <em>including the ID</em> will not be valid until the new room emits the 'Entered' signal.
42     If you need a unique, referenceable indentifier earlier than that point, use the pointer
43     value. */
44     Room* createRoom(const std::string &name);
45 
46     /// Obtain the human-readable name  of this room
getName()47     std::string getName() const
48     {
49         return m_name;
50     }
51 
getTopic()52     std::string getTopic() const
53     {
54         return m_topic;
55     }
56 
57     /// obtain an array of pointers to everyone in this room
58     std::vector<Person*> getPeople() const;
59 
60     /// Obtain a list of rooms within this room
getRooms()61     std::vector<Room*> getRooms() const
62     {
63         return m_subrooms;
64     }
65 
66     /** Get the Atlas object ID of the Room; note that this may return an
67     empty value if called prior to entering the Lobby */
getId()68     std::string getId() const
69     {
70         return m_roomId;
71     }
72 
73     Person* getPersonByUID(const std::string& uid);
74 
75 // signals
76     /** Emitted when entry into the room (after a Join) is complete, i.e the user list has been
77     transferred and resolved. */
78     sigc::signal<void, Room*> Entered;
79 
80     /** The primary talk callback. The arguments are the source room, the person
81     talking, and the message itself */
82     sigc::signal<void, Room*, Person*, const std::string&> Speech;
83 
84     /** Emote (/me) callback. The arguments are identical to those for Talk above */
85     sigc::signal<void, Room*, Person*, const std::string&> Emote;
86 
87     /** Emitted when a person enters the room; argument is the account ID. Note that
88     Appearance is not generated for the local player when entering/leaving; use the
89     Entered signal instead. */
90     sigc::signal<void, Room*, Person*> Appearance;
91 
92     /// Similarly, emitted when the specifed person leaves the room
93     sigc::signal<void, Room*, Person*> Disappearance;
94 
95 
96 protected:
97     friend class Lobby;
98 
99     typedef std::map<std::string, Person*> IdPersonMap;
100 
101     /** standard constructor. Issues a LOOK against the specified ID, and sets up
102     the necessary signals to drive the Room if id arg is provided */
103     explicit Room(Lobby *l, const std::string& id);
104 
105     virtual RouterResult handleOperation(const Atlas::Objects::Operation::RootOperation& op);
106     void handleSoundTalk(Person* p, const std::string& speech);
107     void handleEmote(Person* p, const std::string& desc);
108 
109 
110     std::string m_roomId;
111 private:
112     /// helper to see if all the people in the room are valid, and if so, do entry
113     void checkEntry();
114 
115     void sight(const Atlas::Objects::Entity::RootEntity &room);
116 
117     void appearance(const std::string& personId);
118     void disappearance(const std::string& personId);
119 
120     // callback slot when Lobby recives SIGHT(person)
121     void notifyPersonSight(Person *p);
122 
123     std::string m_name;
124     std::string m_topic;
125     bool m_entered;     ///< set once we enter the room, i.e have info on all the members
126     Lobby* m_lobby;
127 
128     IdPersonMap m_members;
129 
130     std::vector<Room*> m_subrooms;
131 };
132 
133 }
134 
135 #endif
136