00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _OBBY_CHAT_HPP_
00020 #define _OBBY_CHAT_HPP_
00021
00022 #include <ctime>
00023 #include <list>
00024 #include <sigc++/signal.h>
00025 #include <sigc++/connection.h>
00026 #include "user.hpp"
00027 #include "user_table.hpp"
00028
00029
00030 namespace obby
00031 {
00032
00035 class chat
00036 {
00037 public:
00040 class message: private net6::non_copyable
00041 {
00042 public:
00043 message(const std::string& text,
00044 std::time_t timestamp);
00045 message(const serialise::object& obj,
00046 const user_table& user_table);
00047 virtual ~message();
00048
00049 virtual void serialise(serialise::object& obj) const;
00050
00051 const std::string& get_text() const;
00052 std::time_t get_timestamp() const;
00053
00054 std::string format_timestamp(const char* format) const;
00055
00056 virtual std::string repr() const = 0;
00057 protected:
00058 std::string m_text;
00059 std::time_t m_timestamp;
00060 };
00061
00064 class user_message: public message
00065 {
00066 public:
00067 user_message(const std::string& text,
00068 std::time_t timestamp,
00069 const user& from);
00070 user_message(const serialise::object& obj,
00071 const user_table& user_table);
00072
00073 virtual void serialise(serialise::object& obj) const;
00074
00075 const user& get_user() const;
00076 virtual std::string repr() const;
00077 protected:
00078 const user& m_user;
00079 };
00080
00083 class emote_message: public user_message
00084 {
00085 public:
00086 emote_message(const std::string& text,
00087 std::time_t timestamp,
00088 const user& from);
00089 emote_message(const serialise::object& obj,
00090 const user_table& user_table);
00091
00092 virtual std::string repr() const;
00093 };
00094
00097 class server_message: public message
00098 {
00099 public:
00100 server_message(const std::string& text,
00101 std::time_t timestamp);
00102 server_message(const serialise::object& obj,
00103 const user_table& user_table);
00104
00105 virtual std::string repr() const;
00106 };
00107
00110 class system_message: public message
00111 {
00112 public:
00113 system_message(const std::string& text,
00114 std::time_t timestamp);
00115 system_message(const serialise::object& obj,
00116 const user_table& user_table);
00117
00118 virtual std::string repr() const;
00119 };
00120
00121 typedef ptr_iterator<
00122 message,
00123 std::list<message*>,
00124 std::list<message*>::const_iterator
00125 > message_iterator;
00126
00127 typedef sigc::signal<void, const message&>
00128 signal_message_type;
00129
00136 template<typename Buffer>
00137 chat(const Buffer& buffer, unsigned int max_messages);
00138
00139 ~chat();
00140
00144 void serialise(serialise::object& obj) const;
00145
00150 void deserialise(const serialise::object& obj,
00151 const user_table& user_table);
00152
00155 void clear();
00156
00159 void add_user_message(const std::string& text,
00160 const user& from);
00161
00164 void add_emote_message(const std::string& text,
00165 const user& from);
00166
00169 void add_server_message(const std::string& text);
00170
00173 message_iterator message_begin() const;
00174
00177 message_iterator message_end() const;
00178
00181 signal_message_type message_event() const;
00182 protected:
00183 void add_message(message* msg);
00184
00185 void on_sync_init(unsigned int);
00186 void on_sync_final();
00187
00188 void on_user_join(const user& user);
00189 void on_user_part(const user& user);
00190
00191 template<typename DocumentInfo>
00192 void on_document_insert(DocumentInfo& document);
00193
00194 template<typename DocumentInfo>
00195 void on_document_remove(DocumentInfo& document);
00196
00197 unsigned int m_max_messages;
00198 std::list<message*> m_messages;
00199
00200 signal_message_type m_signal_message;
00201
00202 sigc::connection m_user_join_conn;
00203 sigc::connection m_user_part_conn;
00204 sigc::connection m_document_insert_conn;
00205 sigc::connection m_document_remove_conn;
00206 };
00207
00208 template<typename Buffer>
00209 chat::chat(const Buffer& buffer, unsigned int max_messages):
00210 m_max_messages(max_messages)
00211 {
00212 typedef typename Buffer::document_info_type document_info_type;
00213
00214 buffer.sync_init_event().connect(
00215 sigc::mem_fun(*this, &chat::on_sync_init) );
00216 buffer.sync_final_event().connect(
00217 sigc::mem_fun(*this, &chat::on_sync_final) );
00218 m_user_join_conn = buffer.user_join_event().connect(
00219 sigc::mem_fun(*this, &chat::on_user_join) );
00220 m_user_part_conn = buffer.user_part_event().connect(
00221 sigc::mem_fun(*this, &chat::on_user_part) );
00222
00223 m_document_insert_conn = buffer.document_insert_event().connect(
00224 sigc::mem_fun(
00225 *this,
00226 &chat::on_document_insert<document_info_type>
00227 )
00228 );
00229
00230 m_document_remove_conn = buffer.document_remove_event().connect(
00231 sigc::mem_fun(
00232 *this,
00233 &chat::on_document_remove<document_info_type>
00234 )
00235 );
00236 }
00237
00238 template<typename DocumentInfo>
00239 void chat::on_document_insert(DocumentInfo& document)
00240 {
00241 const user* user = document.get_owner();
00242 std::string localised_str;
00243
00244
00245 if(user != NULL)
00246 {
00247 obby::format_string str(
00248 _("%0% has created a new document: %1%") );
00249 str << (*user).get_name() << document.get_title();
00250 localised_str = str.str();
00251 }
00252 else
00253 {
00254 obby::format_string str(_("A new document was created: %0%") );
00255 str << document.get_title();
00256 localised_str = str.str();
00257 }
00258
00259 add_message(new system_message(localised_str, std::time(NULL)) );
00260 }
00261
00262 template<typename DocumentInfo>
00263 void chat::on_document_remove(DocumentInfo& document)
00264 {
00265 obby::format_string str(_("Document %0% has been removed"));
00266 str << document.get_title();
00267 add_message(new system_message(str.str(), std::time(NULL)));
00268 }
00269
00270 }
00271
00272 #endif // _OBBY_CHAT_HPP_
00273