PixelLightAPI  .
LoadableManager.h
Go to the documentation of this file.
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__


PixelLight PixelLight 0.9.11-R1
Copyright (C) 2002-2012 by The PixelLight Team
Last modified Thu Feb 23 2012 14:08:56
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported