source: OGRE/trunk/ogrenew/OgreMain/src/OgreOverlayManager.cpp @ 692

Revision 692, 21.9 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26
27#include "OgreOverlayManager.h"
28#include "OgreStringVector.h"
29#include "OgreOverlayContainer.h"
30#include "OgreStringConverter.h"
31#include "OgreLogManager.h"
32#include "OgreSceneManagerEnumerator.h"
33#include "OgreSceneManager.h"
34#include "OgreSceneNode.h"
35#include "OgreEntity.h"
36#include "OgreException.h"
37#include "OgreViewport.h"
38#include "OgreOverlayElementFactory.h"
39
40namespace Ogre {
41
42    //---------------------------------------------------------------------
43    template<> OverlayManager *Singleton<OverlayManager>::ms_Singleton = 0;
44    OverlayManager* OverlayManager::getSingletonPtr(void)
45    {
46        return ms_Singleton;
47    }
48    OverlayManager& OverlayManager::getSingleton(void)
49    { 
50        assert( ms_Singleton );  return ( *ms_Singleton ); 
51    }
52    //---------------------------------------------------------------------
53    OverlayManager::OverlayManager()
54      : mLastViewportWidth(0),
55        mLastViewportHeight(0),
56        mViewportDimensionsChanged(false)
57    {
58
59        // Scripting is supported by this manager
60        mScriptPatterns.push_back("*.overlay");
61                ResourceGroupManager::getSingleton()._registerScriptLoader(this);
62
63    }
64    //---------------------------------------------------------------------
65    OverlayManager::~OverlayManager()
66    {
67                destroyAllOverlayElements(false);
68                destroyAllOverlayElements(true);
69        destroyAll();
70
71        // Unregister with resource group manager
72                ResourceGroupManager::getSingleton()._unregisterScriptLoader(this);
73    }
74    //---------------------------------------------------------------------
75    const StringVector& OverlayManager::getScriptPatterns(void) const
76    {
77        return mScriptPatterns;
78    }
79    //---------------------------------------------------------------------
80    Real OverlayManager::getLoadingOrder(void) const
81    {
82        // Load late
83        return 1100.0f;
84    }
85    //---------------------------------------------------------------------
86    Overlay* OverlayManager::create(const String& name)
87    {
88        Overlay* ret = 0;
89        OverlayMap::iterator i = mOverlayMap.find(name);
90
91        if (i == mOverlayMap.end())
92        {
93            ret = new Overlay(name);
94            assert(ret && "Overlay creation failed");
95            mOverlayMap[name] = ret;
96        }
97        else
98        {
99            OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM,
100                "Overlay with name '" + name + "' already exists!",
101                "OverlayManager::create");
102        }
103
104        return ret;
105
106    }
107    //---------------------------------------------------------------------
108    Overlay* OverlayManager::getByName(const String& name)
109    {
110        OverlayMap::iterator i = mOverlayMap.find(name);
111        if (i == mOverlayMap.end())
112        {
113            return 0;
114        }
115        else
116        {
117            return i->second;
118        }
119
120    }
121    //---------------------------------------------------------------------
122    void OverlayManager::destroy(const String& name)
123    {
124        OverlayMap::iterator i = mOverlayMap.find(name);
125        if (i == mOverlayMap.end())
126        {
127            OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
128                "Overlay with name '" + name + "' not found.",
129                "OverlayManager::destroy");
130        }
131        else
132        {
133            delete i->second;
134            mOverlayMap.erase(i);
135        }
136    }
137    //---------------------------------------------------------------------
138    void OverlayManager::destroy(Overlay* overlay)
139    {
140        for (OverlayMap::iterator i = mOverlayMap.begin();
141            i != mOverlayMap.end(); ++i)
142        {
143            if (i->second == overlay)
144            {
145                delete i->second;
146                mOverlayMap.erase(i);
147                return;
148            }
149        }
150
151        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
152            "Overlay not found.",
153            "OverlayManager::destroy");
154    }
155    //---------------------------------------------------------------------
156    void OverlayManager::destroyAll(void)
157    {
158        for (OverlayMap::iterator i = mOverlayMap.begin();
159            i != mOverlayMap.end(); ++i)
160        {
161            delete i->second;
162        }
163        mOverlayMap.clear();
164                mLoadedScripts.clear();
165    }
166    //---------------------------------------------------------------------
167    OverlayManager::OverlayMapIterator OverlayManager::getOverlayIterator(void)
168    {
169        return OverlayMapIterator(mOverlayMap.begin(), mOverlayMap.end());
170    }
171    //---------------------------------------------------------------------
172    void OverlayManager::parseScript(DataStreamPtr& stream, const String& groupName)
173    {
174                // check if we've seen this script before (can happen if included
175                // multiple times)
176                if (!stream->getName().empty() &&
177                        mLoadedScripts.find(stream->getName()) != mLoadedScripts.end())
178                {
179                        LogManager::getSingleton().logMessage(
180                                "Skipping loading overlay include: '"
181                                + stream->getName() + " as it is already loaded.");
182                        return;
183                }
184            String line;
185            Overlay* pOverlay = 0;
186                bool skipLine;
187
188            while(!stream->eof())
189            {
190                        bool isTemplate = false;
191                        skipLine = false;
192                    line = stream->getLine();
193                    // Ignore comments & blanks
194                    if (!(line.length() == 0 || line.substr(0,2) == "//"))
195                    {
196                                if (line.substr(0,8) == "#include")
197                                {
198                    std::vector<String> params = StringUtil::split(line, "\t\n ()<>");
199                    DataStreamPtr includeStream =
200                        ResourceGroupManager::getSingleton().openResource(
201                            params[1], groupName);
202                                        parseScript(includeStream, groupName);
203                                        continue;
204                                }
205                            if (!pOverlay)
206                            {
207                                    // No current overlay
208
209                                        // check to see if there is a template
210                                        if (line.substr(0,8) == "template")
211                                        {
212                                                isTemplate = true;
213
214                                        }
215                                        else
216                                        {
217                       
218                                                // So first valid data should be overlay name
219                                                pOverlay = create(line);
220                                                pOverlay->_notifyOrigin(stream->getName());
221                                                // Skip to and over next {
222                                                skipToNextOpenBrace(stream);
223                                                skipLine = true;
224                                        }
225                            }
226                            if ((pOverlay && !skipLine) || isTemplate)
227                            {
228                                    // Already in overlay
229                    std::vector<String> params = StringUtil::split(line, "\t\n ()");
230
231
232                                        uint skipParam = 0;
233                                    if (line == "}")
234                                    {
235                                            // Finished overlay
236                                            pOverlay = 0;
237                                                isTemplate = false;
238                                    }
239                                    else if (parseChildren(stream,line, pOverlay, isTemplate, NULL))
240                                               
241                                    {
242
243                                    }
244                                    else
245                                    {
246                                            // Attribute
247                                                if (!isTemplate)
248                                                {
249                                                        parseAttrib(line, pOverlay);
250                                                }
251                                    }
252
253                            }
254
255                    }
256
257
258            }
259
260                // record as parsed
261                mLoadedScripts.insert(stream->getName());
262
263    }
264    //---------------------------------------------------------------------
265    void OverlayManager::_queueOverlaysForRendering(Camera* cam,
266        RenderQueue* pQueue, Viewport* vp)
267    {
268        // Flag for update pixel-based GUIElements if viewport has changed dimensions
269        if (mLastViewportWidth != vp->getActualWidth() ||
270            mLastViewportHeight != vp->getActualHeight())
271        {
272            mViewportDimensionsChanged = true;
273            mLastViewportWidth = vp->getActualWidth();
274            mLastViewportHeight = vp->getActualHeight();
275
276        }
277        else
278        {
279            mViewportDimensionsChanged = false;
280        }
281
282        OverlayMap::iterator i, iend;
283        iend = mOverlayMap.end();
284        for (i = mOverlayMap.begin(); i != iend; ++i)
285        {
286            Overlay* o = i->second;
287            o->_findVisibleObjects(cam, pQueue);
288        }
289    }
290    //---------------------------------------------------------------------
291    void OverlayManager::parseNewElement( DataStreamPtr& stream, String& elemType, String& elemName,
292            bool isContainer, Overlay* pOverlay, bool isTemplate, String templateName, OverlayContainer* container)
293    {
294        String line;
295
296                OverlayElement* newElement = NULL;
297                newElement =
298                                OverlayManager::getSingleton().createOverlayElementFromTemplate(templateName, elemType, elemName, isTemplate);
299
300                        // do not add a template to an overlay
301
302                // add new element to parent
303                if (container)
304                {
305                        // Attach to container
306                        container->addChild(newElement);
307                }
308                // do not add a template to the overlay. For templates overlay = 0
309                else if (pOverlay)     
310                {
311                        pOverlay->add2D((OverlayContainer*)newElement);
312                }
313
314        while(!stream->eof())
315        {
316            line = stream->getLine();
317            // Ignore comments & blanks
318            if (!(line.length() == 0 || line.substr(0,2) == "//"))
319            {
320                if (line == "}")
321                {
322                    // Finished element
323                    break;
324                }
325                else
326                {
327                    if (isContainer && parseChildren(stream,line, pOverlay, isTemplate, static_cast<OverlayContainer*>(newElement)))
328                    {
329                                            // nested children... don't reparse it
330                    }
331                    else
332                    {
333                        // Attribute
334                        parseElementAttrib(line, pOverlay, newElement);
335                    }
336                }
337            }
338        }
339    }
340
341    //---------------------------------------------------------------------
342    bool OverlayManager::parseChildren( DataStreamPtr& stream, const String& line,
343            Overlay* pOverlay, bool isTemplate, OverlayContainer* parent)
344        {
345                bool ret = false;
346                std::vector<String> params;
347                uint skipParam =0;
348                params = StringUtil::split(line, "\t\n ()");
349
350                if (isTemplate)
351                {
352                        if (params[0] == "template")
353                        {
354                                skipParam++;            // the first param = 'template' on a new child element
355                        }
356                }
357                                               
358                // top level component cannot be an element, it must be a container unless it is a template
359                if (params[0+skipParam] == "container" || (params[0+skipParam] == "element" && (isTemplate || parent != NULL)) )
360                {
361                        String templateName = "";
362                        ret = true;
363                        // nested container/element
364                        if (params.size() > 3+skipParam)
365                        {
366                                if (params.size() != 5+skipParam)
367                                {
368                                        LogManager::getSingleton().logMessage(
369                                                "Bad element/container line: '"
370                                                + line + "' in " + parent->getTypeName()+ " " + parent->getName() +
371                                                ", expecting ':' templateName");
372                                        skipToNextCloseBrace(stream);
373                                        // barf
374                                        return ret;
375                                }
376                                if (params[3+skipParam] != ":")
377                                {
378                                        LogManager::getSingleton().logMessage(
379                                                "Bad element/container line: '"
380                                                + line + "' in " + parent->getTypeName()+ " " + parent->getName() +
381                                                ", expecting ':' for element inheritance");
382                                        skipToNextCloseBrace(stream);
383                                        // barf
384                                        return ret;
385                                }
386
387                                templateName = params[4+skipParam];
388                        }
389
390                        else if (params.size() != 3+skipParam)
391                        {
392                                LogManager::getSingleton().logMessage(
393                                        "Bad element/container line: '"
394                                                + line + "' in " + parent->getTypeName()+ " " + parent->getName() +
395                                        ", expecting 'element type(name)'");
396                                skipToNextCloseBrace(stream);
397                                // barf
398                                return ret;
399                        }
400       
401                        skipToNextOpenBrace(stream);
402                        parseNewElement(stream, params[1+skipParam], params[2+skipParam], true, pOverlay, isTemplate, templateName, (OverlayContainer*)parent);
403
404                }
405
406
407                return ret;
408        }
409
410    //---------------------------------------------------------------------
411    void OverlayManager::parseAttrib( const String& line, Overlay* pOverlay)
412    {
413        std::vector<String> vecparams;
414
415        // Split params on first space
416        vecparams = StringUtil::split(line, "\t ", 1);
417
418        // Look up first param (command setting)
419                StringUtil::toLowerCase(vecparams[0]);
420        if (vecparams[0] == "zorder")
421        {
422            pOverlay->setZOrder(StringConverter::parseUnsignedInt(vecparams[1]));
423        }
424        else
425        {
426            LogManager::getSingleton().logMessage("Bad overlay attribute line: '"
427                + line + "' for overlay " + pOverlay->getName());
428        }
429    }
430    //---------------------------------------------------------------------
431    void OverlayManager::parseElementAttrib( const String& line, Overlay* pOverlay, OverlayElement* pElement )
432    {
433        std::vector<String> vecparams;
434
435        // Split params on first space
436        vecparams = StringUtil::split(line, "\t ", 1);
437
438        // Look up first param (command setting)
439                StringUtil::toLowerCase(vecparams[0]);
440        if (!pElement->setParameter(vecparams[0], vecparams[1]))
441        {
442            // BAD command. BAD!
443            LogManager::getSingleton().logMessage("Bad element attribute line: '"
444                + line + "' for element " + pElement->getName() + " in overlay " +
445                (!pOverlay ? "" : pOverlay->getName().c_str() ));
446        }
447    }
448    //-----------------------------------------------------------------------
449    void OverlayManager::skipToNextCloseBrace(DataStreamPtr& stream)
450    {
451        String line = "";
452        while (!stream->eof() && line != "}")
453        {
454            line = stream->getLine();
455        }
456
457    }
458    //-----------------------------------------------------------------------
459    void OverlayManager::skipToNextOpenBrace(DataStreamPtr& stream)
460    {
461        String line = "";
462        while (!stream->eof() && line != "{")
463        {
464            line = stream->getLine();
465        }
466
467    }
468    //---------------------------------------------------------------------
469    bool OverlayManager::hasViewportChanged(void) const
470    {
471        return mViewportDimensionsChanged;
472    }
473    //---------------------------------------------------------------------
474    int OverlayManager::getViewportHeight(void) const
475    {
476        return mLastViewportHeight;
477    }
478    //---------------------------------------------------------------------
479    int OverlayManager::getViewportWidth(void) const
480    {
481        return mLastViewportWidth;
482    }
483    //---------------------------------------------------------------------
484    Real OverlayManager::getViewportAspectRatio(void) const
485    {
486        return (Real)mLastViewportHeight / (Real)mLastViewportWidth;
487    }
488    //---------------------------------------------------------------------
489        //---------------------------------------------------------------------
490        OverlayManager::ElementMap& OverlayManager::getElementMap(bool isTemplate)
491        {
492                return (isTemplate)?mTemplates:mInstances;
493        }
494
495        //---------------------------------------------------------------------
496        OverlayElement* OverlayManager::createOverlayElementFromTemplate(const String& templateName, const String& typeName, const String& instanceName, bool isTemplate)
497        {
498
499                OverlayElement* newObj  = NULL;
500
501                if (templateName == "")
502                {
503                        newObj = createOverlayElement(typeName, instanceName, isTemplate);
504                }
505                else
506                {
507                        // no template
508                        OverlayElement* templateGui = getOverlayElement(templateName, true);
509
510                        String typeNameToCreate;
511                        if (typeName == "")
512                        {
513                                typeNameToCreate = templateGui->getTypeName();
514                        }
515                        else
516                        {
517                                typeNameToCreate = typeName;
518                        }
519
520                        newObj = createOverlayElement(typeNameToCreate, instanceName, isTemplate);
521
522                        ((OverlayContainer*)newObj)->copyFromTemplate(templateGui);
523                }
524
525                return newObj;
526        }
527
528
529        //---------------------------------------------------------------------
530        OverlayElement* OverlayManager::cloneOverlayElementFromTemplate(const String& templateName, const String& instanceName)
531        {
532                OverlayElement* templateGui = getOverlayElement(templateName, true);
533                return templateGui->clone(instanceName);
534        }
535
536        //---------------------------------------------------------------------
537        OverlayElement* OverlayManager::createOverlayElement(const String& typeName, const String& instanceName, bool isTemplate)
538        {
539                return createOverlayElementImpl(typeName, instanceName, getElementMap(isTemplate));
540        }
541
542        //---------------------------------------------------------------------
543        OverlayElement* OverlayManager::createOverlayElementImpl(const String& typeName, const String& instanceName, ElementMap& elementMap)
544        {
545                // Check not duplicated
546                ElementMap::iterator ii = elementMap.find(instanceName);
547                if (ii != elementMap.end())
548                {
549                        OGRE_EXCEPT(Exception::ERR_DUPLICATE_ITEM, "OverlayElement with name " + instanceName +
550                                " already exists.", "OverlayManager::createOverlayElement" );
551                }
552                OverlayElement* newElem = createOverlayElementFromFactory(typeName, instanceName);
553
554                // Register
555                elementMap.insert(ElementMap::value_type(instanceName, newElem));
556
557                return newElem;
558
559
560        }
561
562        //---------------------------------------------------------------------
563        OverlayElement* OverlayManager::createOverlayElementFromFactory(const String& typeName, const String& instanceName)
564        {
565                // Look up factory
566                FactoryMap::iterator fi = mFactories.find(typeName);
567                if (fi == mFactories.end())
568                {
569                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element type " + typeName,
570                                "OverlayManager::createOverlayElement");
571                }
572
573                // create
574                return fi->second->createOverlayElement(instanceName);
575        }
576
577        //---------------------------------------------------------------------
578        OverlayElement* OverlayManager::getOverlayElement(const String& name, bool isTemplate)
579        {
580                return getOverlayElementImpl(name, getElementMap(isTemplate));
581        }
582        //---------------------------------------------------------------------
583        OverlayElement* OverlayManager::getOverlayElementImpl(const String& name, ElementMap& elementMap)
584        {
585                // Locate instance
586                ElementMap::iterator ii = elementMap.find(name);
587                if (ii == elementMap.end())
588                {
589                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "OverlayElement with name " + name +
590                                " not found.", "OverlayManager::getOverlayElementImpl" );
591                }
592
593                return ii->second;
594        }
595        //---------------------------------------------------------------------
596        void OverlayManager::destroyOverlayElement(const String& instanceName, bool isTemplate)
597        {
598                destroyOverlayElementImpl(instanceName, getElementMap(isTemplate));
599        }
600
601        //---------------------------------------------------------------------
602        void OverlayManager::destroyOverlayElement(OverlayElement* pInstance, bool isTemplate)
603        {
604                destroyOverlayElementImpl(pInstance->getName(), getElementMap(isTemplate));
605        }
606
607        //---------------------------------------------------------------------
608        void OverlayManager::destroyOverlayElementImpl(const String& instanceName, ElementMap& elementMap)
609        {
610                // Locate instance
611                ElementMap::iterator ii = elementMap.find(instanceName);
612                if (ii == elementMap.end())
613                {
614                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "OverlayElement with name " + instanceName +
615                                " not found.", "OverlayManager::destroyOverlayElement" );
616                }
617                // Look up factory
618                const String& typeName = ii->second->getTypeName();
619                FactoryMap::iterator fi = mFactories.find(typeName);
620                if (fi == mFactories.end())
621                {
622                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element type " + typeName,
623                                "OverlayManager::destroyOverlayElement");
624                }
625
626                fi->second->destroyOverlayElement(ii->second);
627                elementMap.erase(ii);
628        }
629        //---------------------------------------------------------------------
630        void OverlayManager::destroyAllOverlayElements(bool isTemplate)
631        {
632                destroyAllOverlayElementsImpl(getElementMap(isTemplate));
633        }
634        //---------------------------------------------------------------------
635        void OverlayManager::destroyAllOverlayElementsImpl(ElementMap& elementMap)
636        {
637                ElementMap::iterator i;
638
639                while ((i = elementMap.begin()) != elementMap.end())
640                {
641                        OverlayElement* element = i->second;
642
643                        // Get factory to delete
644                        FactoryMap::iterator fi = mFactories.find(element->getTypeName());
645                        if (fi == mFactories.end())
646                        {
647                                OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, "Cannot locate factory for element "
648                                        + element->getName(),
649                                        "OverlayManager::destroyAllOverlayElements");
650                        }
651
652                        // remove from parent, if any
653                        OverlayContainer* parent;
654                        if ((parent = element->getParent()) != 0)
655                        {
656                                parent->_removeChild(element->getName());
657                        }
658
659                        // children of containers will be auto-removed when container is destroyed.
660                        // destroy the element and remove it from the list
661                        fi->second->destroyOverlayElement(element);
662                        elementMap.erase(i);
663                }
664        }
665        //---------------------------------------------------------------------
666        void OverlayManager::addOverlayElementFactory(OverlayElementFactory* elemFactory)
667        {
668                // Add / replace
669                mFactories[elemFactory->getTypeName()] = elemFactory;
670
671                LogManager::getSingleton().logMessage("OverlayElementFactory for type " + elemFactory->getTypeName()
672                        + " registered.");
673        }
674}
675
Note: See TracBrowser for help on using the repository browser.