/*************************************************************************** * Copyright (C) 2004 - 2005 by Raphael Langerhorst * * raphael-langerhorst@gmx.at * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.* * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * * OTHER DEALINGS IN THE SOFTWARE. * ***************************************************************************/ #ifndef GWECONTROLLERH #define GWECONTROLLERH #include #include namespace GCS { class GElement; class GElementID; class GElementInfluence; class GEnergy; } namespace GWE { //QPtrList (this way we don't need to include // - GweController is a public interface, should not have additional #include dependencies class QPtrListGElement; class GDataController; /** \Interface GweController GweController.h \brief Base class for G World Engine (GWE) controller implementations @author Raphael Langerhorst GweController defines the interface for the GWE controller implementation. The GWEs single purpose is persistent element management and thus has a very slim and effective interface definition. Whether this implementation is a dynamic network distributed hierarchical server structure with database backend or a simple local implementation does not matter. @note Some documentation given here on this class (or interface) depends on the actual implementation that is used; the implementation is "supposed" to do what the documentation of the method says. @todo use exceptions as they provide a better way for failure description.(??) talk about this on the mailing list first!! */ class GweController : public QObject { Q_OBJECT protected: /** * Every GWE Controller needs to have a data controller anyway, * so it is already present in this base class and can be used * be derived controllers. * @note the data controller is passed in the constructor */ GDataController* Data; public: /** * Constructor. * @param data the GDataController used */ GweController(GDataController* data, QObject *parent = 0, const char *name = 0); /** * Virtual destructor to allow clean memory management * with derived classes. */ virtual ~GweController(); // HELPER OBJECTS // /** * @Returns The data controller used. */ virtual GDataController* getDataController(); /** * @Returns The data controller used, read-only. */ virtual const GDataController* getDataController() const; protected: // USEFUL MANAGEMENT ROUTINES // protected slots: /** * Connects the following element signals in a standard way, * data is the GDataController that is used. * - connect(element,SIGNAL(childElementCreated(GCS::GElement*)), * Data,SLOT(add(GCS::GElement*))); * - connect(element,SIGNAL(radiateInfluence(const GCS::GElementInfluence&)), * this,SLOT(radiateInfluence(const GCS::GElementInfluence& ))); * - connect(element,SIGNAL(sendInfluence(const GCS::GElementID&, const GCS::GElementInfluence& )), * this,SLOT(routeInfluence(const GCS::GElementID&, const GCS::GElementInfluence& ))); * - connect(element,SIGNAL(formChanged(const GCS::GForm& )), * this,SLOT(handleReparenting())); * - connect(element,SIGNAL(energyChanged(const GCS::GEnergy& )), * this,SLOT(removeElementWithNoEnergyLeft(const GCS::GEnergy& ))); */ virtual void connectBasicElementSignals(const GCS::GElementID& id); protected: /** * Uses the data controller to find all elements that are * in the range of the given source element. Elements in * range are simply all elements that touch each other. * * This method is usually used to find all elements that are * affected by an influence. * * If the source element has no form, the form of the parent * element is used as boundary, until a element with a form * is found or traversal count reaches max_depth_parent. * * Normally max_traverse_parents is not set to anything larger than * 1. If it is necessary it most likely because of a bad element design. * Still, it can be useful in some cases. * * @param source The element that defines the range of affected elements. * @param max_traverse_children Sets the maximum element hierarchy traversal * limit in the direction of children; 0 means no children at all, * 1 means all direct children, ... * @param max_traverse_parents Sets the maximum element hierarchy traversal limit * in the direction of parents; 0 means no parents (not even the parent * of the source element!), 1 means including the direct parent; a higher * value than 1 only makes sense if neither the source nor the parent * element have a form attribute. The real maximum of parent traverses is * defined by the minimum of this parameter and the number of traversals to * the first parent with a form and the number of traversals to the root * element. * * @returns List of elements that overlap with their form with the source element. */ virtual QPtrListGElement findInRange(GCS::GElement* source, unsigned max_traverse_children = 0, unsigned max_traverse_parents = 1); public slots: virtual void executeOpenElement(const GCS::GElementID& id); // INFLUENCE MANAGEMENT // /** * Forwards given influence to all elements that are near to the * sender() of this signal. * * @see GElement::radiateInfluence() */ virtual void radiateInfluence(const GCS::GElementInfluence& influence); /** * Routes an influence from an element to given destination. * * @see GElement::routeInfluence() */ virtual void routeInfluence(const GCS::GElementID& destination, const GCS::GElementInfluence& influence); /** * Checks if given element (sender()) leaves it's current * parent or enters a sibling element. * In case any of this applies, reparenting is performed. * * Usually this slot can be connected to the formChanged() signal of * an element. */ virtual void handleReparenting(); /** * Checks if given element (sender()) has an energy amount of 0 * in which case it is deleted. * * Usually this slot can be connected to the energyChanged() signal of * an element. */ virtual void removeElementWithNoEnergyLeft(const GCS::GEnergy& changedEnergy); /** * Shuts down the whole World Engine and does all required * cleanup beforehand. It is highly recommended to call * this slot before shutting down the application. * * At the end the quit signal is emitted. In this * state all cleanup and shutdown is down and the * application can safely quit. * @see quit() */ virtual void shutdown(); signals: /** * Emitted when the GWE Server should shutdown. * @see shutdown() */ void quit(); }; } #endif