MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
resourcemanager.h
Go to the documentation of this file.
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _resourcemanager_h
41 #define _resourcemanager_h
42 
43 #include "crossplatformexport.h"
44 #include "datatypes.h"
45 #include "enumerations.h"
46 #include "managerbase.h"
47 #include "managerfactory.h"
48 #include "singleton.h"
49 #include "Resource/datastream.h"
50 #include "Resource/inputstream.h"
51 
52 /// @file
53 /// @brief The defintion of the Resource Manager.
54 
55 namespace Ogre
56 {
57  class ResourceGroupManager;
58 }
59 
60 namespace Mezzanine
61 {
62  class ResourceGroup;
63 
64  // Used by the scripting language binder to help create bindgings for this class. SWIG does know to creation template instances
65  #ifdef SWIG
66  %template(SingletonResourceManager) Singleton<ResourceManager>;
67  #endif
68 
69  ///////////////////////////////////////////////////////////////////////////////
70  /// @class ResourceManager
71  /// @headerfile resourcemanager.h
72  /// @brief This is the manager responsible for the loading and unloading of files.
73  /// @details This class is responsible for the reading and writing of files of all kinds, be
74  /// it graphical meshes, physics data, or XMl files.
75  ///////////////////////////////////////
77  {
78  public:
79  /// @brief Basic container type for @ref DataStream storage by this class.
80  typedef std::vector<Resource::DataStreamPtr> DataStreamContainer;
81  /// @brief Iterator type for @ref DataStream instances stored by this class.
82  typedef DataStreamContainer::iterator DataStreamIterator;
83  /// @brief Const Iterator type for @ref DataStream instances stored by this class.
84  typedef DataStreamContainer::const_iterator ConstDataStreamIterator;
85  /// @brief Basic container type for named @ref DataStream storage by this class.
86  typedef std::map<String,Resource::DataStreamPtr> NamedDataStreamContainer;
87  /// @brief Iterator type for named @ref DataStream instances stored by this class.
88  typedef NamedDataStreamContainer::iterator NamedDataStreamIterator;
89  /// @brief Const Iterator type for named @ref DataStream instances stored by this class.
90  typedef NamedDataStreamContainer::const_iterator ConstNamedDataStreamIterator;
91  protected:
92  /// @internal
93  /// @brief Encapsulates the functionality of the ogre resource group manager.
94  Ogre::ResourceGroupManager* OgreResource;
95  /// @internal
96  /// @brief The location of engine data.
98 
99  /// @internal
100  /// @brief A container storing all un-named, un-grouped data streams known by the resource system.
101  DataStreamContainer DataStreams;
102  /// @internal
103  /// @brief A container storing all named but un-grouped data streams known by the resource system.
104  NamedDataStreamContainer NamedDataStreams;
105 
106  /// @internal
107  /// @brief A vector of Pointers to streams created to delete periodically.
108  std::vector<ResourceInputStream*> DeleteList;
109  /// @internal
110  /// @brief A vector of all the known internal Asset Groups.
111  std::vector<String> ResourceGroups;
112 
113  /// @brief ArgC as it was passed into Main.
114  /// @details This cannot be set statically, it must wait for main(int, char**) to
115  /// be initialized, then call the appropriate function to set this.
116  int ArgC;
117  /// @brief ArgC as it was passed into Main.
118  /// @details This cannot be set statically, it must wait for main(int, char**) to
119  /// be initialized, then call the appropriate function to set this.
120  char** ArgV;
121 
122  /// @internal
123  /// @brief Adds an asset group name to the list of known AssetGroups.
124  void AddAssetGroupName(String Name);
125  public:
126  /// @brief Class constructor.
127  /// @details Standard manager constructor.
128  /// @param EngineDataPath The directory for engine specific data.
129  /// @param ArchiveType The name of the type of archive at this path.
130  /// @param ArgCount How many arguments will be passed in ArgVars. Defaults to 0
131  /// @param ArgVars A pointer to an array, with ArgCount elements, of char* which point to null terminated c strings. Defaults to NULL.
132  ResourceManager(const String& EngineDataPath = ".", const ArchiveType ArchType = AT_FileSystem, int ArgCount=0, char** ArgVars=NULL);
133  /// @brief XML constructor.
134  /// @param XMLNode The node of the xml document to construct from.
135  ResourceManager(XML::Node& XMLNode);
136  /// @details Class Destructor.
137  virtual ~ResourceManager();
138 
139  /// @brief Store the Main arguments for later use.
140  /// @param ArgCount How many arguments will be passed in ArgVars.
141  /// @param ArgVars A pointer to an array, with ArgCount elements, of char* which point to null terminated c strings.
142  void SetMainArgs(int ArgCount, char** ArgVars);
143 
144  ///////////////////////////////////////////////////////////////////////////////
145  // Directory/Path Management
146 
147  /// @brief Creates a single new directory.
148  /// @remarks This function will only create the directory specified at the end of the path.
149  /// @param DirectoryPath The path for the newly created directory.
150  /// @return Returns true if the directory was created, false in the case of a non-critical error.
151  static bool CreateDirectory(const String& DirectoryPath);
152  /// @brief Checks to see if the given path exists and if it is a folder.
153  /// @param DirectoryPath A String containing the path to test.
154  /// @return True if the item indicated by DirectoryPath exists and it is a directory, false if it does not exist or exists but is a file.
155  /// @throws On Error this might throw a Mezzanine::IOException with detail about why it failed
156  static bool DoesDirectoryExist(const String& DirectoryPath);
157  /// @brief Remove an empty directory.
158  /// @param DirectoryPath Directory to remove.
159  /// @throws On Error this might throw a Mezzanine::IOException with details about why it failed.
160  static void RemoveDirectory(const String& DirectoryPath);
161 
162  /// @brief Get the directory portion of a string
163  /// @param FileName A whole path and filename
164  /// @return If passed "/a/b/c.txt" or "c:\windirs\crash.exe" this will return "/a/b/" or "c:\windirs\"
165  static String DirName(const String& FileName);
166  /// @brief Get the filename portion of a string
167  /// @param FileName A whole path and filename
168  /// @return If passed "/a/b/c.txt" or "c:\windirs\crash.exe" this will return "c.txt" or "crash.exe"
169  static String BaseName(const String& FileName);
170 
171  /// @brief Get the character used to separate directories
172  /// @return Backslash '\' on windows and Forward slash '/' on other operating systems.
173  static char GetDirectorySeparator();
174  /// @brief Get the character used to separate entries in the system PATH
175  /// @return Semicolon ';' on windows and Forward slash ':' on other operating systems.
176  static char GetPathSeparator();
177 
178  /// @brief Get the $PATH or %PATH% split and order for easy checking of how the OS does it.
179  /// @param PATH Defaults to the PATH environment variable. But any value like a system path will be split the return of GetPathSeparator().
180  /// @return A collection of directories that this system will for executables in the order they will be checked.
181  static StringVector GetSystemPATH(const String& PATH = String(getenv("PATH")));
182  /// @brief Search the system path the same way most systems do to find an executable.
183  /// @param ExecutableName The executable to look for.
184  /// @return If the executable is not found "" is returned otherwise the first directory in the PATH containing it is returned.
185  /// @warning This function is case sensitive and not all operating systems are.
186  /// @todo Add support for extension handling on windows. "cmd" should find "cmd.exe" in system32, but currently "cmd.exe" needs to be searched
187  static String Which(String ExecutableName);
188 
189  /// @brief Attempt to get the executable directory from the a set of variables like those passed into Main.
190  /// @details This is the fastest way to get the Executable location, but might not work on all platforms.
191  /// @param ArgCount How many arguments will be passed in ArgVars.
192  /// @param ArgVars A pointer to an array, with ArgCount elements, of char* which point to null terminated c strings.
193  /// @warning If you pass bogus arguments to this bad things can and will happen. Infinite loops, segfaults etc... Just pass what main gives you
194  /// @warning Not all system provide all the needed information to determine the executable directory
195  /// @return If a whole path is present in ArgVars[0] this returns the directory part of that path, if this uses the executable file this returns '.', otherwise this with return "" indicating it is not usable.
196  static String GetExecutableDirFromArg(int ArgCount, char** ArgVars);
197  /// @brief Uses the main parameters stored on an instance of Mezzanine::ResourceManager to attempt determine executable directory
198  /// @return Either a valid Path, '.' if the working dir is likely correct or "" if nothing could be determined.
199  String GetExecutableDirFromArg() const;
200  /// @brief Used a system call to get the curent Directory the executable is in. This make an external system call and is likely slower than GetExecutableDirFromArg
201  /// @return This will return the current path this executable is stored in.
202  static String GetExecutableDirFromSystem();
203  /// @brief Get the Path to the current executable, fast from Args if Possible or from a system call otherwise.
204  /// @param ArgCount How many arguments will be passed in ArgVars.
205  /// @param ArgVars A pointer to an array, with ArgCount elements, of char* which point to null terminated c strings.
206  /// @warning If you pass bogus arguments to this bad things can and will happen. Infinite loops, segfaults etc... Just pass what main gives you
207  /// @warning Not all system provide all the needed information to determine the executable directory
208  /// @return A String containing the path to the current executable.
209  static String GetExecutableDir(int ArgCount, char** ArgVars);
210  /// @brief Get the Path to the current executable, in a fast way if possible.
211  /// @return A String containing the path to the current executable.
212  String GetExecutableDir() const;
213 
214  /// @brief Change directory, to the directory indicated.
215  /// @param ChangeTo The new directory to work from.
216  static void ChangeDirectory(const String& ChangeTo);
217 
218  /// @brief Creates all directories that do not exist in the provided path.
219  /// @param DirectoryPath The path for the newly created directory or directories.
220  /// @return Returns true if all directories were created, false in the case of a non-critical error.
221  bool CreateDirectoryPath(const String& DirectoryPath);
222 
223  /// @brief Get a Listing of the files and subdirectories in a directory.
224  /// @details This follows normal command line conventions, "." is the current directory,
225  /// ".." is the parent directory. To access the file system root you will need to use a
226  /// leading "c:/", "c:\\", or "/" as appropriate for the operating system the software will run on.
227  /// @return This will return a pointer to a set of Strings the caller is responsible for deleting or a null pointer on an error.
228  /// @param Dir The directory to check.
229  static StringSet GetDirContents(const String& Dir = ".");
230 
231  /// @brief Get the working directory as a Mezzanine::String
232  /// @return The Directory the game was called from (not nescessarilly the location of the executable), as a Mezzanine::String
233  static String GetWorkingDirectory();
234  /// @brief Get the pathname where engine data is stored
235  /// @return A String that contains the pathname
236  String GetEngineDataDirectory() const;
237 
238  /// @brief Resolves a string describing one of the platform data paths to the actual path it is.
239  /// @remarks Currently there are only 4 preset path variables, and depending on platform they two or more may go to the same location.
240  /// The valid variables are as follows: LocalAppData, ShareableAppData, CurrentUserData, and CommonUserData. These are not case sensative.
241  /// @param PathVar String containing the name of the path variable.
242  /// @return Returns the actual path of the variable provided.
243  String ResolveDataPathFromString(const String& PathVar);
244  /// @brief Gets the path to the directory intended for game and engine config data that is not meant to be shared.
245  /// @return Returns a string containing the path to the Local Application Data Directory.
246  String GetLocalAppDataDir() const;
247  /// @brief Gets the path to the directory intended for game and engine config data that is allowed to be shared.
248  /// @return Returns a string containing the path to the Shareable Application Data Directory.
249  String GetShareableAppDataDir() const;
250  /// @brief Gets the path to the directory intended for game saves and user profile data for the current user.
251  /// @return Returns a string containing the path to the Current User Data Directory.
252  String GetCurrentUserDataDir() const;
253  /// @brief Gets the path to the directory intended for game saves and user profile data for all users.
254  /// @return Returns a string containing the path to the Common User Data Directory.
255  String GetCommonUserDataDir() const;
256 
257  ///////////////////////////////////////////////////////////////////////////////
258  // Stream Management
259 
260  /// @brief Opens a stream to an asset in an AssetGroup.
261  /// @param AssetName The identity of the asset to be opened (commonly a file name).
262  /// @param AssetGroup The name of the AssetGroup where the Asset can be found.
263  Resource::DataStreamPtr OpenAssetStream(const String& AssetName, const String& AssetGroup);
264 
265  /// @brief Creates a stream from a memory buffer.
266  /// @note The created stream will take ownership of the buffer you provide. If you want it to have a separate buffer then create a copy and pass that in.
267  /// @param Buffer A pointer to the memory to stream from.
268  /// @param BufferSize The size of the provided buffer in bytes.
269  /// @return Returns a @ref CountedPtr to the stream to the provided buffer.
270  Resource::DataStreamPtr CreateDataStream(void* Buffer, const UInt32 BufferSize);
271  /// @brief Creates a named stream from a memory buffer.
272  /// @note The created stream will take ownership of the buffer you provide. If you want it to have a separate buffer then create a copy and pass that in.
273  /// @param AssetName The name to be given to the created stream.
274  /// @param Buffer A pointer to the memory to stream from.
275  /// @param BufferSize The size of the provided buffer in bytes.
276  /// @return Returns a @ref CountedPtr to the stream to the provided buffer.
277  Resource::DataStreamPtr CreateDataStream(const String& AssetName, void* Buffer, const UInt32 BufferSize);
278  /// @brief Creates a named stream from a memory buffer and adds it to the named AssetGroup.
279  /// @note The created stream will take ownership of the buffer you provide. If you want it to have a separate buffer then create a copy and pass that in.
280  /// @param AssetName The name to be given to the created stream.
281  /// @param AssetGroup The name of the AssetGroup this stream will be added to.
282  /// @param Buffer A pointer to the memory to stream from.
283  /// @param BufferSize The size of the provided buffer in bytes.
284  /// @return Returns a @ref CountedPtr to the stream to the provided buffer.
285  Resource::DataStreamPtr CreateDataStream(const String& AssetName, const String& AssetGroup, void* Buffer, const UInt32 BufferSize);
286 
287  ///////////////////////////////////////////////////////////////////////////////
288  // AssetGroup Management
289 
290  /// @brief Adds a location for graphical resources.
291  /// @details This function will add a location on the disk to find files needed to create and
292  /// manipulate graphical objects. Once an asset is added it must be initalized using
293  /// ResourceManager::InitResourceGroup(String Group).
294  /// @param Location The location on the file system the asset can be found.
295  /// @param Type The kind of file system the location can be found in. @n
296  /// Options are: filesystem, zip.
297  /// @param Group The name of the group the resources at this location belong to. If the group does not exist it will be created.
298  /// @param Recursive Whether or not to search sub-directories.
299  void AddAssetLocation(const String& Location, const ArchiveType Type, const String& Group, const bool Recursive = false);
300  /// @brief Creates an asset group.
301  /// @param GroupName The name to be given to the created asset group.
302  void CreateAssetGroup(const String& GroupName);
303  /// @brief Destroys an asset group, unloading all of it's resources.
304  /// @param GroupName The name of the asset group to destroy.
305  void DestroyAssetGroup(const String& GroupName);
306  /// @brief Prepares the asset for use.
307  /// @details This function can be thought of as a preloader. This will prepare the defined
308  /// asset located on the disk for use.
309  /// @param Name Name of the file/asset to be 'prepared'.
310  /// @param Type The type of asset that the file is. @n
311  /// Options are: Font, GpuProgram, HighLevelGpuProgram, Material, Mesh, Skeleton, Texture.
312  /// @param Group Name of the group the asset belongs to.
313  void DeclareAsset(const String& Name, const String& Type, const String& Group);
314  /// @brief Makes a asset group ready to use.
315  /// @details After adding all of your assets and declaring them as nessessary, this function
316  /// is the final step. After calling this function any and all assets within the defined group
317  /// will be ready to use. Do not initialize any more groups then you need to however, as that will
318  /// take up memory and drop performance.
319  /// @param Name Name of the asset group.
320  void InitAssetGroup(const String& Name);
321 
322  ///////////////////////////////////////////////////////////////////////////////
323  // Asset Query
324 
325  /// @brief Gets the actual path to an asset.
326  /// @note This function currently only returns the first match, and doesn't check for multiple matches.
327  /// @param FileName The name of the file to search for.
328  /// @param Group The asset group to search in for the file.
329  /// @return Returns a string containing the path to the file.
330  String GetAssetPath(const String& FileName, const String& Group);
331 
332  ///////////////////////////////////////////////////////////////////////////////
333  // Utility
334 
335  /// @brief Gets the dot-and-extention of this platforms plugins.
336  /// @return Returns the platform appropriate extention for plugin files.
337  String GetPluginExtension() const;
338  /// @brief Get a stream to read from the specified file.
339  /// @details The returned ResourceInputStream is the Caller's responsibility to deal with. If it is not deleted it is a memory leak.
340  /// @param FileName The name of the File you want to stream data from.
341  /// @return An derivative of std::istream a ResourceInputStream that will pull it's data from the desired resource.
342  ResourceInputStream* GetResourceStream(const String& FileName);
343 
344  /// @copydoc ManagerBase::Initialize()
345  virtual void Initialize();
346  /// @copydoc ManagerBase::Deinitialize()
347  virtual void Deinitialize();
348 
349  /// @brief Gets a string that describes an @ref ArchiveType.
350  /// @param ArchType A @ref ArchiveType That you want to log or pass to Ogre, or just need a @ref String that represents it.
351  /// @return A String that represents the @ref ArchiveType passed.
352  static String GetStringFromArchiveType(const Mezzanine::ArchiveType ArchType);
353  /// @brief Gets an @ref ArchiveType from a string.
354  /// @param FromString The string to be converted to an archive type.
355  /// @return Returns a @ref ArchiveType corresponding to the string provided, or AT_Invalid if it is invalid.
356  static ArchiveType GetArchiveTypeFromString(const String& FromString);
357 
358  ///////////////////////////////////////////////////////////////////////////////
359  // Type Identifier Methods
360 
361  /// @copydoc ManagerBase::GetInterfaceType()
362  virtual ManagerType GetInterfaceType() const;
363  /// @copydoc ManagerBase::GetImplementationTypeName()
364  virtual String GetImplementationTypeName() const;
365  };//ResourceManager
366 
367  ///////////////////////////////////////////////////////////////////////////////
368  /// @class DefaultResourceManagerFactory
369  /// @headerfile resourcemanager.h
370  /// @brief A factory responsible for the creation and destruction of the default resourcemanager.
371  ///////////////////////////////////////
373  {
374  public:
375  /// @brief Class constructor.
377  /// @brief Class destructor.
379 
380  /// @copydoc ManagerFactory::GetManagerTypeName()
381  String GetManagerTypeName() const;
382 
383  /// @copydoc ManagerFactory::CreateManager(NameValuePairList&)
384  ManagerBase* CreateManager(NameValuePairList& Params);
385  /// @copydoc ManagerFactory::CreateManager(XML::Node&)
386  ManagerBase* CreateManager(XML::Node& XMLNode);
387  /// @copydoc ManagerFactory::DestroyManager(ManagerBase*)
388  void DestroyManager(ManagerBase* ToBeDestroyed);
389  };//DefaultResourceManagerFactory
390 }//Mezzanine
391 
392 #endif