PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: LoadableManager.h * 00003 * 00004 * Copyright (C) 2002-2012 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 * @brief 00156 * Returns loadable types by using a loadable extension 00157 * 00158 * @param[in] sExtension 00159 * Extension of loadable 00160 * @param[out] lstTypes 00161 * Receives the list of matching loadable types (list is not cleared before new entries are added), there can be multiple candidates 00162 */ 00163 PLCORE_API void GetTypesByExtension(const String &sExtension, Array<LoadableType*> &lstTypes); 00164 00165 //[-------------------------------------------------------] 00166 //[ Loaders ] 00167 //[-------------------------------------------------------] 00168 /** 00169 * @brief 00170 * Returns the number of loaders 00171 * 00172 * @return 00173 * The number of loaders 00174 */ 00175 inline uint32 GetNumOfLoaders(); 00176 00177 /** 00178 * @brief 00179 * Returns a loader by using an index 00180 * 00181 * @param[in] nIndex 00182 * Loader index 00183 * 00184 * @return 00185 * The requested loader, a null pointer on error 00186 */ 00187 inline Loader *GetLoaderByIndex(uint32 nIndex); 00188 00189 /** 00190 * @brief 00191 * Returns a loader by using a loadable extension 00192 * 00193 * @param[in] sExtension 00194 * Extension of loadable 00195 * 00196 * @return 00197 * The requested loader (first found if there are multiple candidates), a null pointer on error 00198 */ 00199 inline Loader *GetLoaderByExtension(const String &sExtension); 00200 00201 /** 00202 * @brief 00203 * Returns loaders by using a loadable extension 00204 * 00205 * @param[in] sExtension 00206 * Extension of loadable 00207 * @param[out] lstLoaders 00208 * Receives the list of matching loaders (list is not cleared before new entries are added), there can be multiple candidates 00209 */ 00210 PLCORE_API void GetLoadersByExtension(const String &sExtension, Array<Loader*> &lstLoaders); 00211 00212 //[-------------------------------------------------------] 00213 //[ Formats ] 00214 //[-------------------------------------------------------] 00215 /** 00216 * @brief 00217 * Returns the number of supported formats 00218 * 00219 * @return 00220 * The number of supported formats 00221 */ 00222 inline uint32 GetNumOfFormats(); 00223 00224 /** 00225 * @brief 00226 * Returns a supported format 00227 * 00228 * @param[in] nIndex 00229 * Format index 00230 * 00231 * @return 00232 * The requested supported format, empty string on error 00233 */ 00234 inline String GetFormat(uint32 nIndex); 00235 00236 /** 00237 * @brief 00238 * Returns whether loading is supported for the given format 00239 * 00240 * @param[in] sExtension 00241 * Extension of the format 00242 * @param[in] sType 00243 * Required loadable type, if empty string ignore loadable type 00244 * 00245 * @return 00246 * 'true' if loading is supported for the given format, else 'false' 00247 */ 00248 PLCORE_API bool IsFormatLoadSupported(const String &sExtension, const String &sType = ""); 00249 00250 /** 00251 * @brief 00252 * Returns whether saving is supported for the given format 00253 * 00254 * @param[in] sExtension 00255 * Extension of the format 00256 * @param[in] sType 00257 * Required loadable type, if empty string ignore loadable type 00258 * 00259 * @return 00260 * 'true' if saving is supported for the given format, else 'false' 00261 */ 00262 PLCORE_API bool IsFormatSaveSupported(const String &sExtension, const String &sType = ""); 00263 00264 //[-------------------------------------------------------] 00265 //[ Base directories ] 00266 //[-------------------------------------------------------] 00267 /** 00268 * @brief 00269 * Returns the number of base directories 00270 * 00271 * @return 00272 * Number of base directories 00273 */ 00274 inline uint32 GetNumOfBaseDirs() const; 00275 00276 /** 00277 * @brief 00278 * Returns one of the base directories 00279 * 00280 * @param[in] nNum 00281 * Number of the base directory to get 00282 * 00283 * @return 00284 * Path of the base directory or empty string 00285 */ 00286 inline String GetBaseDir(uint32 nNum) const; 00287 00288 /** 00289 * @brief 00290 * Checks whether the given path is a base directory 00291 * 00292 * @param[in] sPath 00293 * Path to the base directory 00294 * 00295 * @return 00296 * 'true', if the given path is a base directory, else 'false' 00297 */ 00298 PLCORE_API bool IsBaseDir(const String &sPath) const; 00299 00300 /** 00301 * @brief 00302 * Adds a base directory 00303 * 00304 * @param[in] sPath 00305 * Path to the base directory 00306 * 00307 * @return 00308 * 'true', if all went fine, else 'false' 00309 */ 00310 PLCORE_API bool AddBaseDir(const String &sPath); 00311 00312 /** 00313 * @brief 00314 * Set the priority of base directories 00315 * 00316 * @param[in] sFirstPath 00317 * Path to the first base directory 00318 * @param[in] sSecondPath 00319 * Path to the second base directory 00320 * 00321 * @return 00322 * 'true', if all went fine, else 'false' 00323 * 00324 * @remarks 00325 * This function changes the order of the two base dirs 00326 * so that sSecondPath comes right after sFirstPath. 00327 */ 00328 PLCORE_API bool SetBaseDirPriority(const String &sFirstPath, const String &sSecondPath); 00329 00330 /** 00331 * @brief 00332 * Remove a base directory 00333 * 00334 * @param[in] sPath 00335 * Base directory to remove 00336 * 00337 * @return 00338 * 'true', if all went fine, else 'false' 00339 */ 00340 PLCORE_API bool RemoveBaseDir(const String &sPath); 00341 00342 /** 00343 * @brief 00344 * Remove a base directory 00345 * 00346 * @param[in] nNum 00347 * Number of the base directory to remove 00348 * 00349 * @return 00350 * 'true', if all went fine, else 'false' 00351 */ 00352 PLCORE_API bool RemoveBaseDir(uint32 nNum); 00353 00354 /** 00355 * @brief 00356 * Removes all base directories 00357 * 00358 * @return 00359 * 'true', if all went fine, else 'false' 00360 */ 00361 inline bool ClearBaseDirs(); 00362 00363 /** 00364 * @brief 00365 * Gets the relative version of an absolute filename 00366 * 00367 * @param[in] sFilename 00368 * Absolute filename to get the relative version from 00369 * 00370 * @return 00371 * Relative filename, empty string on error (maybe unknown loadable type?) 00372 * 00373 * @note 00374 * - This function only checks whether there's a loadable type for the given file type, 00375 * if so, the request is given to this loadable type 00376 * 00377 * @see 00378 * - LoadableType::GetRelativeFilePath() 00379 */ 00380 PLCORE_API String GetRelativeFilename(const String &sFilename); 00381 00382 /** 00383 * @brief 00384 * Scan a directory for data packages and add them as base paths to the loadable manager 00385 * 00386 * @param[in] sPath 00387 * Directory to search in 00388 * @param[in] sExtension 00389 * Extension of the archives to add (e.g. 'zip' or 'pak') 00390 * 00391 * @return 00392 * 'true' if all went fine, else 'false' 00393 */ 00394 PLCORE_API bool ScanPackages(const String &sPath, const String &sExtension = "*.zip"); 00395 00396 /** 00397 * @brief 00398 * Opens a file by using base directories 00399 * 00400 * @param[in] cFile 00401 * File object 00402 * @param[in] sFilename 00403 * Filename of the file to open 00404 * @param[in] bCreate 00405 * Create the file if it doesn't exist? 00406 * @param[in] nStringFormat 00407 * String encoding format to use when dealing with string functions (not supported by all file implementations) 00408 * 00409 * @return 00410 * 'true' if all went fine, else 'false' 00411 * 00412 * @note 00413 * - It's not recommended to use Unicode by because internally wchar_t is used and this data type has not 00414 * the same size on every platform (use ASCII or UTF8 instead) 00415 */ 00416 PLCORE_API bool OpenFile(File &cFile, const String &sFilename, bool bCreate = false, String::EFormat nStringFormat = String::ASCII) const; 00417 00418 /** 00419 * @brief 00420 * Loads in a string by using a file 00421 * 00422 * @param[in] sFilename 00423 * Name of the file to read the string from 00424 * @param[in] nStringFormat 00425 * String encoding format to use when dealing with string functions (not supported by all file implementations) 00426 * 00427 * @return 00428 * The read string, empty string on error or if the file is just empty 00429 * 00430 * @note 00431 * - The file is opened by using base directories 00432 * - It's not recommended to use Unicode by because internally wchar_t is used and this data type has not 00433 * the same size on every platform (use ASCII or UTF8 instead) 00434 */ 00435 PLCORE_API String LoadStringFromFile(const String &sFilename, String::EFormat nStringFormat = String::ASCII) const; 00436 00437 00438 //[-------------------------------------------------------] 00439 //[ Protected functions ] 00440 //[-------------------------------------------------------] 00441 protected: 00442 /** 00443 * @brief 00444 * Constructor 00445 */ 00446 PLCORE_API LoadableManager(); 00447 00448 /** 00449 * @brief 00450 * Destructor 00451 */ 00452 PLCORE_API virtual ~LoadableManager(); 00453 00454 00455 //[-------------------------------------------------------] 00456 //[ Private functions ] 00457 //[-------------------------------------------------------] 00458 private: 00459 /** 00460 * @brief 00461 * Copy operator 00462 * 00463 * @param[in] cSource 00464 * Source to copy from 00465 * 00466 * @return 00467 * Reference to this instance 00468 */ 00469 LoadableManager &operator =(const LoadableManager &cSource); 00470 00471 /** 00472 * @brief 00473 * Register a class 00474 * 00475 * @param[in] pClass 00476 * Class to register, must be valid! 00477 * 00478 * @note 00479 * - If the class is not derived from 'Loader' it is ignored 00480 * - The given class must be a new one, so this function did not check whether the 00481 * class is already registered 00482 */ 00483 void OnClassLoaded(const Class *pClass); 00484 00485 /** 00486 * @brief 00487 * Unregister a class 00488 * 00489 * @param[in] pClass 00490 * Class to unregister, must be valid! 00491 */ 00492 void OnClassUnloaded(const Class *pClass); 00493 00494 /** 00495 * @brief 00496 * Registers queued classes 00497 */ 00498 PLCORE_API void RegisterClasses(); 00499 00500 00501 //[-------------------------------------------------------] 00502 //[ Private slots ] 00503 //[-------------------------------------------------------] 00504 private: 00505 EventHandler<const Class*> SlotClassLoaded; 00506 EventHandler<const Class*> SlotClassUnloaded; 00507 00508 00509 //[-------------------------------------------------------] 00510 //[ Private data ] 00511 //[-------------------------------------------------------] 00512 private: 00513 // General 00514 Array<LoadableType*> m_lstTypes; /**< List of loadable types */ 00515 HashMap<String, LoadableType*> m_mapTypes; /**< Map of loadable types */ 00516 Array<String> m_lstBaseDirs; /**< List of base directories */ 00517 Array<const Class*> m_lstNewClasses; /**< New classes to register as soon as required */ 00518 // Filled by LoadableType 00519 Array<Loader*> m_lstLoaders; /**< List of loaders */ 00520 HashMap<String, Loader*> m_mapLoaders; /**< Map of loaders (key = extension) */ 00521 Array<String> m_lstFormats; /**< List of loadable formats */ 00522 HashMap<String, LoadableType*> m_mapTypesByExtension; /**< Map of loadable types (key = extension) */ 00523 00524 00525 }; 00526 00527 00528 //[-------------------------------------------------------] 00529 //[ Namespace ] 00530 //[-------------------------------------------------------] 00531 } // PLCore 00532 00533 00534 //[-------------------------------------------------------] 00535 //[ Implementation ] 00536 //[-------------------------------------------------------] 00537 #include "PLCore/Tools/LoadableManager.inl" 00538 00539 00540 #endif // __PLCORE_LOADABLEMANAGER_H__
|