// Cyphesis Online RPG Server and AI Engine
// Copyright (C) 2000,2001 Alistair Riddoch
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// $Id: PersistantThingFactory.h,v 1.26 2007-12-07 01:19:16 alriddoch Exp $
#ifndef SERVER_THING_FACTORY_H
#define SERVER_THING_FACTORY_H
#include <Atlas/Message/Element.h>
#include <set>
class Entity;
class ScriptFactory;
class TypeNode;
template <class T>
class Persistor;
/// \brief Interface class for connecting a newly created entity to its
/// persistor
class PersistorBase {
public:
virtual ~PersistorBase() { }
virtual void persist() = 0;
};
/// \brief Class template for connecting a newly created entity to its
/// persistor
template <class T>
class PersistorConnection : public PersistorBase {
private:
T & m_t;
Persistor<T> & m_p;
public:
PersistorConnection(T & t, Persistor<T> & p) : m_t(t), m_p(p) { }
/// Use p to hook up t into the persistance code
void persist();
};
/// \brief Base class for for factories for creating entities
///
/// An Entity consists of an instance of one of a number of C++ classes
/// optionally with a script. Stores information about default attributes,
/// script language and class name.
class FactoryBase {
protected:
FactoryBase();
public:
ScriptFactory * m_scriptFactory;
/// Default attribute values for this class
Atlas::Message::MapType m_classAttributes;
/// Default attribute values for instances of this class, including
/// defaults inherited from parent classes.
Atlas::Message::MapType m_attributes;
/// Factory for class from which the class handled by this factory
/// inherits.
FactoryBase * m_parent;
/// Set of factories for classes which inherit from the class handled
/// by this factory.
std::set<FactoryBase *> m_children;
/// Inheritance type of this class.
TypeNode * m_type;
virtual ~FactoryBase();
/// \brief Create a new Entity and make it persistent.
///
/// @param id a string giving the identifier of the Entity.
/// @param intId an integer giving the identifier of the Entity.
/// @param pb a pointer to the persistor object for the Entity.
virtual Entity * newPersistantThing(const std::string & id, long intId, PersistorBase ** pb) = 0;
/// \brief Add anything required to the entity after it has been created.
virtual int populate(Entity &) = 0;
/// \brief Create a copy of this factory.
virtual FactoryBase * duplicateFactory() = 0;
};
template <class T>
class ThingFactory : public FactoryBase {
protected:
ThingFactory(ThingFactory<T> & o);
public:
ThingFactory();
virtual ~ThingFactory();
virtual T * newPersistantThing(const std::string & id, long intId,
PersistorBase ** p);
virtual int populate(Entity &);
virtual FactoryBase * duplicateFactory();
};
// How do we make sure the peristance hooks are put in place in a typesafe way
// but after all the initial attribute have been set.
/// \brief Class template for factories for creating instances of the give
/// entity class
template <class T>
class PersistantThingFactory : public ThingFactory<T> {
protected:
PersistantThingFactory(PersistantThingFactory<T> & p) : m_p(p.m_p),
m_master(false) { }
public:
Persistor<T> & m_p;
const bool m_master;
PersistantThingFactory() : m_p(* new Persistor<T>()), m_master(true) { }
virtual ~PersistantThingFactory();
virtual T * newPersistantThing(const std::string & id, long intId, PersistorBase ** p);
virtual FactoryBase * duplicateFactory();
};
/// \brief Class template for factories for entity classes which cannot or
/// should not be instanced
template <class T>
class ForbiddenThingFactory : public FactoryBase {
public:
Persistor<T> & m_p;
ForbiddenThingFactory() : m_p(* new Persistor<T>()) { }
virtual ~ForbiddenThingFactory();
virtual T * newPersistantThing(const std::string & id, long intId, PersistorBase ** p);
virtual int populate(Entity &);
virtual FactoryBase * duplicateFactory();
};
#endif // SERVER_THING_FACTORY_H
syntax highlighted by Code2HTML, v. 0.9.1