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


PixelLight PixelLight 0.9.10-R1
Copyright (C) 2002-2011 by The PixelLight Team
Last modified Fri Dec 23 2011 15:50:57
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported