Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CEGUIWindowManager.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIWindowManager.cpp
00003         created:        21/2/2004
00004         author:         Paul D Turner
00005         
00006         purpose:        Implements the WindowManager class
00007 *************************************************************************/
00008 /*************************************************************************
00009     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Lesser General Public
00014     License as published by the Free Software Foundation; either
00015     version 2.1 of the License, or (at your option) any later version.
00016 
00017     This library is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020     Lesser General Public License for more details.
00021 
00022     You should have received a copy of the GNU Lesser General Public
00023     License along with this library; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 *************************************************************************/
00026 #include "CEGUIWindowManager.h"
00027 #include "CEGUIWindowFactoryManager.h"
00028 #include "CEGUIWindowFactory.h"
00029 #include "CEGUIWindow.h"
00030 #include "CEGUIExceptions.h"
00031 #include "CEGUIGUILayout_xmlHandler.h"
00032 #include "CEGUIXMLParser.h"
00033 #include <iostream>
00034 #include <sstream>
00035 
00036 // Start of CEGUI namespace section
00037 namespace CEGUI
00038 {
00039 /*************************************************************************
00040         Static Data Definitions
00041 *************************************************************************/
00042 // singleton instance pointer
00043 template<> WindowManager* Singleton<WindowManager>::ms_Singleton        = NULL;
00044 
00045 
00046 /*************************************************************************
00047         Definition of constant data for WindowManager
00048 *************************************************************************/
00049 // Declared in WindowManager
00050 const char      WindowManager::GUILayoutSchemaName[]    = "GUILayout.xsd";
00051 const String WindowManager::GeneratedWindowNameBase("__cewin_uid_");
00052 
00053 
00054 /*************************************************************************
00055     Constructor
00056 *************************************************************************/
00057 WindowManager::WindowManager(void) :
00058     d_uid_counter(0)
00059 {
00060     Logger::getSingleton().logEvent((utf8*)"CEGUI::WindowManager singleton created");
00061 }
00062 
00063 
00064 /*************************************************************************
00065         Destructor
00066 *************************************************************************/
00067 WindowManager::~WindowManager(void)
00068 {
00069         destroyAllWindows();
00070     cleanDeadPool();
00071 
00072         Logger::getSingleton().logEvent((utf8*)"CEGUI::WindowManager singleton destroyed");
00073 }
00074 
00075 
00076 /*************************************************************************
00077         Create a new window of the specified type
00078 *************************************************************************/
00079 Window* WindowManager::createWindow(const String& type, const String& name)
00080 {
00081     String finalName(name.empty() ? generateUniqueWindowName() : name);
00082 
00083         if (isWindowPresent(finalName))
00084         {
00085                 throw AlreadyExistsException("WindowManager::createWindow - A Window object with the name '" + finalName +"' already exists within the system.");
00086         }
00087 
00088     WindowFactoryManager& wfMgr = WindowFactoryManager::getSingleton();
00089     WindowFactory* factory = wfMgr.getFactory(type);
00090 
00091     Window* newWindow = factory->createWindow(finalName);
00092     Logger::getSingleton().logEvent("Window '" + finalName +"' of type '" + type + "' has been created.", Informative);
00093 
00094     // see if we need to assign a look to this window
00095     if (wfMgr.isFalagardMappedType(type))
00096     {
00097         // this was a mapped type, so assign a look to the window so it can finalise
00098         // its initialisation
00099         newWindow->setLookNFeel(type, wfMgr.getMappedLookForType(type));
00100     }
00101 
00102     // perform initialisation step
00103     newWindow->initialise();
00104 
00105         d_windowRegistry[finalName] = newWindow;
00106 
00107         return newWindow;
00108 }
00109 
00110 
00111 /*************************************************************************
00112         Destroy the given window by pointer
00113 *************************************************************************/
00114 void WindowManager::destroyWindow(Window* window)
00115 {
00116         if (window != NULL)
00117         {
00118                 // this is done because the name is used for the log after the window is destroyed,
00119                 // if we just did getName() we would get a const ref to the Window's internal name
00120                 // string which is destroyed along with the window so wouldn't exist when the log tried
00121                 // to use it (as I soon discovered).
00122                 String name = window->getName();
00123 
00124                 destroyWindow(name);
00125         }
00126 
00127 }
00128 
00129 
00130 /*************************************************************************
00131         Destroy the given window by name
00132 *************************************************************************/
00133 void WindowManager::destroyWindow(const String& window)
00134 {
00135         WindowRegistry::iterator wndpos = d_windowRegistry.find(window);
00136 
00137         if (wndpos != d_windowRegistry.end())
00138         {
00139         Window* wnd = wndpos->second;
00140 
00141         // remove entry from the WindowRegistry.
00142         d_windowRegistry.erase(wndpos);
00143 
00144         // do 'safe' part of cleanup
00145         wnd->destroy();
00146 
00147         // add window to dead pool
00148         d_deathrow.push_back(wnd);
00149 
00150         // notify system object of the window destruction
00151         System::getSingleton().notifyWindowDestroyed(wnd);
00152 
00153                 Logger::getSingleton().logEvent((utf8*)"Window '" + window + "' has been added to dead pool.", Informative);
00154         }
00155 
00156 }
00157 
00158 
00159 /*************************************************************************
00160         Return a pointer to the named window
00161 *************************************************************************/
00162 Window* WindowManager::getWindow(const String& name) const
00163 {
00164         WindowRegistry::const_iterator pos = d_windowRegistry.find(name);
00165 
00166         if (pos == d_windowRegistry.end())
00167         {
00168                 throw UnknownObjectException("WindowManager::getWindow - A Window object with the name '" + name +"' does not exist within the system");
00169         }
00170 
00171         return pos->second;
00172 }
00173 
00174 
00175 /*************************************************************************
00176         Return true if a window with the given name is present
00177 *************************************************************************/
00178 bool WindowManager::isWindowPresent(const String& name) const
00179 {
00180         return (d_windowRegistry.find(name) != d_windowRegistry.end());
00181 }
00182 
00183 
00184 /*************************************************************************
00185         Destroy all Window objects
00186 *************************************************************************/
00187 void WindowManager::destroyAllWindows(void)
00188 {
00189         String window_name;
00190         while (!d_windowRegistry.empty())
00191         {
00192                 window_name = d_windowRegistry.begin()->first;
00193                 destroyWindow(window_name);
00194         }
00195 
00196 }
00197 
00198 
00199 /*************************************************************************
00200         Creates a set of windows (a Gui layout) from the information in the
00201         specified XML file.     
00202 *************************************************************************/
00203 Window* WindowManager::loadWindowLayout(const String& filename, const String& name_prefix, const String& resourceGroup, PropertyCallback* callback, void* userdata)
00204 {
00205         if (filename.empty() || (filename == (utf8*)""))
00206         {
00207                 throw InvalidRequestException((utf8*)"WindowManager::loadWindowLayout - Filename supplied for gui-layout loading must be valid.");
00208         }
00209 
00210         // log the fact we are about to load a layout
00211         Logger::getSingleton().logEvent((utf8*)"---- Beginning loading of GUI layout from '" + filename + "' ----", Informative);
00212 
00213     // create handler object
00214     GUILayout_xmlHandler handler(name_prefix, callback, userdata);
00215 
00216         // do parse (which uses handler to create actual data)
00217         try
00218         {
00219         System::getSingleton().getXMLParser()->parseXMLFile(handler, filename, GUILayoutSchemaName, resourceGroup);
00220         }
00221         catch(...)
00222         {
00223         Logger::getSingleton().logEvent("WindowManager::loadWindowLayout - loading of layout from file '" + filename +"' failed.", Errors);
00224         throw;
00225         }
00226 
00227     // log the completion of loading
00228     Logger::getSingleton().logEvent((utf8*)"---- Successfully completed loading of GUI layout from '" + filename + "' ----", Standard);
00229 
00230         return handler.getLayoutRootWindow();
00231 }
00232 
00233 
00234 WindowManager& WindowManager::getSingleton(void)
00235 {
00236         return Singleton<WindowManager>::getSingleton();
00237 }
00238 
00239 
00240 WindowManager* WindowManager::getSingletonPtr(void)
00241 {
00242         return Singleton<WindowManager>::getSingletonPtr();
00243 }
00244 
00245 bool WindowManager::isDeadPoolEmpty(void) const
00246 {
00247     return d_deathrow.empty();
00248 }
00249 
00250 void WindowManager::cleanDeadPool(void)
00251 {
00252     WindowVector::reverse_iterator curr = d_deathrow.rbegin();
00253     for (; curr != d_deathrow.rend(); ++curr)
00254     {
00255 // in debug mode, log what gets cleaned from the dead pool (insane level)
00256 #if defined(DEBUG) || defined (_DEBUG)
00257         CEGUI_LOGINSANE("Window '" + (*curr)->getName() + "' about to be finally destroyed from dead pool.");
00258 #endif
00259 
00260         WindowFactory* factory = WindowFactoryManager::getSingleton().getFactory((*curr)->getType());
00261         factory->destroyWindow(*curr);
00262     }
00263     
00264     // all done here, so clear all pointers from dead pool
00265     d_deathrow.clear();
00266 }
00267 
00268 void WindowManager::writeWindowLayoutToStream(const Window& window, OutStream& out_stream, bool writeParent) const
00269 {
00270     // output xml header
00271     out_stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
00272     // output GUILayout start element
00273     out_stream << "<GUILayout";
00274     // see if we need the parent attribute to be written
00275     if ((window.getParent() != 0) && writeParent)
00276     {
00277         out_stream << " Parent=\"" << window.getParent()->getName() << "\" ";
00278     }
00279     // close opening tag
00280     out_stream << ">" << std::endl;
00281     // write windows
00282     window.writeXMLToStream(out_stream);
00283     // write closing GUILayout element
00284     out_stream << "</GUILayout>" << std::endl;
00285 }
00286 
00287 void WindowManager::writeWindowLayoutToStream(const String& window, OutStream& out_stream, bool writeParent) const
00288 {
00289     writeWindowLayoutToStream(*getWindow(window), out_stream, writeParent);
00290 }
00291 
00292 String WindowManager::generateUniqueWindowName()
00293 {
00294     // build name
00295     std::ostringstream uidname;
00296     uidname << GeneratedWindowNameBase.c_str() << d_uid_counter;
00297 
00298     // update counter for next time
00299     unsigned long old_uid = d_uid_counter;
00300     ++d_uid_counter;
00301 
00302     // log if we ever wrap-around (which should be pretty unlikely)
00303     if (d_uid_counter < old_uid)
00304         Logger::getSingleton().logEvent("UID counter for generated window names has wrapped around - the fun shall now commence!");
00305 
00306     // return generated name as a CEGUI::String.
00307     return String(uidname.str());
00308 }
00309 
00310 
00311 /*************************************************************************
00312         Return a WindowManager::WindowIterator object to iterate over the
00313         currently defined Windows.
00314 *************************************************************************/
00315 WindowManager::WindowIterator WindowManager::getIterator(void) const
00316 {
00317         return WindowIterator(d_windowRegistry.begin(), d_windowRegistry.end());
00318 }
00319 } // End of  CEGUI namespace section

Generated on Wed Sep 7 09:56:35 2005 for Crazy Eddies GUI System by  doxygen 1.4.3