PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: LoadableManager.h * 00003 * 00004 * Copyright (C) 2002-2011 The PixelLight Team (http://www.pixellight.org/) 00005 * 00006 * This file is part of PixelLight. 00007 * 00008 * PixelLight is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * PixelLight is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with PixelLight. If not, see <http://www.gnu.org/licenses/>. 00020 \*********************************************************/ 00021 00022 00023 #ifndef __PLCORE_LOADABLEMANAGER_H__ 00024 #define __PLCORE_LOADABLEMANAGER_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include "PLCore/Tools/Loadable.h" 00032 #include "PLCore/Core/Singleton.h" 00033 #include "PLCore/Container/Array.h" 00034 #include "PLCore/Container/HashMap.h" 00035 #include "PLCore/Base/Event/EventHandler.h" 00036 00037 00038 //[-------------------------------------------------------] 00039 //[ Namespace ] 00040 //[-------------------------------------------------------] 00041 namespace PLCore { 00042 00043 00044 //[-------------------------------------------------------] 00045 //[ Forward declarations ] 00046 //[-------------------------------------------------------] 00047 class Class; 00048 class Loader; 00049 class Directory; 00050 class LoadableType; 00051 class LoadableManager; 00052 00053 00054 //[-------------------------------------------------------] 00055 //[ Classes ] 00056 //[-------------------------------------------------------] 00057 /** 00058 * @brief 00059 * Loadable manager 00060 * 00061 * @remarks 00062 * A loadable class is for instance an image that can be loaded & saved in multiple ways/formats. 00063 * Such a loadable is registered within this manager as a 'loadable type'. Each loadable type can 00064 * have multiple loaders which load/save the loadable within a concrete way/format. 00065 * 00066 * Example: 00067 * - Image 00068 * - ImageLoaderEXR (*.exr) 00069 * - Mesh 00070 * - MeshLoaderPL (*.mesh) 00071 * - MeshLoader3ds (*.3ds) 00072 * - MeshLoaderObj (*.obj) 00073 * -> By asking the loadable manager which 'file formats/extensions' are supported for the 'Mesh' type, 00074 * it will return in this example 'mesh, 3ds. obj'. One loader can also support multiple formats. 00075 * 00076 * @note 00077 * - An empty string is also a valid base directory and represents the current system directory 00078 * (see System::GetCurrentDir()) 00079 */ 00080 class LoadableManager : public Singleton<LoadableManager> { 00081 00082 00083 //[-------------------------------------------------------] 00084 //[ Friends ] 00085 //[-------------------------------------------------------] 00086 friend class LoadableType; 00087 friend class Singleton<LoadableManager>; 00088 00089 00090 //[-------------------------------------------------------] 00091 //[ Public static PLCore::Singleton functions ] 00092 //[-------------------------------------------------------] 00093 // This solution enhances the compatibility with legacy compilers like GCC 4.2.1 used on Mac OS X 10.6 00094 // -> The C++11 feature "extern template" (C++11, see e.g. http://www2.research.att.com/~bs/C++0xFAQ.html#extern-templates) can only be used on modern compilers like GCC 4.6 00095 // -> We can't break legacy compiler support, especially when only the singletons are responsible for the break 00096 // -> See PLCore::Singleton for more details about singletons 00097 public: 00098 static PLCORE_API LoadableManager *GetInstance(); 00099 static PLCORE_API bool HasInstance(); 00100 00101 00102 //[-------------------------------------------------------] 00103 //[ Public functions ] 00104 //[-------------------------------------------------------] 00105 public: 00106 //[-------------------------------------------------------] 00107 //[ Types ] 00108 //[-------------------------------------------------------] 00109 /** 00110 * @brief 00111 * Returns the number of loadable types 00112 * 00113 * @return 00114 * The number of loadable types 00115 */ 00116 inline uint32 GetNumOfTypes(); 00117 00118 /** 00119 * @brief 00120 * Returns a loadable type by using an index 00121 * 00122 * @param[in] nIndex 00123 * Loadable type index 00124 * 00125 * @return 00126 * The requested loadable type, a null pointer on error 00127 */ 00128 inline LoadableType *GetTypeByIndex(uint32 nIndex); 00129 00130 /** 00131 * @brief 00132 * Returns a loadable type by using it's name 00133 * 00134 * @param[in] sName 00135 * Loadable type name 00136 * 00137 * @return 00138 * The requested loadable type, a null pointer on error 00139 */ 00140 inline LoadableType *GetTypeByName(const String &sName); 00141 00142 /** 00143 * @brief 00144 * Returns a loadable type by using a loadable extension 00145 * 00146 * @param[in] sExtension 00147 * Extension of loadable 00148 * 00149 * @return 00150 * The requested loadable type (first found if there are multiple candidates), a null pointer on error 00151 */ 00152 inline LoadableType *GetTypeByExtension(const String &sExtension); 00153 00154 //[-------------------------------------------------------] 00155 //[ Loaders ] 00156 //[-------------------------------------------------------] 00157 /** 00158 * @brief 00159 * Returns the number of loaders 00160 * 00161 * @return 00162 * The number of loaders 00163 */ 00164 inline uint32 GetNumOfLoaders(); 00165 00166 /** 00167 * @brief 00168 * Returns a loader by using an index 00169 * 00170 * @param[in] nIndex 00171 * Loader index 00172 * 00173 * @return 00174 * The requested loader, a null pointer on error 00175 */ 00176 inline Loader *GetLoaderByIndex(uint32 nIndex); 00177 00178 /** 00179 * @brief 00180 * Returns a loader by using a loadable extension 00181 * 00182 * @param[in] sExtension 00183 * Extension of loadable 00184 * 00185 * @return 00186 * The requested loader (first found if there are multiple candidates), a null pointer on error 00187 */ 00188 inline Loader *GetLoaderByExtension(const String &sExtension); 00189 00190 //[-------------------------------------------------------] 00191 //[ Formats ] 00192 //[-------------------------------------------------------] 00193 /** 00194 * @brief 00195 * Returns the number of supported formats 00196 * 00197 * @return 00198 * The number of supported formats 00199 */ 00200 inline uint32 GetNumOfFormats(); 00201 00202 /** 00203 * @brief 00204 * Returns a supported format 00205 * 00206 * @param[in] nIndex 00207 * Format index 00208 * 00209 * @return 00210 * The requested supported format, empty string on error 00211 */ 00212 inline String GetFormat(uint32 nIndex); 00213 00214 /** 00215 * @brief 00216 * Returns whether loading is supported for the given format 00217 * 00218 * @param[in] sExtension 00219 * Extension of the format 00220 * @param[in] sType 00221 * Required loadable type, if empty string ignore loadable type 00222 * 00223 * @return 00224 * 'true' if loading is supported for the given format, else 'false' 00225 */ 00226 PLCORE_API bool IsFormatLoadSupported(const String &sExtension, const String &sType = ""); 00227 00228 /** 00229 * @brief 00230 * Returns whether saving is supported for the given format 00231 * 00232 * @param[in] sExtension 00233 * Extension of the format 00234 * @param[in] sType 00235 * Required loadable type, if empty string ignore loadable type 00236 * 00237 * @return 00238 * 'true' if saving is supported for the given format, else 'false' 00239 */ 00240 PLCORE_API bool IsFormatSaveSupported(const String &sExtension, const String &sType = ""); 00241 00242 //[-------------------------------------------------------] 00243 //[ Base directories ] 00244 //[-------------------------------------------------------] 00245 /** 00246 * @brief 00247 * Returns the number of base directories 00248 * 00249 * @return 00250 * Number of base directories 00251 */ 00252 inline uint32 GetNumOfBaseDirs() const; 00253 00254 /** 00255 * @brief 00256 * Returns one of the base directories 00257 * 00258 * @param[in] nNum 00259 * Number of the base directory to get 00260 * 00261 * @return 00262 * Path of the base directory or empty string 00263 */ 00264 inline String GetBaseDir(uint32 nNum) const; 00265 00266 /** 00267 * @brief 00268 * Checks whether the given path is a base directory 00269 * 00270 * @param[in] sPath 00271 * Path to the base directory 00272 * 00273 * @return 00274 * 'true', if the given path is a base directory, else 'false' 00275 */ 00276 PLCORE_API bool IsBaseDir(const String &sPath) const; 00277 00278 /** 00279 * @brief 00280 * Adds a base directory 00281 * 00282 * @param[in] sPath 00283 * Path to the base directory 00284 * 00285 * @return 00286 * 'true', if all went fine, else 'false' 00287 */ 00288 PLCORE_API bool AddBaseDir(const String &sPath); 00289 00290 /** 00291 * @brief 00292 * Set the priority of base directories 00293 * 00294 * @param[in] sFirstPath 00295 * Path to the first base directory 00296 * @param[in] sSecondPath 00297 * Path to the second base directory 00298 * 00299 * @return 00300 * 'true', if all went fine, else 'false' 00301 * 00302 * @remarks 00303 * This function changes the order of the two base dirs 00304 * so that sSecondPath comes right after sFirstPath. 00305 */ 00306 PLCORE_API bool SetBaseDirPriority(const String &sFirstPath, const String &sSecondPath); 00307 00308 /** 00309 * @brief 00310 * Remove a base directory 00311 * 00312 * @param[in] sPath 00313 * Base directory to remove 00314 * 00315 * @return 00316 * 'true', if all went fine, else 'false' 00317 */ 00318 PLCORE_API bool RemoveBaseDir(const String &sPath); 00319 00320 /** 00321 * @brief 00322 * Remove a base directory 00323 * 00324 * @param[in] nNum 00325 * Number of the base directory to remove 00326 * 00327 * @return 00328 * 'true', if all went fine, else 'false' 00329 */ 00330 PLCORE_API bool RemoveBaseDir(uint32 nNum); 00331 00332 /** 00333 * @brief 00334 * Removes all base directories 00335 * 00336 * @return 00337 * 'true', if all went fine, else 'false' 00338 */ 00339 inline bool ClearBaseDirs(); 00340 00341 /** 00342 * @brief 00343 * Gets the relative version of an absolute filename 00344 * 00345 * @param[in] sFilename 00346 * Absolute filename to get the relative version from 00347 * 00348 * @return 00349 * Relative filename, empty string on error (maybe unknown loadable type?) 00350 * 00351 * @note 00352 * - This function only checks whether there's a loadable type for the given file type, 00353 * if so, the request is given to this loadable type 00354 * 00355 * @see 00356 * - LoadableType::GetRelativeFilePath() 00357 */ 00358 PLCORE_API String GetRelativeFilename(const String &sFilename); 00359 00360 /** 00361 * @brief 00362 * Scan a directory for data packages and add them as base paths to the loadable manager 00363 * 00364 * @param[in] sPath 00365 * Directory to search in 00366 * @param[in] sExtension 00367 * Extension of the archives to add (e.g. 'zip' or 'pak') 00368 * 00369 * @return 00370 * 'true' if all went fine, else 'false' 00371 */ 00372 PLCORE_API bool ScanPackages(const String &sPath, const String &sExtension = "*.zip"); 00373 00374 /** 00375 * @brief 00376 * Opens a file by using base directories 00377 * 00378 * @param[in] cFile 00379 * File object 00380 * @param[in] sFilename 00381 * Filename of the file to open 00382 * @param[in] bCreate 00383 * Create the file if it doesn't exist? 00384 * @param[in] nStringFormat 00385 * String encoding format to use when dealing with string functions (not supported by all file implementations) 00386 * 00387 * @return 00388 * 'true' if all went fine, else 'false' 00389 * 00390 * @note 00391 * - It's not recommended to use Unicode by because internally wchar_t is used and this data type has not 00392 * the same size on every platform (use ASCII or UTF8 instead) 00393 */ 00394 PLCORE_API bool OpenFile(File &cFile, const String &sFilename, bool bCreate = false, String::EFormat nStringFormat = String::ASCII) const; 00395 00396 /** 00397 * @brief 00398 * Loads in a string by using a file 00399 * 00400 * @param[in] sFilename 00401 * Name of the file to read the string from 00402 * @param[in] nStringFormat 00403 * String encoding format to use when dealing with string functions (not supported by all file implementations) 00404 * 00405 * @return 00406 * The read string, empty string on error or if the file is just empty 00407 * 00408 * @note 00409 * - The file is opened by using base directories 00410 * - It's not recommended to use Unicode by because internally wchar_t is used and this data type has not 00411 * the same size on every platform (use ASCII or UTF8 instead) 00412 */ 00413 PLCORE_API String LoadStringFromFile(const String &sFilename, String::EFormat nStringFormat = String::ASCII) const; 00414 00415 00416 //[-------------------------------------------------------] 00417 //[ Protected functions ] 00418 //[-------------------------------------------------------] 00419 protected: 00420 /** 00421 * @brief 00422 * Constructor 00423 */ 00424 PLCORE_API LoadableManager(); 00425 00426 /** 00427 * @brief 00428 * Destructor 00429 */ 00430 PLCORE_API virtual ~LoadableManager(); 00431 00432 00433 //[-------------------------------------------------------] 00434 //[ Private functions ] 00435 //[-------------------------------------------------------] 00436 private: 00437 /** 00438 * @brief 00439 * Copy operator 00440 * 00441 * @param[in] cSource 00442 * Source to copy from 00443 * 00444 * @return 00445 * Reference to this instance 00446 */ 00447 LoadableManager &operator =(const LoadableManager &cSource); 00448 00449 /** 00450 * @brief 00451 * Register a class 00452 * 00453 * @param[in] pClass 00454 * Class to register, must be valid! 00455 * 00456 * @note 00457 * - If the class is not derived from 'Loader' it is ignored 00458 * - The given class must be a new one, so this function did not check whether the 00459 * class is already registered 00460 */ 00461 void OnClassLoaded(const Class *pClass); 00462 00463 /** 00464 * @brief 00465 * Registers queued classes 00466 */ 00467 PLCORE_API void RegisterClasses(); 00468 00469 00470 //[-------------------------------------------------------] 00471 //[ Private slots ] 00472 //[-------------------------------------------------------] 00473 private: 00474 EventHandler<const Class*> SlotClassLoaded; 00475 00476 00477 //[-------------------------------------------------------] 00478 //[ Private data ] 00479 //[-------------------------------------------------------] 00480 private: 00481 // General 00482 Array<LoadableType*> m_lstTypes; /**< List of loadable types */ 00483 HashMap<String, LoadableType*> m_mapTypes; /**< Map of loadable types */ 00484 Array<String> m_lstBaseDirs; /**< List of base directories */ 00485 Array<const Class*> m_lstNewClasses; /**< New classes to register as soon as required */ 00486 // Filled by LoadableType 00487 Array<Loader*> m_lstLoaders; /**< List of loaders */ 00488 HashMap<String, Loader*> m_mapLoaders; /**< Map of loaders (key = extension) */ 00489 Array<String> m_lstFormats; /**< List of loadable formats */ 00490 HashMap<String, LoadableType*> m_mapTypesByExtension; /**< Map of loadable types (key = extension) */ 00491 00492 00493 }; 00494 00495 00496 //[-------------------------------------------------------] 00497 //[ Namespace ] 00498 //[-------------------------------------------------------] 00499 } // PLCore 00500 00501 00502 //[-------------------------------------------------------] 00503 //[ Implementation ] 00504 //[-------------------------------------------------------] 00505 #include "PLCore/Tools/LoadableManager.inl" 00506 00507 00508 #endif // __PLCORE_LOADABLEMANAGER_H__
|