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

CEGUIScheme.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIScheme.cpp
00003         created:        21/2/2004
00004         author:         Paul D Turner
00005         
00006         purpose:        Implements GUI Scheme 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 "CEGUIScheme.h"
00027 #include "CEGUIExceptions.h"
00028 #include "CEGUISchemeManager.h"
00029 #include "CEGUILogger.h"
00030 #include "CEGUIImagesetManager.h"
00031 #include "CEGUIImageset.h"
00032 #include "CEGUIFontManager.h"
00033 #include "CEGUIFont.h"
00034 #include "CEGUIWindowFactoryManager.h"
00035 #include "CEGUIFactoryModule.h"
00036 #include "CEGUIScheme_xmlHandler.h"
00037 #include "CEGUIDataContainer.h"
00038 #include "CEGUISystem.h"
00039 
00040 #include "xercesc/sax2/SAX2XMLReader.hpp"
00041 #include "xercesc/sax2/XMLReaderFactory.hpp"
00042 #include "xercesc/framework/MemBufInputSource.hpp"
00043 
00044 // Start of CEGUI namespace section
00045 namespace CEGUI
00046 {
00047 
00048 /*************************************************************************
00049         Static Data definitions
00050 *************************************************************************/
00051 // name of the xml schema for GUIScheme files
00052 const char Scheme::GUISchemeSchemaName[]                                        = "GUIScheme.xsd";
00053 
00054 
00055 /*************************************************************************
00056         Constructor for scheme objects
00057 *************************************************************************/
00058 Scheme::Scheme(const String& filename, const String& resourceGroup)
00059 {
00060         XERCES_CPP_NAMESPACE_USE
00061 
00062         if (filename.empty() || (filename == (utf8*)""))
00063         {
00064                 throw InvalidRequestException((utf8*)"Scheme::Scheme - Filename supplied for Scheme loading must be valid");
00065         }
00066 
00067         SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
00068 
00069         // set basic settings we want from parser
00070         parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
00071         parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
00072         parser->setFeature(XMLUni::fgXercesSchema, true);
00073         parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal, true);
00074 
00075 //    InputSourceContainer schemeSchemaData;
00076 //    System::getSingleton().getResourceProvider()->loadInputSourceContainer(GUISchemeSchemaName, schemeSchemaData);
00077 //
00078 //    parser->loadGrammar(*(schemeSchemaData.getDataPtr()),
00079 //            Grammar::SchemaGrammarType, true);
00080 
00081     RawDataContainer rawSchemaData;
00082     System::getSingleton().getResourceProvider()->loadRawDataContainer(GUISchemeSchemaName, rawSchemaData, resourceGroup);
00083     MemBufInputSource  schemeSchemaData(rawSchemaData.getDataPtr(), rawSchemaData.getSize(), GUISchemeSchemaName, false);
00084     parser->loadGrammar(schemeSchemaData, Grammar::SchemaGrammarType, true);
00085 
00086     // enable grammar reuse
00087     parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
00088 
00089         // setup schema for Scheme data
00090         XMLCh* pval = XMLString::transcode(GUISchemeSchemaName);
00091         parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, pval);
00092         XMLString::release(&pval);
00093 
00094         // setup handler object
00095         Scheme_xmlHandler handler(this);
00096         parser->setContentHandler(&handler);
00097         parser->setErrorHandler(&handler);
00098 
00099 //    InputSourceContainer schemeData;
00100 //    System::getSingleton().getResourceProvider()->loadInputSourceContainer(filename, schemeData);
00101 
00102     RawDataContainer rawXMLData;
00103     System::getSingleton().getResourceProvider()->loadRawDataContainer(filename, rawXMLData, resourceGroup);
00104     MemBufInputSource  schemeData(rawXMLData.getDataPtr(), rawXMLData.getSize(), filename.c_str(), false);
00105 
00106         // do parse (which uses handler to create actual data)
00107         try
00108         {
00109 //        parser->parse(*(schemeData.getDataPtr()));
00110         parser->parse(schemeData);
00111         }
00112         catch(const XMLException& exc)
00113         {
00114                 if (exc.getCode() != XMLExcepts::NoError)
00115                 {
00116                         delete parser;
00117 
00118                         char* excmsg = XMLString::transcode(exc.getMessage());
00119                         String message((utf8*)"Scheme::Scheme - An error occurred while parsing Scheme file '" + filename + "'.  Additional information: ");
00120                         message += excmsg;
00121                         XMLString::release(&excmsg);
00122 
00123                         throw FileIOException(message);
00124                 }
00125 
00126         }
00127         catch(const SAXParseException& exc)
00128         {
00129                 delete parser;
00130 
00131                 char* excmsg = XMLString::transcode(exc.getMessage());
00132                 String message((utf8*)"Scheme::Scheme - An error occurred while parsing Scheme file '" + filename + "'.  Additional information: ");
00133                 message += excmsg;
00134                 XMLString::release(&excmsg);
00135 
00136                 throw FileIOException(message);
00137         }
00138         catch(...)
00139         {
00140                 delete parser;
00141 
00142                 throw FileIOException((utf8*)"Scheme::Scheme - An unexpected error occurred while parsing Scheme file '" + filename + "'.");
00143         }
00144 
00145         // cleanup
00146         delete parser;
00147 
00148         Logger::getSingleton().logEvent((utf8*)"Loaded GUI scheme '" + d_name + "' from data in file '" + filename + "'.", Informative);
00149 
00150         // attempt to load in resources
00151         loadResources();
00152 }
00153 
00154 
00155 /*************************************************************************
00156         Destructor for scheme objects
00157 *************************************************************************/
00158 Scheme::~Scheme(void)
00159 {
00160         unloadResources();
00161 
00162         Logger::getSingleton().logEvent((utf8*)"GUI scheme '" + d_name + "' has been unloaded.", Informative);
00163 }
00164 
00165 
00166 /*************************************************************************
00167         Load all resources for this scheme
00168 *************************************************************************/
00169 void Scheme::loadResources(void)
00170 {
00171         Logger::getSingleton().logEvent((utf8*)"---- Begining resource loading for GUI scheme '" + d_name + "' ----", Informative);
00172 
00173         ImagesetManager& ismgr          = ImagesetManager::getSingleton();
00174         FontManager& fntmgr                     = FontManager::getSingleton();
00175         WindowFactoryManager& wfmgr = WindowFactoryManager::getSingleton();
00176 
00177         std::vector<LoadableUIElement>::const_iterator  pos;
00178 
00179         // check imagesets
00180         for (pos = d_imagesets.begin(); pos != d_imagesets.end(); ++pos)
00181         {
00182                 if (!ismgr.isImagesetPresent((*pos).name))
00183                 {
00184                         Imageset* iset = ismgr.createImageset((*pos).filename, (*pos).resourceGroup);
00185 
00186                         // check for wrong imageset for specified name
00187                         String realname = iset->getName();
00188 
00189                         if (realname != (*pos).name)
00190                         {
00191                                 ismgr.destroyImageset(iset);
00192                                 throw InvalidRequestException((utf8*)"Scheme::loadResources - The Imageset created by file '" + 
00193                                         (*pos).filename + "' is named '" + realname + "', not '" + (*pos).name + "' as required by Scheme '" + d_name + "'.");
00194                         }
00195 
00196                 }
00197 
00198         }
00199 
00200         // check fonts
00201         for (pos = d_fonts.begin(); pos != d_fonts.end(); ++pos)
00202         {
00203                 if (!fntmgr.isFontPresent((*pos).name))
00204                 {
00205                         Font* font = fntmgr.createFont((*pos).filename, (*pos).resourceGroup);
00206 
00207                         // check for wrong font for specified name
00208                         String realname = font->getName();
00209 
00210                         if (realname != (*pos).name)
00211                         {
00212                                 fntmgr.destroyFont(font);
00213                                 throw InvalidRequestException((utf8*)"Scheme::loadResources - The Font created by file '" + 
00214                                         (*pos).filename + "' is named '" + realname + "', not '" + (*pos).name + "' as required by Scheme '" + d_name + "'.");
00215                         }
00216 
00217                 }
00218 
00219         }
00220 
00221         // check factories
00222         std::vector<UIModule>::iterator cmod = d_widgetModules.begin();
00223         for (;cmod != d_widgetModules.end(); ++cmod)
00224         {
00225                 // create and load dynamic module as required
00226                 if ((*cmod).module == NULL)
00227                 {
00228                         (*cmod).module = new FactoryModule((*cmod).name);
00229                 }
00230 
00231                 std::vector<UIElementFactory>::const_iterator   elem = (*cmod).factories.begin();
00232                 for (; elem != (*cmod).factories.end(); ++elem)
00233                 {
00234                         if (!wfmgr.isFactoryPresent((*elem).name))
00235                         {
00236                                 (*cmod).module->registerFactory((*elem).name);
00237                         }
00238 
00239                 }
00240 
00241         }
00242 
00243         // check aliases
00244         std::vector<AliasMapping>::iterator alias = d_aliasMappings.begin();
00245         for (;alias != d_aliasMappings.end(); ++alias)
00246         {
00247                 // get iterator 
00248                 WindowFactoryManager::TypeAliasIterator iter = wfmgr.getAliasIterator();
00249 
00250                 // look for this alias
00251                 while (!iter.isAtEnd() && (iter.getCurrentKey() != (*alias).aliasName))
00252                         ++iter;
00253 
00254                 // if the alias exists
00255                 if (!iter.isAtEnd())
00256                 {
00257                         // if the current target type matches
00258                         if (iter.getCurrentValue().getActiveTarget() == (*alias).targetName)
00259                         {
00260                                 // assume this mapping is ours and skip to next alias
00261                                 continue;
00262                         }
00263 
00264                 }
00265 
00266                 // create a new alias entry
00267                 wfmgr.addWindowTypeAlias((*alias).aliasName, (*alias).targetName);
00268         }
00269 
00270         Logger::getSingleton().logEvent((utf8*)"---- Resource loading for GUI scheme '" + d_name + "' completed ----", Informative);
00271 }
00272 
00273 
00274 /*************************************************************************
00275         Unload all resources for this scheme
00276 *************************************************************************/
00277 void Scheme::unloadResources(void)
00278 {
00279         Logger::getSingleton().logEvent((utf8*)"---- Begining resource cleanup for GUI scheme '" + d_name + "' ----", Informative);
00280 
00281         ImagesetManager& ismgr          = ImagesetManager::getSingleton();
00282         FontManager& fntmgr                     = FontManager::getSingleton();
00283         WindowFactoryManager& wfmgr = WindowFactoryManager::getSingleton();
00284 
00285         std::vector<LoadableUIElement>::const_iterator  pos;
00286 
00287         // check fonts
00288         for (pos = d_fonts.begin(); pos != d_fonts.end(); ++pos)
00289         {
00290                 fntmgr.destroyFont((*pos).name);
00291         }
00292 
00293         // check Imagesets
00294         for (pos = d_imagesets.begin(); pos != d_imagesets.end(); ++pos)
00295         {
00296                 ismgr.destroyImageset((*pos).name);
00297         }
00298 
00299         // check factories
00300         std::vector<UIModule>::iterator cmod = d_widgetModules.begin();
00301         for (;cmod != d_widgetModules.end(); ++cmod)
00302         {
00303                 std::vector<UIElementFactory>::const_iterator   elem = (*cmod).factories.begin();
00304                 for (; elem != (*cmod).factories.end(); ++elem)
00305                 {
00306                         wfmgr.removeFactory((*elem).name);
00307                 }
00308 
00309                 // unload dynamic module as required
00310                 if ((*cmod).module != NULL)
00311                 {
00312                         delete (*cmod).module;
00313                         (*cmod).module = NULL;
00314                 }
00315 
00316         }
00317 
00318         // check aliases
00319         std::vector<AliasMapping>::iterator alias = d_aliasMappings.begin();
00320         for (;alias != d_aliasMappings.end(); ++alias)
00321         {
00322                 // get iterator 
00323                 WindowFactoryManager::TypeAliasIterator iter = wfmgr.getAliasIterator();
00324 
00325                 // look for this alias
00326                 while (!iter.isAtEnd() && (iter.getCurrentKey() != (*alias).aliasName))
00327                         ++iter;
00328 
00329                 // if the alias exists
00330                 if (!iter.isAtEnd())
00331                 {
00332                         // create a new alias entry
00333                         wfmgr.removeWindowTypeAlias((*alias).aliasName, (*alias).targetName);
00334                 }
00335 
00336         }
00337 
00338         Logger::getSingleton().logEvent((utf8*)"---- Resource cleanup for GUI scheme '" + d_name + "' completed ----", Informative);
00339 }
00340 
00341 
00342 /*************************************************************************
00343         Check if all resources for this Scheme are loaded
00344 *************************************************************************/
00345 bool Scheme::resourcesLoaded(void) const
00346 {
00347         ImagesetManager& ismgr          = ImagesetManager::getSingleton();
00348         FontManager& fntmgr                     = FontManager::getSingleton();
00349         WindowFactoryManager& wfmgr = WindowFactoryManager::getSingleton();
00350 
00351         std::vector<LoadableUIElement>::const_iterator  pos;
00352 
00353         // check imagesets
00354         for (pos = d_imagesets.begin(); pos != d_imagesets.end(); ++pos)
00355         {
00356                 if (!ismgr.isImagesetPresent((*pos).name))
00357                 {
00358                         return false;
00359                 }
00360 
00361         }
00362 
00363         // check fonts
00364         for (pos = d_fonts.begin(); pos != d_fonts.end(); ++pos)
00365         {
00366                 if (!fntmgr.isFontPresent((*pos).name))
00367                 {
00368                         return false;
00369                 }
00370 
00371         }
00372 
00373         // check factories
00374         std::vector<UIModule>::const_iterator   cmod = d_widgetModules.begin();
00375         for (;cmod != d_widgetModules.end(); ++cmod)
00376         {
00377                 std::vector<UIElementFactory>::const_iterator   elem = (*cmod).factories.begin();
00378 
00379                 for (; elem != (*cmod).factories.end(); ++elem)
00380                 {
00381                         if (!wfmgr.isFactoryPresent((*elem).name))
00382                         {
00383                                 return false;
00384                         }
00385 
00386                 }
00387 
00388         }
00389 
00390         // check aliases
00391         std::vector<AliasMapping>::const_iterator alias = d_aliasMappings.begin();
00392         for (;alias != d_aliasMappings.end(); ++alias)
00393         {
00394                 // get iterator 
00395                 WindowFactoryManager::TypeAliasIterator iter = wfmgr.getAliasIterator();
00396 
00397                 // look for this alias
00398                 while (!iter.isAtEnd() && (iter.getCurrentKey() != (*alias).aliasName))
00399                         ++iter;
00400 
00401                 // if the alias exists
00402                 if (!iter.isAtEnd())
00403                 {
00404                         // if the current target type matches
00405                         if (iter.getCurrentValue().getActiveTarget() == (*alias).targetName)
00406                         {
00407                                 // target matches, assume we set it and continue to next alias
00408                                 continue;
00409                         }
00410 
00411                 }
00412 
00413                 // no alias or target type does not match
00414                 return false;
00415         }
00416 
00417         return true;
00418 }
00419 
00420 
00421 } // End of  CEGUI namespace section

Generated on Wed Feb 16 12:41:07 2005 for Crazy Eddies GUI System by  doxygen 1.3.9.1