/* 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 <net6/host.hpp>
#include "local_document_info.hpp"
#include "server_document_info.hpp"
namespace obby
{
template<typename Document, typename Selector>
class basic_host_buffer;
/** Information about a document that is provided without being subscribed to
* a document.
*/
template<typename Document, typename Selector>
class basic_host_document_info:
virtual public basic_local_document_info<Document, Selector>,
virtual public basic_server_document_info<Document, Selector>
{
public:
typedef basic_document_info<Document, Selector> base_type;
typedef basic_local_document_info<Document, Selector> base_local_type;
typedef basic_server_document_info<Document, Selector> base_server_type;
typedef typename base_server_type::document_type document_type;
typedef basic_host_buffer<Document, Selector> 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<typename Document, typename Selector>
basic_host_document_info<Document, Selector>::
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<typename Document, typename Selector>
basic_host_document_info<Document, Selector>::
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<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::
insert(position pos,
const std::string& text)
{
const user* self = &get_buffer().get_self();
base_server_type::insert_impl(pos, text, self);
}
template<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::
erase(position pos,
position len)
{
base_server_type::erase_impl(pos, len, &get_buffer().get_self() );
}
template<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::
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<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::subscribe()
{
const user& self = get_buffer().get_self();
user_subscribe(self);
if(base_type::m_net != NULL)
base_server_type::broadcast_subscription(self);
}
template<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::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 Document, typename Selector>
typename basic_host_document_info<Document, Selector>::subscription_state
basic_host_document_info<Document, Selector>::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<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::
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<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::
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<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::obby_session_close()
{
session_close_impl();
basic_server_document_info<Document, Selector>::session_close_impl();
basic_document_info<Document, Selector>::session_close_impl();
}
template<typename Document, typename Selector>
void basic_host_document_info<Document, Selector>::session_close_impl()
{
}
template<typename Document, typename Selector>
const typename basic_host_document_info<Document, Selector>::buffer_type&
basic_host_document_info<Document, Selector>::get_buffer() const
{
return dynamic_cast<const buffer_type&>(base_type::get_buffer());
}
template<typename Document, typename Selector>
typename basic_host_document_info<Document, Selector>::net_type&
basic_host_document_info<Document, Selector>::get_net6()
{
return dynamic_cast<net_type&>(base_type::get_net6());
}
template<typename Document, typename Selector>
const typename basic_host_document_info<Document, Selector>::net_type&
basic_host_document_info<Document, Selector>::get_net6() const
{
return dynamic_cast<const net_type&>(base_type::get_net6());
}
} // namespace obby
#endif // _OBBY_HOST_DOCUMENT_INFO_HPP_
syntax highlighted by Code2HTML, v. 0.9.1