/// @file factory.hh /// @author Stefan Schmitt /// @version 1.0 /// @date 2003-07 /// /// Declares Factory and Updater classes. #ifndef FACTORY_HH #define FACTORY_HH #include "base/base.hh" #include "base/templates.hh" namespace EyeMind { class Updater; // forward declaration /// Manufacturing and book-keeping of objects. /// Objects can be created using the () operator. The Factory class /// keeps book of all created objects and destroys them in the destructor, i.e /// all objects live as long as their Factory object. The object are destroyed /// in reverse order as they have been created. template class Factory : public Updatable { private: /// Linked list type. struct LList { T* entity; LList* next; }; LList* instances; ///< Pointer to last element in linked list. Updater* updater; ///< Pointer to assigned Updater object. NO_COPYING(Factory); ///< Prevent copying. public: /// Default constructor; initializes data members. Factory(); /// Constructor; registers new Factory with Updater u. Factory(Updater& u); /// Destructor; destroys all objects created using () and unregister /// with updater. virtual ~Factory(); /// Tells all created object to update (if applicable). virtual bool Update(); /// Returns a reference to a newly created instance of T. T& operator()(void); }; template Factory::Factory() { instances = NULL; updater = NULL; } template Factory::Factory(Updater& u) : Factory() { updater = &u; u.Register(*this); } template Factory::~Factory() { if (updater) updater->Unregister(*this); LList *i,*in; // iterate through linked list, destroying list elements and // created objects. i=instances; while (i) { in=i->next; delete i->entity; delete i; i=in; }; } template bool Factory::Update() { if (!instances) return false; // check if the Factory products can be updated if (!dynamic_cast(instances->entity)) return false; LList* i = instances; while (i) { // This cast is 100% safe because the legality of this cast // was tested some lines above. reinterpret_cast(i->entity)->Update(); i=i->next; }; return true; } template T& Factory::operator()(void) { // create new instance T* temp=new T; // create new list item LList* first=new LList; // prepend new list item first->entity=temp; first->next=instances; instances=first; return *temp; } /// Provides a container/handle for Updatable objects. All objects that are /// registered with the Updater are updated when Updater::Update() is called. class Updater : public Updatable { private: LinkedList instances; ///< Updatable objects list. NO_COPYING(Updater); ///< Prevent copying. public: /// Default constructor. Updater(){} /// Updates all registered objects; returns always \c true. virtual bool Update(); /// Registers a new object to be updated by Updater. void Register(Updatable& u); /// Unregisters an object that should not updated anymore by Updater. void Unregister(Updatable& u); }; }; // namespace EyeMind #endif // FACTORY_HH