From: <kla...@us...> - 2006-03-29 23:39:35
|
Revision: 10155 Author: klaussfreire Date: 2006-03-29 15:38:29 -0800 (Wed, 29 Mar 2006) ViewCVS: http://svn.sourceforge.net/vegastrike/?rev=10155&view=rev Log Message: ----------- Another iteration - plus some stuff for SystemExplorer to be able to take neat screenshots (dynamic lighting stuff). Modified Paths: -------------- branches/ogre_branch/vegastrike/src/UserInterface/Element.cpp branches/ogre_branch/vegastrike/src/UserInterface/Element.h branches/ogre_branch/vegastrike/src/UserInterface/Layer.cpp branches/ogre_branch/vegastrike/src/UserInterface/Layer.h branches/ogre_branch/vegastrike/src/UserInterface/Layout.cpp branches/ogre_branch/vegastrike/src/UserInterface/Layout.h branches/ogre_branch/vegastrike/src/UserInterface/Root.cpp branches/ogre_branch/vegastrike/src/UserInterface/Root.h branches/ogre_branch/vegastrike/src/UserInterface/Target.cpp branches/ogre_branch/vegastrike/src/UserInterface/Target.h branches/ogre_branch/vegastrike/src/UserInterface/Types.h branches/ogre_branch/vegastrike/src/UserInterface/VirtualIterator.h Added Paths: ----------- branches/ogre_branch/vegastrike/src/UserInterface/LayerFactory.h branches/ogre_branch/vegastrike/src/UserInterface/LayerManager.cpp branches/ogre_branch/vegastrike/src/UserInterface/LayerManager.h branches/ogre_branch/vegastrike/src/UserInterface/LayoutManager.cpp branches/ogre_branch/vegastrike/src/UserInterface/LayoutManager.h branches/ogre_branch/vegastrike/src/UserInterface/SimpleLayer.cpp branches/ogre_branch/vegastrike/src/UserInterface/SimpleLayer.h branches/ogre_branch/vegastrike/src/UserInterface/StandardIterable.h branches/ogre_branch/vegastrike/src/UserInterface/TargetManager.cpp branches/ogre_branch/vegastrike/src/UserInterface/TargetManager.h branches/ogre_branch/vegastrike/src/UserInterface/XMLDocument.cpp branches/ogre_branch/vegastrike/src/UserInterface/XMLDocument.h branches/ogre_branch/vegastrike/src/UserInterface/uitime.cpp branches/ogre_branch/vegastrike/src/UserInterface/uitime.h Modified: branches/ogre_branch/vegastrike/src/UserInterface/Element.cpp =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/Element.cpp 2006-03-29 23:22:09 UTC (rev 10154) +++ branches/ogre_branch/vegastrike/src/UserInterface/Element.cpp 2006-03-29 23:38:29 UTC (rev 10155) @@ -16,3 +16,16 @@ for (StringMap::const_iterator it=attrMap.begin(); it!=attrMap.end(); ++it) setAttribute(it->first,it->second); } + +const UserInterface::Element::RenderOptions& UserInterface::Element::getRenderOptions() const +{ + static RenderOptions default_ropts = { + true, //needs setup + true, //needs render + true, //needs cleanup + + false, //multiple render calls + 0 //singleQueueGroupNumber (ignored) + }; + return default_ropts; +} \ No newline at end of file Modified: branches/ogre_branch/vegastrike/src/UserInterface/Element.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/Element.h 2006-03-29 23:22:09 UTC (rev 10154) +++ branches/ogre_branch/vegastrike/src/UserInterface/Element.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -17,6 +17,12 @@ @par All instances should be created from within layers, which will pick the correct subclass. Hence, all interaction should go through the abstract interface. + @par + The rendering loop will call setup, render and cleanup at a specific time (see Layer). + At that time, layers are responsible of relaying that call to its elements, as required. + @par + So, all elements will receive the setup call... then the render call... then the cleanup + call. Have that in mind when organizing your rendering sequence. */ class Element { @@ -44,10 +50,14 @@ since they're not illegal. @note This implies invisibility in the specified target. + @note + It is possible to receive this call on targets that were never initialise()d. + This makes it possible for layers not to keep track of which targets were initialized + for every element, which should simplify implementations quite a bit. Handle it. */ virtual void shutdown(Target* target, Layer* owner) = 0; - /** Set up this element to work with this target + /** Prepare for rendering this element, on the specified target. @remarks The behavior of this function, and of cleanup, should be orthogonal to others... because this is used only to set up rendering state prior @@ -62,7 +72,7 @@ @note Expect this one to be called regularly, with possibly alternating target and zOrder parameters. Standard loop will call, for each target, setup, render, - cleanup. + cleanup, at various times. See class notes. */ virtual void setup(Target* target, Layer* owner, unsigned int zOrder) = 0; @@ -74,8 +84,10 @@ it would be preferrable. If you do not, though, make reasonable effort to respect relative zOrder - if not possible, make sure to document this extremely clearly and prominently. + @see + Layer */ - virtual void render(Target* target, Layer* owner, unsigned int zOrder) = 0; + virtual void render(Target* target, Layer* owner, unsigned int zOrder, int queueGroupNumber) = 0; /** Undo the last setup(). @remarks @@ -96,6 +108,65 @@ /** Send a command to the element - useful abstract string interface */ virtual String sendCommand(const String& cmdName, const StringMap& cmdParams)=0; + + public: + /** Return the element's class name. + @remarks + Very useful, so that layers can identify subclasses and ensure runtime safety + if they ever need to use a special interface (aside from the abstract one). + */ + virtual const ClassName& getClass() const = 0; + + /** Structure used to report specific rendering scheduling to the layer. + @remarks + Enhances the abstract rendering interface, to allow very important speed + optimizations. + @par + Its use is entirely optional - the base implementation will return + generic render options that work for everybody, but it will probably + be suboptimal. + @par + Although layers are not required to honor this information, it is expected + that layers will do so when dealing with unknown element classes. Thus, + it is more a tool for making basic layers easier to implement, allowing + efficient generalized render loop implementations. + @note + You could implement elements that need no special rendering tasks, + like non-visual elements, quite efficiently by specifying + needsSetup, needsRender and needsCleanup all as false. The reference + implementation on SimpleLayer is guaranteed to have its performance + unaffected by such elements at render time. + @see + SimpleLayer + */ + struct RenderOptions + { + /** If false, setup won't be called as part of the rendering loop */ + bool needsSetup; + + /** If false, render won't be called as part of the rendering loop */ + bool needsRender; + + /** If false, cleanup won't be called as part of the rendering loop */ + bool needsCleanup; + + /** If true, only one render call will be issued, + with queueGroupNumber equal to singleQueueGroupNumber + */ + bool usesSingleQueueGroup; + + /** @see usesSingleQueueGroup */ + int singleQueueGroupNumber; + }; + + /** Return render options. + @remarks + Enhances the abstract rendering interface, to allow very important speed + optimizations. + @see + Element::RenderOptions + */ + virtual const RenderOptions& getRenderOptions() const; }; } Modified: branches/ogre_branch/vegastrike/src/UserInterface/Layer.cpp =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/Layer.cpp 2006-03-29 23:22:09 UTC (rev 10154) +++ branches/ogre_branch/vegastrike/src/UserInterface/Layer.cpp 2006-03-29 23:38:29 UTC (rev 10155) @@ -36,24 +36,7 @@ return rv; } -void UserInterface::Layer::loadImpl() -{ - // To-Do -} -void UserInterface::Layer::unloadImpl() -{ - // To-Do -} - -size_t UserInterface::Layer::calculateSize() const -{ - // How would I? - return sizeof(*this); -} - - - void UserInterface::Layer::removeElement(const ElementID &id) { ElementIterator *it = findElement(id); Modified: branches/ogre_branch/vegastrike/src/UserInterface/Layer.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/Layer.h 2006-03-29 23:22:09 UTC (rev 10154) +++ branches/ogre_branch/vegastrike/src/UserInterface/Layer.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -15,15 +15,27 @@ User Interface screens are composed with overlapping layers. A layer always takes up the whole target... but may (and usually will) have transparent areas. - An Element, if it maps visually on the screen, will have a Layer ID and - probably a Layer Element ID. + @par + Layouts will call setup/render/cleanup at specific times in the rendering + loop. + @par + @item setup: before asynchronous target rendering queues are executed. This + allows elements and layouts to set up the respective asynchronous tasks. + @item render: at specific points, between asynchronous tasks. + @item cleanup: final call for the target - besides cleanup, overlay immediates + would be executed here. + @note + Ogre::Resource has a generic string interface as well, accessed through + set/getParameter(). Do not confuse this with set/getAttribute() - attributes + need not be static or persistent. While parameters need not be so either... + it is usually expected in Ogre that they are. */ class Layer : public Resource { public: /** Standard resource constructor @remarks - Creates a resource that will load the XML layer description from an equally + Creates a resource that will load the layer description from an equally named data stream when required. */ Layer(ResourceManager *creator, const String &name, ResourceHandle handle, const String &group, bool isManual=false, ManualResourceLoader *loader=0); @@ -85,12 +97,19 @@ it would be preferrable. If you do not, though, make reasonable effort to respect relative zOrder - if not possible, make sure to document this extremely clearly and prominently. + @par + This function will be called multiple times, each with a different + queueGroupNumber - it is expected that specific asynchronous rendering + tasks be scheduled at diferent queueGroups... when render() is called + with the corresponding queueGroupNumber, all those tasks should have been + executed - this way, you can precisely schedule immediate rendering tasks + between asynchronous ones. @note An example of unorderable layers are Viewport layers, which must rely on the underlying scene management subsystem and thus haven't got the fine control of rendering times to conform to every zOrder combination. */ - virtual void render(Target* target, unsigned int zOrder) = 0; + virtual void render(Target* target, unsigned int zOrder, int queueGroupNumber) = 0; /** Undo the last setup(). @remarks @@ -181,7 +200,14 @@ */ virtual void removeElement(const ElementID &id); - /** Retrieves the supported element classes */ + /** Retrieves the supported element classes + @remarks + You may use wildcards: * to match any number of characters. + Thus... you can use hierarchical classes: + booze/* would match any class name that begins with 'booze/', which could + mean that it supports the 'booze' interface, and thus can be cast up to a + corresponding BoozeElement class. + */ virtual const StringVector& querySupportedElementClasses() const = 0; /** Retrieves the layer's class name @@ -201,19 +227,11 @@ /** Convenience function to set lots of attributes */ void setAttributes(const StringMap& attrMap); + /** Attribute enumeration - will report present or built-in attributes */ + virtual StringVector enumAttributes() const = 0; + /** Send a command to the layer - useful abstract string interface */ virtual String sendCommand(const String& cmdName, const StringMap& cmdParams)=0; - - protected: - /** Internal implementation stuff */ - virtual void loadImpl(); - - /** Internal implementation stuff */ - virtual void unloadImpl(); - - /** Internal implementation stuff */ - virtual size_t calculateSize() const; - }; typedef UISharedPtr<Layer> LayerPtr; Added: branches/ogre_branch/vegastrike/src/UserInterface/LayerFactory.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/LayerFactory.h (rev 0) +++ branches/ogre_branch/vegastrike/src/UserInterface/LayerFactory.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -0,0 +1,31 @@ + +#ifndef __UI_LAYERFACTORY_H__INCLUDED__ +#define __UI_LAYERFACTORY_H__INCLUDED__ + +#include "Types.h" +#include <map> + +namespace UserInterface { + + class Layer; + + /** The responsible of creating layer subclasses. */ + class LayerFactory + { + public: + LayerFactory() {} + virtual ~LayerFactory() {} + + public: + /** Implementation for creation of layer resources + @remarks + Implement this method for creating layer resources. + */ + virtual Layer* create(const ClassName &className, + const Ogre::String &name, Ogre::ResourceHandle handle, const Ogre::String &group, + bool isManual, Ogre::ManualResourceLoader *loader, const Ogre::NameValuePairList *createParams) = 0; + }; + +} + +#endif//__UI_LAYERFACTORY_H__INCLUDED__ Added: branches/ogre_branch/vegastrike/src/UserInterface/LayerManager.cpp =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/LayerManager.cpp (rev 0) +++ branches/ogre_branch/vegastrike/src/UserInterface/LayerManager.cpp 2006-03-29 23:38:29 UTC (rev 10155) @@ -0,0 +1,123 @@ +#include "Root.h" +#include "LayerManager.h" +#include "LayerFactory.h" +#include "Layer.h" +#include "XMLDocument.h" + + +using namespace Ogre; + +template<> UserInterface::LayerManager* Ogre::Singleton<UserInterface::LayerManager>::ms_Singleton = 0; + +namespace UserInterface { + + LayerManager::LayerManager() + { + mResourceType = "GUILayer"; + } + + LayerManager::~LayerManager() + { + } + + bool LayerManager::registerFactory(const ClassName &className, LayerFactory* factory) + { + // This is O(log N + log #C) + // N = number of classes registered + // #C = number of classes sharing the factory instance assigned to this className. + + if (mFactoryMap.insert(std::pair<ClassName,LayerFactory*>(className,factory)).second) { + mFactoryPtrMap[factory].insert(className); + return true; + } else + return false; + } + + void LayerManager::unregisterFactory(const ClassName &className) + { + // This is O(log N + log #C) + // N = number of classes registered + // #C = number of classes sharing the factory instance assigned to this className. + + FactoryMap::iterator it = mFactoryMap.find(className); + + if (it!=mFactoryMap.end()) { + FactoryPtrMap::iterator pit = mFactoryPtrMap.find(it->second); + assert(pit != mFactoryPtrMap.end()); + + pit->second.erase(className); + mFactoryMap.erase(it); + } + } + + void LayerManager::unregisterFactory(LayerFactory* factory) + { + // This is O( (#C+1) * log N ) + // N = number of classes registered + // #C = number of classes sharing the factory instance assigned to this className. + // + // NOTE: It *could* be O( #C + 1 ), but it would be a cumbersome implementation. + // I don't really think it's worth it. At least it's not O(N). + + FactoryPtrMap::iterator it = mFactoryPtrMap.find(factory); + if (it!=mFactoryPtrMap.end()) { + for (std::set<ClassName>::iterator sit=it->second.begin(); sit != it->second.end(); ++sit) + mFactoryMap.erase(*sit); + mFactoryPtrMap.erase(it); + } + } + + LayerFactory* LayerManager::getFactory(const ClassName &className) const + { + FactoryMap::const_iterator it=mFactoryMap.find(className); + if (it!=mFactoryMap.end()) + return it->second; else + return 0; + } + + Resource* LayerManager::createImpl( + const Ogre::String &name, Ogre::ResourceHandle handle, const Ogre::String &group, + bool isManual, Ogre::ManualResourceLoader *loader, const Ogre::NameValuePairList *createParams) + { + String className; + LayerFactory *factory=0; + Ogre::NameValuePairList::const_iterator it; + if (createParams && ((it = createParams->find("className")) != createParams->end())) { + className = it->second; + } else if (!isManual) { + //Figure out the resource path + Ogre::String fname; + if (createParams && ((it = createParams->find("resourcePath")) != createParams->end())) + fname = it->second; else + fname = name; + //Figure out from XML DOCTYPE + DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(fname); + if (stream.isNull()) { + OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND, "No resource named " + fname + " found.", "LayerManager::createImpl"); + } else { + XMLDOM::XMLSerializer xmlparser; + char buf[512]; + size_t count = stream->read(buf,sizeof(buf)); + xmlparser.parse(buf,count); + XMLDOM::XMLDocument *doc = xmlparser.close(); + + // Translate docType into a className. + if (doc->docType.compare(0,9,"GUILayer/")==0) + className = doc->docType.substr(9); + + delete doc; + } + } + + if (className.empty()) { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Layer resource " + name + " does not specify a class name, or is not an layer resource at all.", "LayerManager::createImpl"); + } else if (!(factory=getFactory(className))) { + OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Layer resource " + name + " has an unregistered class name " + className, "LayerManager::createImpl"); + } else { + return factory->create(className,name,handle,group,isManual,loader,createParams); + } + + } + +} + Added: branches/ogre_branch/vegastrike/src/UserInterface/LayerManager.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/LayerManager.h (rev 0) +++ branches/ogre_branch/vegastrike/src/UserInterface/LayerManager.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -0,0 +1,118 @@ + +#ifndef __UI_LAYERMANAGER_H__INCLUDED__ +#define __UI_LAYERMANAGER_H__INCLUDED__ + +#include "Types.h" +#include <map> + +namespace UserInterface { + + class LayerFactory; + + /** The resource manager for Layer resources */ + class LayerManager : public ResourceManager, public UISingleton<LayerManager> + { + public: + LayerManager(); + virtual ~LayerManager(); + + private: + typedef std::map<ClassName,LayerFactory*> FactoryMap; + typedef std::map<LayerFactory*,std::set<ClassName> > FactoryPtrMap; + FactoryMap mFactoryMap; + FactoryPtrMap mFactoryPtrMap; + + public: + /** Register a layer factory with this manager. + @remarks + Layer factories are used to install new layer classes. + @par + Whenever a layer must be instanced, the corresponding factory + will be called to carry out the creation of the corresponding + Layer implementation. + @par + You can only register one factory for a certain className, + but you can specify the same factory instance for multiple + layers (the factory will be provided the className so that + it knows which one it is asked to create). + @par + Returns true if successful, false if otherwise. The only reason + for failure is that the specified className has already been + registered. + @note + Remember to mantain the instances alive until they are unregistered. + And to unregister them. + */ + bool registerFactory(const ClassName &className, LayerFactory* factory); + + /** Deregister a layer factory, by class name. + @rearks + You still have to destroy the factory instance. + */ + void unregisterFactory(const ClassName &className); + + /** Deregister a layer factory, by instance pointer. + @rearks + All class names assigned to that factory will be unregistered. + You still have to destroy the factory instance. + */ + void unregisterFactory(LayerFactory* factory); + + /** Returns the layer factory instance registered to the specified class name. + @remarks + May return NULL if the class name has not been registered. + */ + LayerFactory* getFactory(const ClassName &className) const; + + /** A read-only iterator through registered factories. + @remarks + LayerIterator::value_type is std::pair<ClassName,LayerFactory*>, + with the first being the className, and the second being the + factory associated with it. + */ + typedef FactoryMap::const_iterator FactoryIterator; + + /** An iterator pointing to the first registered factory */ + FactoryIterator factoriesBegin() const { return mFactoryMap.begin(); } + + /** An iterator pointing past the end of the registered factory sequence */ + FactoryIterator factoriesEnd() const { return mFactoryMap.end(); } + + + protected: + /** Implementation for creation of layer resources + @remarks + The creation of layers requires an additional parameter, namely + the class name. That parameter must be passed in the createParams list, + with key name 'className'. + @par + If the className is not specified, the name will be assumed to be + an XML resource which will be parsed in order to retrieve its DOCTYPE. + The DOCTYPE must have the form GUILayer/<className> - if that succeeds, + decoding procedes by loading that resource from the corresponding factory. + If it fails, resource loading as a whole fails. + @par + In any case, loading proceeds by using the registered LayerFactory for + that className. + @par + Although the ultimate responsible for actual loading is the layer + layer implementation, standard behavior is to load from the createParam + 'resourcePath', if it exists, or the resource name if it does not. + @note + Only the first few bytes are inspected to find the DOCTYPE - the number + of which is implementation-dependant. So, it is important to keep the + DOCTYPE tag within reasonable size limits. + @note + The ClassName may not be a string type. But the parameter specified in + the 'className' creation parameter must be. If necessary, a conversion + must be performed - in the usual way (if it were unusual, it would be + specified here). + */ + virtual Resource* createImpl( + const Ogre::String &name, Ogre::ResourceHandle handle, const Ogre::String &group, + bool isManual, Ogre::ManualResourceLoader *loader, const Ogre::NameValuePairList *createParams); + }; + +} + +#endif//__UI_LAYERMANAGER_H__INCLUDED__ Modified: branches/ogre_branch/vegastrike/src/UserInterface/Layout.cpp =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/Layout.cpp 2006-03-29 23:22:09 UTC (rev 10154) +++ branches/ogre_branch/vegastrike/src/UserInterface/Layout.cpp 2006-03-29 23:38:29 UTC (rev 10155) @@ -1,5 +1,6 @@ #include "Root.h" #include "Layout.h" +#include "LayoutManager.h" using namespace UserInterface; @@ -25,17 +26,23 @@ void UserInterface::Layout::show() { // Too simple? - // Target's listener takes care of everything. + // LayoutManager takes care of everything. // It'll rely on Layout reporting its own visibility. - visibility = false; + if (!visibility) { + visibility = true; + LayoutManager::getSingleton()._notifyLayoutVisibilityChange(this); + } } void UserInterface::Layout::hide() { // Too simple? - // Target's listener takes care of everything. + // LayoutManager takes care of everything. // It'll rely on Layout reporting its own visibility. - visibility = true; + if (visibility) { + visibility = false; + LayoutManager::getSingleton()._notifyLayoutVisibilityChange(this); + } } bool UserInterface::Layout::isVisible() const @@ -50,6 +57,7 @@ void UserInterface::Layout::unloadImpl() { + _shutdown(); layers.clear(); targets.clear(); } @@ -101,7 +109,85 @@ return false; } -void UserInterface::Layout::select() +void UserInterface::Layout::_synchronize() { - //To-Do -} \ No newline at end of file + for (LayerMap::iterator it=layers.begin(); it!=layers.end(); ++it) + _synchronizeLayer(it); +} + +void UserInterface::Layout::_shutdown() +{ + for (LayerMap::iterator it=layers.begin(); it!=layers.end(); ++it) + _shutdownLayer(it); +} + +void UserInterface::Layout::_synchronizeLayer(LayerMap::iterator iter) +{ + LayerInfo::TargetNames::iterator tit = iter->second.targets.begin(); + LayerInfo::TargetNames::iterator itit = iter->second.initialisedTargets.begin(); + while (tit != iter->second.targets.end() && itit != iter->second.initialisedTargets.end()) { + if (*tit < *itit) { + iter->second.layer->initialise(targets[*tit].getPointer()); + iter->second.initialisedTargets.insert(itit,*tit); + ++tit; + } else if (*itit < *tit) { + iter->second.layer->shutdown(targets[*tit].getPointer()); + iter->second.initialisedTargets.erase(*(itit++)); + } else { + ++itit; + ++tit; + } + } + while (tit != iter->second.targets.end()) { + iter->second.layer->initialise(targets[*tit].getPointer()); + iter->second.initialisedTargets.insert(*tit); + ++tit; + } + while (itit != iter->second.initialisedTargets.end()) { + iter->second.layer->shutdown(targets[*tit].getPointer()); + iter->second.initialisedTargets.erase(*(itit++)); + } +} + +void UserInterface::Layout::_shutdownLayer(LayerMap::iterator iter) +{ + for (LayerInfo::TargetNames::iterator it=iter->second.initialisedTargets.begin(); it!=iter->second.initialisedTargets.end(); ++it) + iter->second.layer->initialise(targets[*it].getPointer()); + iter->second.initialisedTargets.clear(); +} + +void UserInterface::Layout::_setup(const TargetID &target) +{ + TargetMap::iterator tit = targets.find(target); + if (tit!=targets.end()) { + unsigned int zOrder=0; + for (LayerMap::iterator it=layers.begin(); it!=layers.end(); ++it,++zOrder) { + if (it->second.targets.count(target)>0) + it->second.layer->setup(tit->second.getPointer(),zOrder); + } + } +} + +void UserInterface::Layout::_render(const TargetID &target, int queueGroupNumber) +{ + TargetMap::iterator tit = targets.find(target); + if (tit!=targets.end()) { + unsigned int zOrder=0; + for (LayerMap::iterator it=layers.begin(); it!=layers.end(); ++it,++zOrder) { + if (it->second.targets.count(target)>0) + it->second.layer->render(tit->second.getPointer(),zOrder,queueGroupNumber); + } + } +} + +void UserInterface::Layout::_cleanup(const TargetID &target) +{ + TargetMap::iterator tit = targets.find(target); + if (tit!=targets.end()) { + unsigned int zOrder=0; + for (LayerMap::iterator it=layers.begin(); it!=layers.end(); ++it,++zOrder) { + if (it->second.targets.count(target)>0) + it->second.layer->cleanup(tit->second.getPointer(),zOrder); + } + } +} Modified: branches/ogre_branch/vegastrike/src/UserInterface/Layout.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/Layout.h 2006-03-29 23:22:09 UTC (rev 10154) +++ branches/ogre_branch/vegastrike/src/UserInterface/Layout.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -63,10 +63,27 @@ bool isLayerVisible(const LayerID& layerName, const TargetID& targetName); public: - /** Hide all layers not visible or not belonging to this layout, and show all - visible in this layout. */ - void select(); + /** Low-level stuff - Initialise all uninitialised targets, shutdown all that should be, on all layers. + @remarks: Intended for framework members to call - not you. */ + void _synchronize(); + /** Low-level stuff - Shutdown all initialised targets on all layers. + @remarks: Intended for framework members to call - not you. */ + void _shutdown(); + + /** Low-level stuff - Perform setup phase on all layers. + @remarks: Intended for framework members to call - not you. */ + void _setup(const TargetID &target); + + /** Low-level stuff - Execute post-render queue group immediate rendering phase on all layers. + @remarks: Intended for framework members to call - not you. */ + void _render(const TargetID &target, int queueGroupNumber); + + /** Low-level stuff - Perform per-frame cleanup phase on all layers. + @remarks: Intended for framework members to call - not you. */ + void _cleanup(const TargetID &target); + + protected: typedef std::map<TargetID,TargetPtr> TargetMap; TargetMap targets; @@ -75,6 +92,7 @@ { typedef std::set<TargetID> TargetNames; TargetNames targets; + TargetNames initialisedTargets; LayerPtr layer; }; @@ -90,6 +108,13 @@ /** Internal implementation stuff */ virtual size_t calculateSize() const; + TargetPtr _getTarget(const TargetID &which); + + /** Internal implementation stuff - Initialise all uninitialised targets, shutdown all that should be. */ + void _synchronizeLayer(LayerMap::iterator iter); + + /** Internal implementation stuff - Shutdown all initialised targets */ + void _shutdownLayer(LayerMap::iterator iter); }; } Added: branches/ogre_branch/vegastrike/src/UserInterface/LayoutManager.cpp =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/LayoutManager.cpp (rev 0) +++ branches/ogre_branch/vegastrike/src/UserInterface/LayoutManager.cpp 2006-03-29 23:38:29 UTC (rev 10155) @@ -0,0 +1,73 @@ +#include "Root.h" +#include "LayoutManager.h" +#include "Layout.h" + + +using namespace Ogre; + +template<> UserInterface::LayoutManager* Ogre::Singleton<UserInterface::LayoutManager>::ms_Singleton = 0; + +namespace UserInterface { + + LayoutManager::LayoutManager() + { + mResourceType = "GUILayout"; + } + + LayoutManager::~LayoutManager() + { + } + + Resource* LayoutManager::createImpl( + const Ogre::String &name, Ogre::ResourceHandle handle, const Ogre::String &group, + bool isManual, Ogre::ManualResourceLoader *loader, const Ogre::NameValuePairList *createParams) + { + // no use for createParams here + return new Layout(this, name, handle, group, isManual, loader); + } + + bool LayoutManager::frameStarted(const Ogre::FrameEvent &evt) + { + VisibleLayoutIterator it=visibleBegin(); + while (it!=visibleEnd()) { + Layout* layout = (Layout*)(it->getPointer()); + if (layout) { + if (layout->isVisible()) { + layout->_synchronize(); + ++it; + } else { + layout->_shutdown(); + mVisibleLayouts.erase(it++); + } + } else { + mVisibleLayouts.erase(it++); + } + } + return true; + } + + bool LayoutManager::frameEnded(const Ogre::FrameEvent &evt) + { + return true; + } + + void LayoutManager::_notifyLayoutVisibilityChange(Layout* layout) + { + // Do not delete + if (layout->isVisible()) + mVisibleLayouts.insert(getByHandle(layout->getHandle())); + } + + void LayoutManager::addImpl(ResourcePtr &res) + { + ResourceManager::addImpl(res); + } + + void LayoutManager::removeImpl(ResourcePtr &res) + { + mVisibleLayouts.erase(res); + ResourceManager::removeImpl(res); + } + +} + Added: branches/ogre_branch/vegastrike/src/UserInterface/LayoutManager.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/LayoutManager.h (rev 0) +++ branches/ogre_branch/vegastrike/src/UserInterface/LayoutManager.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -0,0 +1,72 @@ + +#ifndef __UI_LAYERMANAGER_H__INCLUDED__ +#define __UI_LAYERMANAGER_H__INCLUDED__ + +#include "Types.h" +#include <set> +#include <iterator> + +namespace UserInterface { + + class Layout; + + /** The resource manager for Layout resources */ + class LayoutManager : public ResourceManager, public Ogre::FrameListener, public UISingleton<LayoutManager> + { + public: + LayoutManager(); + virtual ~LayoutManager(); + + public: + /** Internal implementation stuff */ + virtual bool frameStarted(const Ogre::FrameEvent &evt); + + /** Internal implementation stuff */ + virtual bool frameEnded(const Ogre::FrameEvent &evt); + + public: + /** Internal implementation stuff + @remarks + Called whenever a layout changes its visibility state, + to allow internal housekeeping (tracking visible layouts). + */ + void _notifyLayoutVisibilityChange(Layout* layout); + + protected: + /** Implementation for creation of layout resources */ + virtual Resource* createImpl( + const Ogre::String &name, Ogre::ResourceHandle handle, const Ogre::String &group, + bool isManual, Ogre::ManualResourceLoader *loader, const Ogre::NameValuePairList *createParams); + + /** Implementation stuff */ + virtual void addImpl(ResourcePtr &res); + + /** Implementation stuff */ + virtual void removeImpl(ResourcePtr &res); + + private: + class ResourcePtrSort { + public: bool operator()(const ResourcePtr &a, const ResourcePtr &b) const + { return a.getPointer()<b.getPointer(); }; + }; + typedef std::set<ResourcePtr,ResourcePtrSort> ResourceSet; + ResourceSet mVisibleLayouts; + + public: + typedef ResourceSet::iterator VisibleLayoutIterator; + + /** An iterator pointing to the first visible layout, that will iterate through visible + layouts only + @remarks + Actually... it's a pessimistic filter - items not in this sequence are guaranteed + to be invisible, but not all of them will be visible. + */ + VisibleLayoutIterator visibleBegin() const { return mVisibleLayouts.begin(); }; + + /** An iterator pointing past the end of the visible layout sequence @see visibleBegin */ + VisibleLayoutIterator visibleEnd() const { return mVisibleLayouts.end(); }; + }; + +} + +#endif//__UI_LAYERMANAGER_H__INCLUDED__ Modified: branches/ogre_branch/vegastrike/src/UserInterface/Root.cpp =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/Root.cpp 2006-03-29 23:22:09 UTC (rev 10154) +++ branches/ogre_branch/vegastrike/src/UserInterface/Root.cpp 2006-03-29 23:38:29 UTC (rev 10155) @@ -20,6 +20,7 @@ settingFlags(0), root(0), sceneManager(0), + mainWindow(0), nodeCacheSize(DEFAULT_NODE_CACHE_SIZE), envMapState(0) { @@ -280,9 +281,9 @@ CopyTextureLoader jointTexLoader; CopyTextureLoader sphericTexLoader; - ResourcePtr separateTex[6]; - ResourcePtr jointTex; - ResourcePtr sphericTex; + TexturePtr separateTex[6]; + TexturePtr jointTex; + TexturePtr sphericTex; void init() { @@ -293,22 +294,22 @@ // Create default textures for (i=0; i<6; ++i) { - separateTex[i] = ResourcePtr(TextureManager::getSingleton().createManual( + separateTex[i] = TextureManager::getSingleton().createManual( separate_cubic_names[i], ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 1, 1, 1, MIP_UNLIMITED, PF_R8G8B8A8, - TU_STATIC_WRITE_ONLY, &separateTexLoader[i]).getPointer()); + TU_STATIC_WRITE_ONLY, &separateTexLoader[i]); } - jointTex = ResourcePtr(TextureManager::getSingleton().createManual( + jointTex = TextureManager::getSingleton().createManual( joint_cubic_name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_CUBE_MAP, 1, 1, 1, MIP_UNLIMITED, PF_R8G8B8A8, - TU_STATIC_WRITE_ONLY, &jointTexLoader).getPointer()); - sphericTex = ResourcePtr(TextureManager::getSingleton().createManual( + TU_STATIC_WRITE_ONLY, &jointTexLoader); + sphericTex = TextureManager::getSingleton().createManual( spheric_name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 1, 1, 1, MIP_UNLIMITED, PF_R8G8B8A8, - TU_STATIC_WRITE_ONLY, &sphericTexLoader).getPointer()); + TU_STATIC_WRITE_ONLY, &sphericTexLoader); } void shutdown() @@ -316,14 +317,13 @@ int i; // Release texture pointers - allow textures to be deleted - for (i=0; i<6; ++i) { + for (i=0; i<6; ++i) if (!separateTex[i].isNull()) - TextureManager::getSingleton().remove(separateTex[i]); - } + TextureManager::getSingleton().remove(separateTex[i]->getName()), separateTex[i].setNull(); if (!jointTex.isNull()) - TextureManager::getSingleton().remove(jointTex); + TextureManager::getSingleton().remove(jointTex->getName()), jointTex.setNull(); if (!sphericTex.isNull()) - TextureManager::getSingleton().remove(sphericTex); + TextureManager::getSingleton().remove(sphericTex->getName()), sphericTex.setNull(); } void rebind(const std::vector<String> &separate, const String &joint, const String &spheric, const String &group) @@ -517,3 +517,8 @@ sceneManager = 0; initialised = false; } + +UserInterface::RenderTarget* UserInterface::Root::getPrimaryRenderTarget() +{ + return mainWindow; +} \ No newline at end of file Modified: branches/ogre_branch/vegastrike/src/UserInterface/Root.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/Root.h 2006-03-29 23:22:09 UTC (rev 10154) +++ branches/ogre_branch/vegastrike/src/UserInterface/Root.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -180,6 +180,9 @@ /** Destroys a nameless billboard set @note detach from scene nodes first */ void destroyBillboardSet(BillboardSet *bill); + public: + RenderTarget* getPrimaryRenderTarget(); + private: unsigned int settingFlags; std::vector<SceneNode*> nodeCache; @@ -187,6 +190,7 @@ protected: Ogre::Root *root; Ogre::SceneManager *sceneManager; + Ogre::RenderWindow *mainWindow; size_t nodeCacheSize; Added: branches/ogre_branch/vegastrike/src/UserInterface/SimpleLayer.cpp =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/SimpleLayer.cpp (rev 0) +++ branches/ogre_branch/vegastrike/src/UserInterface/SimpleLayer.cpp 2006-03-29 23:38:29 UTC (rev 10155) @@ -0,0 +1,217 @@ +#include "Root.h" +#include "SimpleLayer.h" +#include "Element.h" + +#include <assert.h> + +using namespace UserInterface; + + +UserInterface::SimpleLayer::SimpleLayer() +{ +} + +UserInterface::SimpleLayer::SimpleLayer( + ResourceManager *creator, const String &name, + ResourceHandle handle, const String &group, + bool isManual, ManualResourceLoader *loader) : + Layer(creator,name,handle,group,isManual,loader) +{ +} + +UserInterface::SimpleLayer::~SimpleLayer() +{ + //Make sure we've been properly shut down + assert(targetInfo.targets.size() == 0); +} + +void UserInterface::SimpleLayer::ElementInfo::remove(ElementID eid, Element** corpse) +{ + // Find in the master map + ElementMap::iterator it=allByID.find(eid); + if (it!=allByID.end()) { + assert(it->second.getPointer()); + //Get render options... to know which sets need updating + const Element::RenderOptions &ropt = it->second.getPointer()->getRenderOptions(); + //Remove it from all sets. + all.erase(it->second); + if (ropt.needsSetup) + needSetup.erase(it->second); + if (ropt.needsCleanup) + needCleanup.erase(it->second); + if (ropt.needsRender && !ropt.usesSingleQueueGroup) + needFullRender.erase(it->second); + if (ropt.needsRender && ropt.usesSingleQueueGroup) + needSingleRender[ropt.singleQueueGroupNumber].erase(it->second); + //Kill the element + if (!corpse) + delete it->second.getPointer(); else + *corpse = it->second.getPointer(); + //Remove it from the master map + allByID.erase(it); + } +} + +void UserInterface::SimpleLayer::ElementInfo::add(ElementID eid, Element* ptr, unsigned int zOrder) +{ + assert(ptr); + // Construct the ElementHolder, and add it to the master map + ElementHolder holder(ptr,zOrder); + allByID.insert(std::pair<ElementID,ElementHolder>(eid,holder)); + //Get render options... to know which sets need updating + const Element::RenderOptions &ropt = ptr->getRenderOptions(); + //Add to all the required sets + all.insert(holder); + if (ropt.needsSetup) + needSetup.insert(holder); + if (ropt.needsCleanup) + needCleanup.insert(holder); + if (ropt.needsRender && !ropt.usesSingleQueueGroup) + needFullRender.insert(holder); + if (ropt.needsRender && ropt.usesSingleQueueGroup) + needSingleRender[ropt.singleQueueGroupNumber].insert(holder); +} + +void UserInterface::SimpleLayer::ElementInfo::reorder(ElementID eid, unsigned int zOrder) +{ + Element *corpse=0; + remove(eid,&corpse); + if (corpse) + add(eid,corpse,zOrder); +} + +unsigned int UserInterface::SimpleLayer::ElementInfo::maxZOrder() const +{ + ElementSet::const_reverse_iterator last = all.rbegin(); + if (last != all.rend()) + return last->getZOrder(); else + return ~0; +} + +void UserInterface::SimpleLayer::ElementInfo::clear() +{ + all.clear(); + needSetup.clear(); + needCleanup.clear(); + needFullRender.clear(); + needSingleRender.clear(); + + for (ElementMap::iterator it=allByID.begin(); it!=allByID.end(); ++it) + delete it->second.getPointer(); +} + +UserInterface::SimpleLayer::ElementInfo::~ElementInfo() +{ + clear(); +} + +void UserInterface::SimpleLayer::initialise(Target* target) +{ + targetInfo.targets.insert(target); + for (ElementInfo::ElementSet::iterator it=elementInfo.all.begin(); it!=elementInfo.all.end(); ++it) + it->getPointer()->initialise(target,this); +} + +void UserInterface::SimpleLayer::shutdown(Target* target) +{ + for (ElementInfo::ElementSet::iterator it=elementInfo.all.begin(); it!=elementInfo.all.end(); ++it) + it->getPointer()->shutdown(target,this); + targetInfo.targets.erase(target); +} + +void UserInterface::SimpleLayer::setup(Target* target, unsigned int zOrder) +{ + for (ElementInfo::ElementSet::iterator it=elementInfo.needSetup.begin(); it!=elementInfo.needSetup.end(); ++it) + it->getPointer()->setup(target,this,it->getZOrder()); +} + +void UserInterface::SimpleLayer::render(Target* target, unsigned int zOrder, int queueGroupNumber) +{ + { for (ElementInfo::ElementSet::iterator it=elementInfo.needFullRender.begin(); it!=elementInfo.needFullRender.end(); ++it) + it->getPointer()->render(target,this,it->getZOrder(),queueGroupNumber); } + { for (ElementInfo::ElementSet::iterator it=elementInfo.needSingleRender[queueGroupNumber].begin(); it!=elementInfo.needSingleRender[queueGroupNumber].end(); ++it) + it->getPointer()->render(target,this,it->getZOrder(),queueGroupNumber); } +} + +void UserInterface::SimpleLayer::cleanup(Target* target, unsigned int zOrder) +{ + for (ElementInfo::ElementSet::iterator it=elementInfo.needCleanup.begin(); it!=elementInfo.needCleanup.end(); ++it) + it->getPointer()->cleanup(target,this,it->getZOrder()); +} + +Element* UserInterface::SimpleLayer::addElement(const ElementID &id, const ClassName &cls, const StringMap ¶ms) +{ + Element *eptr = createElement(id,cls,params); + if (!eptr) + return 0; + + unsigned int zOrder; + StringMap::const_iterator zOrder_it = params.find("zOrder"); + if (zOrder_it != params.end()) + zOrder = Ogre::StringConverter::parseUnsignedInt(zOrder_it->second); else + zOrder = elementInfo.maxZOrder()+1; + + elementInfo.add(id,eptr,zOrder); + + for (TargetInfo::TargetSet::iterator it=targetInfo.targets.begin(); it!=targetInfo.targets.end(); ++it) + eptr->initialise(*it,this); + + return eptr; +} + +void UserInterface::SimpleLayer::reorderElement(const ElementID &id, unsigned int zOrder) +{ + elementInfo.reorder(id,zOrder); +} + +void UserInterface::SimpleLayer::removeElement(ElementIterator *it) +{ + for (TargetInfo::TargetSet::iterator it2=targetInfo.targets.begin(); it2!=targetInfo.targets.end(); ++it2) + it->get().shutdown(*it2,this); + elementInfo.remove(it->getID()); +} + +void UserInterface::SimpleLayer::setAttribute(const String& attrName, const String& attrValue) +{ + //No attributes, just provide an empty implementation, both in case we want to add + //attributes, and to simplify subclassing without attributes. +} + +String UserInterface::SimpleLayer::getAttribute(const String& attrName) const +{ + //No attributes, just provide an empty implementation, both in case we want to add + //attributes, and to simplify subclassing without attributes. + return String(); +} + +StringVector UserInterface::SimpleLayer::enumAttributes() const +{ + //No attributes, just provide an empty implementation, both in case we want to add + //attributes, and to simplify subclassing without attributes. + return StringVector(); +} + +String UserInterface::SimpleLayer::sendCommand(const String& cmdName, const StringMap& cmdParams) +{ + //No commands, just provide an empty implementation, both in case we want to add + //commands, and to simplify subclassing without them. + return String(); +} + +UserInterface::SimpleLayer::ElementIterator* UserInterface::SimpleLayer::findElement(const ElementID &id) const +{ + ElementInfo::ElementMap::const_iterator base_it = elementInfo.allByID.find(id); + if (base_it == elementInfo.allByID.end()) + return 0; else + return new ElementInfo::ElementIterator(base_it); +} + +const UserInterface::SimpleLayer::ElementIterator& UserInterface::SimpleLayer::elemBegin() const +{ + return elementInfo.getBegin(); +} + +const UserInterface::SimpleLayer::ElementIterator& UserInterface::SimpleLayer::elemEnd() const +{ + return elementInfo.getEnd(); +} Added: branches/ogre_branch/vegastrike/src/UserInterface/SimpleLayer.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/SimpleLayer.h (rev 0) +++ branches/ogre_branch/vegastrike/src/UserInterface/SimpleLayer.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -0,0 +1,203 @@ + +#ifndef __UI_SIMPLELAYER_H__INCLUDED__ +#define __UI_SIMPLELAYER_H__INCLUDED__ + +#include "Layer.h" +#include "StandardIterable.h" + +namespace UserInterface { + + /** A visualization layer - UI elements are always contained within layers + @remarks + User Interface screens are composed with overlapping layers. + A layer always takes up the whole target... but may (and usually will) have + transparent areas. + @par + Layouts will call setup/render/cleanup at specific times in the rendering + loop. + @par + @item setup: before asynchronous target rendering queues are executed. This + allows elements and layouts to set up the respective asynchronous tasks. + @item render: at specific points, between asynchronous tasks. + @item cleanup: final call for the target - besides cleanup, overlay immediates + would be executed here. + @par + SimpleLayer is a partial implementation which provides common functionality. + Among those, are: + @par + @item container: It implements the standard 'container' behavior, in which + elements exist as actual Element instances (notice that not all implementations + are required to behave this way), stored in an associative container + for quick access. + @item optimized render loop: A generic render loop with necessary optimizations. + A generic render loop is difficult to optimize... SimpleLayer does its best + without loosing any generality. Usually, this is enough. + @item arbitrary zOrder: Elements are rendered in the abritrary order specified + by their zOrder. Its assignment is automatic, but it can be overridden at + creation time by specifying 'zOrder' in createParams. There's no generic + interface for element reordering, though. But a less generic interface is + available for that end. + */ + class SimpleLayer : public Layer + { + private: + /** Implementation stuff... why are you reading this? */ + struct ElementInfo + { + + class ElementHolder + { + Element* ptr; + unsigned int zOrder; + + public: + ElementHolder() : ptr(0),zOrder(0) {} + ElementHolder(Element* _ptr, unsigned int _zOrder) : ptr(_ptr),zOrder(_zOrder) {} + ElementHolder(const ElementHolder& other) : ptr(other.ptr), zOrder(other.zOrder) {} + + Element* getPointer() const { return ptr; } + unsigned int getZOrder() const { return zOrder; } + + bool operator<(const ElementHolder& other) const + { return (zOrder<other.zOrder) || ((zOrder==other.zOrder) && (ptr<other.ptr)); } + bool operator==(const ElementHolder& other) const + { return (zOrder==other.zOrder) && (ptr==other.ptr); } + }; + + typedef std::map<ElementID,ElementHolder> ElementMap; + typedef std::set<ElementHolder> ElementSet; + typedef std::map<unsigned int,ElementSet> SingleRenderElementSet; + + class IDFunctor + { + public: + ElementID operator()(const ElementMap::const_iterator &it) const + { return it->first; } + }; + + class DerefFunctor + { + public: + Element& operator()(const ElementMap::const_iterator &it) const + { return *it->second.getPointer(); } + }; + + typedef StandardIterable<Element,ElementID,Element&,Element*,ElementMap::const_iterator,IDFunctor,DerefFunctor > ElementIterator; + mutable ElementIterator beginIterator; + mutable ElementIterator endIterator; + + ElementMap allByID; + ElementSet all; + ElementSet needSetup; + ElementSet needCleanup; + ElementSet needFullRender; + SingleRenderElementSet needSingleRender; + + void clear(); + void remove(ElementID eid, Element** corpse=0); + void add(ElementID eid, Element* ptr, unsigned int zOrder); + void reorder(ElementID eid, unsigned int zOrder); + unsigned int maxZOrder() const; + + ElementIterator& getBegin() const { return (beginIterator = ElementIterator(allByID.begin())); } + ElementIterator& getEnd() const { return (beginIterator = ElementIterator(allByID.end())); } + + ~ElementInfo(); + } elementInfo; + + /** Implementation stuff... why are you reading this? */ + struct TargetInfo + { + typedef std::set<Target*> TargetSet; + TargetSet targets; + } targetInfo; + + public: + /** Standard resource constructor + @remarks + Creates a resource that will load the layer description from an equally + named data stream when required. + */ + SimpleLayer(ResourceManager *creator, const String &name, ResourceHandle handle, const String &group, bool isManual=false, ManualResourceLoader *loader=0); + + virtual ~SimpleLayer(); + + protected: + SimpleLayer(); + + public: + /** @copydoc Layer::initialise */ + virtual void initialise(Target* target); + + /** @copydoc Layer::shutdown */ + virtual void shutdown(Target* target); + + /** @copydoc Layer::setup */ + virtual void setup(Target* target, unsigned int zOrder); + + /** @copydoc Layer::render */ + virtual void render(Target* target, unsigned int zOrder, int queueGroupNumber); + + /** @copydoc Layer::cleanup */ + virtual void cleanup(Target* target, unsigned int zOrder); + + public: + /** @copydoc Layer::findElement */ + virtual ElementIterator* findElement(const ElementID &id) const; + + /** @copydoc Layer::elemBegin */ + virtual const ElementIterator& elemBegin() const; + + /** @copydoc Layer::elemEnd */ + virtual const ElementIterator& elemEnd() const; + + public: + /** Add an element. + @param params May contain a special parameter named 'zOrder' which overrides + the default zOrder used for rendering (the default is such that the specified + element renders last). + @see Layer::addElement + */ + virtual Element* addElement(const ElementID &id, const ClassName &cls, const StringMap ¶ms); + + /** @copydoc Layer::removeElement */ + virtual void removeElement(ElementIterator *it); + + /** Set the element's zOrder. + @remarks + This operation is asymptotically as costly as addElement(). + Which is not much, but not negligible either. + */ + virtual void reorderElement(const ElementID &id, unsigned int zOrder); + + public: + /** @copydoc Layer::setAttribute */ + virtual void setAttribute(const String& attrName, const String& attrValue); + + /** @copydoc Layer::getAttribute */ + virtual String getAttribute(const String& attrName) const; + + /** @copydoc Layer::enumAttributes */ + virtual StringVector enumAttributes() const; + + /** @copydoc Layer::sendCommand */ + virtual String sendCommand(const String& cmdName, const StringMap& cmdParams); + + + protected: + /** Create an element with the specified parameters, and return a pointer to it. + @remarks + To be used by addElement, to provide subclasses a means of "registering" themselves + with the base implementation. + @par + Return NULL if somehow you can't create it... and please do log the reasons for + failure - SimpleLayer won't. + */ + virtual Element* createElement(const ElementID &id, const ClassName &cls, const StringMap ¶ms) = 0; + }; + + typedef UISharedPtr<Layer> LayerPtr; + +} + +#endif//__UI_SIMPLELAYER_H__INCLUDED__ Added: branches/ogre_branch/vegastrike/src/UserInterface/StandardIterable.h =================================================================== --- branches/ogre_branch/vegastrike/src/UserInterface/StandardIterable.h (rev 0) +++ branches/ogre_branch/vegastrike/src/UserInterface/StandardIterable.h 2006-03-29 23:38:29 UTC (rev 10155) @@ -0,0 +1,66 @@ +#ifndef __UI_STANDARDITERABLE_H__INCLUDED__ +#define __UI_STANDARDITERABLE_H__INCLUDED__ + +#include "VirtualIterator.h" + +namespace UserInterface { + + namespace Functors + { + + template<class _IT> class First + { + public: + _IT::value_type::first_type operator()(const _IT& it) const + { return it->first; } + }; + + template<class _IT> class Second + { + public: + _IT::value_type::second_type& operator()(_IT& it) const + { return it->second; } + }; + + template<class _IT> class Deref + { + public: + _IT::reference_type operator()(_IT& it) const + { return *it; } + }; + + } + + template<class _T, class _IDt, class _Rt, class _Pt, class _BaseIT, class _IDFun = FirstFunctor<_BaseIT>, class _DerefFun = SecondFunctor<_BaseIT> > class StandardIterable : public VirtualIterator<_T, _IDt, _Rt, _Pt> + { + typedef _IDFun id_functor_type; + typedef _DerefFun dereference_functor_type; + typedef _BaseIT base_iterator_type; + typedef StandardIterable<_T,_IDt,_Rt,_Pt,_BaseIT,_IDFun,_DerefFun> this_iterator_type; + + id_functor_type id_functor; + dereference_functor_type dereference_functor; + base_iterator_type base_iterator; + + public: + StandardIterable() {} + StandardIterable(const base_iterator_type &base) : base_iterator(base) {} + virtual ~StandardIterable() {} + + virtual reference_type operator*() const { return dereference_functor(base_iterator); }; + virtual pointer_type operator->() const { return &dereference_functor(base_iterator); }; + + virtual iterator_type& operator++() { ++base_iterator; return *this; }; + virtual iterator_type& operator--() {... [truncated message content] |