00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00045 namespace CEGUI
00046 {
00047
00048
00049
00050
00051
00052 const char Scheme::GUISchemeSchemaName[] = "GUIScheme.xsd";
00053
00054
00055
00056
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
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
00076
00077
00078
00079
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
00087 parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
00088
00089
00090 XMLCh* pval = XMLString::transcode(GUISchemeSchemaName);
00091 parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, pval);
00092 XMLString::release(&pval);
00093
00094
00095 Scheme_xmlHandler handler(this);
00096 parser->setContentHandler(&handler);
00097 parser->setErrorHandler(&handler);
00098
00099
00100
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
00107 try
00108 {
00109
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
00146 delete parser;
00147
00148 Logger::getSingleton().logEvent((utf8*)"Loaded GUI scheme '" + d_name + "' from data in file '" + filename + "'.", Informative);
00149
00150
00151 loadResources();
00152 }
00153
00154
00155
00156
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
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
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
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
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
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
00222 std::vector<UIModule>::iterator cmod = d_widgetModules.begin();
00223 for (;cmod != d_widgetModules.end(); ++cmod)
00224 {
00225
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
00244 std::vector<AliasMapping>::iterator alias = d_aliasMappings.begin();
00245 for (;alias != d_aliasMappings.end(); ++alias)
00246 {
00247
00248 WindowFactoryManager::TypeAliasIterator iter = wfmgr.getAliasIterator();
00249
00250
00251 while (!iter.isAtEnd() && (iter.getCurrentKey() != (*alias).aliasName))
00252 ++iter;
00253
00254
00255 if (!iter.isAtEnd())
00256 {
00257
00258 if (iter.getCurrentValue().getActiveTarget() == (*alias).targetName)
00259 {
00260
00261 continue;
00262 }
00263
00264 }
00265
00266
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
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
00288 for (pos = d_fonts.begin(); pos != d_fonts.end(); ++pos)
00289 {
00290 fntmgr.destroyFont((*pos).name);
00291 }
00292
00293
00294 for (pos = d_imagesets.begin(); pos != d_imagesets.end(); ++pos)
00295 {
00296 ismgr.destroyImageset((*pos).name);
00297 }
00298
00299
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
00310 if ((*cmod).module != NULL)
00311 {
00312 delete (*cmod).module;
00313 (*cmod).module = NULL;
00314 }
00315
00316 }
00317
00318
00319 std::vector<AliasMapping>::iterator alias = d_aliasMappings.begin();
00320 for (;alias != d_aliasMappings.end(); ++alias)
00321 {
00322
00323 WindowFactoryManager::TypeAliasIterator iter = wfmgr.getAliasIterator();
00324
00325
00326 while (!iter.isAtEnd() && (iter.getCurrentKey() != (*alias).aliasName))
00327 ++iter;
00328
00329
00330 if (!iter.isAtEnd())
00331 {
00332
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
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
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
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
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
00391 std::vector<AliasMapping>::const_iterator alias = d_aliasMappings.begin();
00392 for (;alias != d_aliasMappings.end(); ++alias)
00393 {
00394
00395 WindowFactoryManager::TypeAliasIterator iter = wfmgr.getAliasIterator();
00396
00397
00398 while (!iter.isAtEnd() && (iter.getCurrentKey() != (*alias).aliasName))
00399 ++iter;
00400
00401
00402 if (!iter.isAtEnd())
00403 {
00404
00405 if (iter.getCurrentValue().getActiveTarget() == (*alias).targetName)
00406 {
00407
00408 continue;
00409 }
00410
00411 }
00412
00413
00414 return false;
00415 }
00416
00417 return true;
00418 }
00419
00420
00421 }