MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
asynchronousfileloadingworkunit.h
Go to the documentation of this file.
1 // The DAGFrameScheduler is a Multi-Threaded lock free and wait free scheduling library.
2 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
3 /* This file is part of The DAGFrameScheduler.
4 
5  The DAGFrameScheduler is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  The DAGFrameScheduler is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with The DAGFrameScheduler. If not, see <http://www.gnu.org/licenses/>.
17 */
18 /* The original authors have included a copy of the license specified above in the
19  'doc' folder. See 'gpl.txt'
20 */
21 /* We welcome the use of the DAGFrameScheduler to anyone, including companies who wish to
22  Build professional software and charge for their product.
23 
24  However there are some practical restrictions, so if your project involves
25  any of the following you should contact us and we will try to work something
26  out:
27  - DRM or Copy Protection of any kind(except Copyrights)
28  - Software Patents You Do Not Wish to Freely License
29  - Any Kind of Linking to Non-GPL licensed Works
30  - Are Currently In Violation of Another Copyright Holder's GPL License
31  - If You want to change our code and not add a few hundred MB of stuff to
32  your distribution
33 
34  These and other limitations could cause serious legal problems if you ignore
35  them, so it is best to simply contact us or the Free Software Foundation, if
36  you have any questions.
37 
38  Joseph Toppi - toppij@gmail.com
39  John Blackwood - makoenergy02@gmail.com
40 */
41 #ifndef _asynchronousfileloadingworkunit_h
42 #define _asynchronousfileloadingworkunit_h
43 
44 #if !defined(SWIG) || defined(SWIG_THREADING) // Do not read when in swig and not in the threading module
45 #include "asynchronousworkunit.h"
46 #endif
47 
48 /// @file
49 /// @brief The declaration of the @ref Mezzanine::Threading::AsynchronousFileLoadWorkUnit "AsynchronousFileLoadWorkUnit" a workunit that loads a listing of files asynchronously.
50 namespace Mezzanine
51 {
52  namespace Threading
53  {
54 #ifndef SWIG
55  /// @brief An Internal helper function for the @ref AsynchronousFileLoadWorkUnit. This is the function that AsynchronousFileLoadWorkUnit instances will use to load data.
56  /// @details There is a 1 to 1 relationship between this function and its associated @ref Mezzanine::Threading::AsynchronousFileLoadWorkUnit "AsynchronousFileLoadWorkUnit".
57  /// This is the function run in another thread to allow loading asynchrously.
58  /// @param WU A pointer to the @ref Mezzanine::Threading::AsynchronousFileLoadWorkUnit "AsynchronousFileLoadWorkUnit" that is passed to the asynchronous thread to be used as metadata.
59  void ThreadLoading(void* WU);
60 
61  /// @brief A simple in memory representation of a file.
63  {
64  public:
65  /// @brief How big is the file in bytes?
67 
68  /// @brief A pointer to a block of memory as it was loaded raw from the file.
70 
71  /// @brief Constructor
72  /// @details Allocates space of the amount passed. In the @ref Mezzanine::Threading::AsynchronousFileLoadWorkUnit "AsynchronousFileLoadWorkUnit"
73  /// this is the size of the file to be loaded.
74  /// @param BufferSize The size of the buffer to allocate.
75  RawFile(const MaxInt BufferSize) : Size(BufferSize)
76  { Data = new UInt8[BufferSize]; }
77 
78  /// @brief De-allocates the memory for the file. This make deleting Data manually a bad idea.
80  {
81  if(Data)
82  { delete[] Data; }
83  }
84 
85  private:
86  /// @brief Copying this class is a bad idea, private copy constructor
87  RawFile(RawFile&) {}
88 
89  /// @brief Assigning this class is bad, private operator=.
90  /// @param Unused Like it says it is unused in any real sense, it is returned to prevent compiler warnings.
91  /// @return Returns *this.
92  RawFile& operator=(RawFile& Unused) { return Unused; }
93  };//RawFile
94 #endif
95 
96  /// @brief This is intended to load files asynchronously and continue doing so whether or not other the @ref FrameScheduler is running or paused.
97  /// @details The goal is to trigger lower level mechanisms to use DMA to load directly without CPU intervention. In some operating systems this
98  /// is handled in the standard library, and in others special mechanisms must be used to make this happen. The current state of this allows
99  /// testing to determine how good automatic mechanisms work.
101  {
102 #ifndef SWIG
103  /// @cond false
104  // If only there was a way to pass member function to the thread constructor.
105  friend void ThreadLoading(void* WU);
106  /// @endcond
107 #endif
108  protected:
109  /// @brief The names of the files this batch of loading will retrieve.
110  std::vector<String> Filenames;
111 
112  /// @brief Used to make referencing the the type of @ref FilesRaw easier.
113  typedef std::vector<
114  RawFile*
116 
117  /// @brief The contents of the files once they have been loaded. No partial files will exists here, either the whole file is added or nothing is added.
119 
120  /// @brief This is either 0 or the other thread that is loading.
122 
123  /// @brief This stores the current RunningState.
125 
126  public:
127  /// @brief Default constructor.
129 
130  /// @brief Destructor, deletes all loaded files.
131  virtual ~AsynchronousFileLoadWorkUnit();
132 
133  /// @brief Begin loading a list of files based on their names.
134  /// @param Filenames_ A vector of Strings that correspond to either relative or absolute filenames that will be loaded.
135  /// @details When the file is loaded its contents are placed in a @ref RawFile and can be retrieved with @ref GetFile
136  /// or @ref GetFile member functions.
137  /// @n @n
138  /// This starts by clearing the previous list of loaded files. If that list has not been deleted then
139  /// this will cause a memory leak. Use @ref DeleteLoadedFiles to clear this list or copy all the pointers elsewhere before
140  /// calling this and delete them manually at your convience. When this work unit is destroyed it deletes any loaded files from
141  /// the last call of this method.
142  /// @n @n
143  /// If this is called while it is loading files the behavior is undefined, most likely it will crash or fail silently, either
144  /// way no good can come from it. Use @ref IsWorkDone to see if the work is @ref Complete "Complete". If the work is complete
145  /// then this can be called after any call to this class's @ref DoWork member function.
146  /// @warning This can leak memory if not used in conjuction with memory management or @ref DeleteLoadedFiles and read the details.
147  /// @warning This can fail in horrible ways if called twice without waiting for the first call to finish, use @ref IsWorkDone and read the details.
148  /// @return This returns @ref Starting "Starting" when loading is successful started and who knows what it returns if it fails, likely a segfault or GPF.
149  RunningState BeginLoading(const std::vector<String>& Filenames_);
150 
151  /// @brief This checks if Asynchronous loading thread has completed and if so it cleans up that threads' resources.
152  virtual void DoWork(DefaultThreadSpecificStorage::Type&);
153 
154  /// @brief Get the @ref RunningState of the file loading
155  /// @details This can return any @ref RunningState and the meaning applies to the current state of the files being loaded.
156  /// - @ref NotStarted "NotStarted" - Either @ref BeginLoading has not been called or it has been called and has not progressed to the point where it sets this. Not useful for making logical decisions without knowledge of how many times @ref BeginLoading has been called.
157  /// - @ref Starting "Starting" - This is returned from @ref BeginLoading is success conditions, and is never returned from this.
158  /// - @ref Running "Running" - This means that the loading thread has started but not yet completed.
159  /// - @ref Complete "Complete" - The loading thread has completed its work, and new loading can definitely begin after the next call to @ref DoWork method.
160  /// - @ref Failed "Failed" - If somekind of recoverable error occured, this will be returned, there are no guarantees about the state of the loaded files.
161  /// @return The running state as of the time of this call, though it is subject to immediate thread unsafe change.
162  virtual RunningState IsWorkDone();
163 
164  /// @brief Get a loaded @ref RawFile in linear time.
165  /// @details This searches the list of files names to determine the index of the filename then calls @ref GetFile "GetFile".
166  /// @param FileName The file to retrieve.
167  /// @return A pointer to a @ref RawFile or 0 if it cannot be retrieved for any reason.
168  RawFile* GetFile(const String& FileName) const;
169 
170  /// @brief Retrieve a pointer to file contents in constant time.
171  /// @param Index The index of the File Name when it was passed into @ref BeginLoading "BeginLoading".
172  /// @return This returns a null pointer if the correct @ref RawFile cannot be retrieved, otherwise a pointer to the @ref RawFile with index corresponing to the index of a passed in filename is returned.
173  /// @warning Do no call this before @ref IsWorkDone() indicates that the work is @ref Complete "Complete". These memory addresses are subject to change until all loading is complete.
174  RawFile* GetFile(const Whole& Index) const;
175 
176  /// @brief This deletes all the loaded files from the last call of @ref BeginLoading "BeginLoading" .
177  void DeleteLoadedFiles();
178  };//AsynchronousFileLoadWorkUnit
179  } // \Threading
180 }// \Mezzanine
181 
182 #endif