/* libobby - Network text editing library * Copyright (C) 2005, 2006 0x539 dev group * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _OBBY_HOST_DOCUMENT_INFO_HPP_ #define _OBBY_HOST_DOCUMENT_INFO_HPP_ #include #include "local_document_info.hpp" #include "server_document_info.hpp" namespace obby { template class basic_host_buffer; /** Information about a document that is provided without being subscribed to * a document. */ template class basic_host_document_info: virtual public basic_local_document_info, virtual public basic_server_document_info { public: typedef basic_document_info base_type; typedef basic_local_document_info base_local_type; typedef basic_server_document_info base_server_type; typedef typename base_server_type::document_type document_type; typedef basic_host_buffer buffer_type; typedef typename buffer_type::net_type net_type; typedef typename base_local_type::subscription_state subscription_state; basic_host_document_info(const buffer_type& buffer, net_type& net, const user* owner, unsigned int id, const std::string& title, const std::string& encoding, const std::string& content); basic_host_document_info(const buffer_type& buffer, net_type& net, const serialise::object& obj); /** Inserts the given text at the given position into the document. */ virtual void insert(position pos, const std::string& text); /** Erases the given range from the document. */ virtual void erase(position pos, position len); /** Renames the current document. */ virtual void rename(const std::string& new_title); /** Sends a subscribe request for the local user. If the subscribe * request succeeded, the subscribe_event will be emitted. */ virtual void subscribe(); /** Unsubscribes the local user from this document. signal_unsubscribe * will be emitted if the request has been accepted. */ virtual void unsubscribe(); /** @brief Returns the state of the local user's subscription to * this document. */ virtual subscription_state get_subscription_state() const; /** @brief Called when the session has been closed. */ virtual void obby_session_close(); protected: /** Internally subscribes a user to this document. */ virtual void user_subscribe(const user& user); /** Internally unsubscribes a user from this document. */ virtual void user_unsubscribe(const user& user); /** @brief Implementation of the session close callback that does * not call the base function. */ virtual void session_close_impl(); public: /** Returns the buffer to which this document_info belongs. */ const buffer_type& get_buffer() const; protected: /** Returns the underlaying net6 object. */ net_type& get_net6(); /** Returns the underlaying net6 object. */ const net_type& get_net6() const; }; template basic_host_document_info:: basic_host_document_info(const buffer_type& buffer, net_type& net, const user* owner, unsigned int id, const std::string& title, const std::string& encoding, const std::string& content): base_type(buffer, net, owner, id, title, encoding), base_local_type(buffer, net, owner, id, title, encoding), base_server_type(buffer, net, owner, id, title, encoding, content) { // Server adds owner automagically to jupiter algo. If the local user // is the owner, it does not need to be added to jupiter. // TODO: Find a better solution here, maybe another server_document_info // ctor if(&buffer.get_self() == owner) base_server_type::m_jupiter->client_remove(*owner); } template basic_host_document_info:: basic_host_document_info(const buffer_type& buffer, net_type& net, const serialise::object& obj): base_type(buffer, net, obj), base_local_type(buffer, net, obj), base_server_type(buffer, net, obj) { } template void basic_host_document_info:: insert(position pos, const std::string& text) { const user* self = &get_buffer().get_self(); base_server_type::insert_impl(pos, text, self); } template void basic_host_document_info:: erase(position pos, position len) { base_server_type::erase_impl(pos, len, &get_buffer().get_self() ); } template void basic_host_document_info:: rename(const std::string& new_title) { base_server_type::rename_impl(new_title, &get_buffer().get_self() ); } // TODO: Overload (un)subscribe_user to map to these functions here to // prevent host from sending stuff to itself template void basic_host_document_info::subscribe() { const user& self = get_buffer().get_self(); user_subscribe(self); if(base_type::m_net != NULL) base_server_type::broadcast_subscription(self); } template void basic_host_document_info::unsubscribe() { const user& self = get_buffer().get_self(); user_unsubscribe(self); if(base_type::m_net != NULL) base_server_type::broadcast_unsubscription(self); } template typename basic_host_document_info::subscription_state basic_host_document_info::get_subscription_state() const { // SUBSCRIBING and UNSUBSCRIBING do not exist in our case if(base_local_type::is_subscribed() ) return base_local_type::SUBSCRIBED; else return base_local_type::UNSUBSCRIBED; } template void basic_host_document_info:: user_subscribe(const user& user) { // TODO: Clean this up by a function like add_client_to_jupiter / // remove_client_from_jupiter that the host may overload to prevent // from adding the local client to jupiter // Do not call server function because it will add the client to // jupiter in any case. base_type::user_subscribe(user); // Add client to jupiter if it is not the local client if(base_server_type::m_jupiter.get() != NULL && &user != &get_buffer().get_self() ) { base_server_type::m_jupiter->client_add(user); } } template void basic_host_document_info:: user_unsubscribe(const user& user) { // Remove client from jupiter if is is not the local client if(base_server_type::m_jupiter.get() != NULL && &user != &get_buffer().get_self() ) { base_server_type::m_jupiter->client_remove(user); } // Call base function base_type::user_unsubscribe(user); } template void basic_host_document_info::obby_session_close() { session_close_impl(); basic_server_document_info::session_close_impl(); basic_document_info::session_close_impl(); } template void basic_host_document_info::session_close_impl() { } template const typename basic_host_document_info::buffer_type& basic_host_document_info::get_buffer() const { return dynamic_cast(base_type::get_buffer()); } template typename basic_host_document_info::net_type& basic_host_document_info::get_net6() { return dynamic_cast(base_type::get_net6()); } template const typename basic_host_document_info::net_type& basic_host_document_info::get_net6() const { return dynamic_cast(base_type::get_net6()); } } // namespace obby #endif // _OBBY_HOST_DOCUMENT_INFO_HPP_