Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / misc / async_file_manager.cpp
blobe8f6414e48c9f1e519cc070f6f19f1ae71b6b2f7
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program 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 Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "stdmisc.h"
19 #include "nel/misc/file.h"
20 #include "nel/misc/path.h"
21 #include "nel/misc/async_file_manager.h"
24 using namespace std;
26 #ifdef DEBUG_NEW
27 #define new DEBUG_NEW
28 #endif
30 namespace NLMISC
33 //CAsyncFileManager *CAsyncFileManager::_Singleton = NULL;
34 NLMISC_SAFE_SINGLETON_IMPL(CAsyncFileManager);
37 // ***************************************************************************
39 /*CAsyncFileManager::CAsyncFileManager()
43 // ***************************************************************************
45 /*CAsyncFileManager &CAsyncFileManager::getInstance()
47 if (_Singleton == NULL)
49 _Singleton = new CAsyncFileManager();
51 return *_Singleton;
54 // ***************************************************************************
56 void CAsyncFileManager::terminate ()
58 if (_Instance != NULL)
60 INelContext::getInstance().releaseSingletonPointer("CAsyncFileManager", _Instance);
61 delete _Instance;
62 _Instance = NULL;
67 void CAsyncFileManager::addLoadTask(IRunnable *ploadTask)
69 addTask(ploadTask);
72 bool CAsyncFileManager::cancelLoadTask(const CAsyncFileManager::ICancelCallback &callback)
74 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
75 list<CWaitingTask> &rTaskQueue = acces.value ();
76 list<CWaitingTask>::iterator it = rTaskQueue.begin();
78 while (it != rTaskQueue.end())
80 IRunnable *pR = it->Task;
82 // check the task with the cancel callback.
83 if (callback.callback(pR))
85 // Delete the load task
86 delete pR;
87 rTaskQueue.erase (it);
88 return true;
90 ++it;
93 // If not found, the current running task may be the one we want to cancel. Must wait it.
94 // Beware that this code works because of the CSynchronized access we made above (ensure that the
95 // taskmanager will end just the current task async (if any) and won't start an other one.
96 waitCurrentTaskToComplete ();
98 return false;
101 // ***************************************************************************
103 void CAsyncFileManager::loadMesh(const std::string& meshName, IShape **ppShp, IDriver *pDriver)
105 addTask (new CMeshLoad(meshName, ppShp, pDriver));
108 // ***************************************************************************
110 bool CAsyncFileManager::cancelLoadMesh(const std::string& sMeshName)
112 CSynchronized<list<IRunnable *> >::CAccessor acces(&_TaskQueue);
113 list<IRunnable*> &rTaskQueue = acces.value ();
114 list<IRunnable*>::iterator it = rTaskQueue.begin();
116 while (it != rTaskQueue.end())
118 IRunnable *pR = *it;
119 CMeshLoad *pML = dynamic_cast<CMeshLoad*>(pR);
120 if (pML != NULL)
122 if (pML->MeshName == sMeshName)
124 // Delete mesh load task
125 delete pML;
126 rTaskQueue.erase (it);
127 return true;
130 ++it;
132 return false;
135 // ***************************************************************************
137 void CAsyncFileManager::loadIG (const std::string& IGName, CInstanceGroup **ppIG)
139 addTask (new CIGLoad(IGName, ppIG));
142 // ***************************************************************************
144 void CAsyncFileManager::loadIGUser (const std::string& IGName, UInstanceGroup **ppIG)
146 addTask (new CIGLoadUser(IGName, ppIG));
149 // ***************************************************************************
151 void CAsyncFileManager::loadFile (const std::string& sFileName, uint8 **ppFile)
153 addTask (new CFileLoad (sFileName, ppFile));
156 // ***************************************************************************
158 void CAsyncFileManager::loadFiles (const std::vector<std::string> &vFileNames, const std::vector<uint8**> &vPtrs)
160 addTask (new CMultipleFileLoad (vFileNames, vPtrs));
163 // ***************************************************************************
165 void CAsyncFileManager::signal (bool *pSgn)
167 addTask (new CSignal (pSgn));
170 // ***************************************************************************
172 void CAsyncFileManager::cancelSignal (bool *pSgn)
174 CSynchronized<list<CWaitingTask> >::CAccessor acces(&_TaskQueue);
175 list<CWaitingTask> &rTaskQueue = acces.value ();
176 list<CWaitingTask>::iterator it = rTaskQueue.begin();
178 while (it != rTaskQueue.end())
180 IRunnable *pR = it->Task;
181 CSignal *pS = dynamic_cast<CSignal*>(pR);
182 if (pS != NULL)
184 if (pS->Sgn == pSgn)
186 // Delete signal task
187 delete pS;
188 rTaskQueue.erase (it);
189 return;
192 ++it;
196 // ***************************************************************************
197 // FileLoad
198 // ***************************************************************************
200 // ***************************************************************************
201 CAsyncFileManager::CFileLoad::CFileLoad (const std::string& sFileName, uint8 **ppFile)
203 _FileName = sFileName;
204 _ppFile = ppFile;
207 // ***************************************************************************
208 void CAsyncFileManager::CFileLoad::run (void)
210 FILE *f = nlfopen (_FileName, "rb");
211 if (f != NULL)
213 uint32 filesize=CFile::getFileSize (f);
214 uint8 *ptr = new uint8[filesize];
215 if (fread (ptr, filesize, 1, f) != 1)
216 nlwarning("AFM: Couldn't read '%s'", _FileName.c_str());
217 fclose (f);
219 *_ppFile = ptr;
221 else
223 nlwarning ("AFM: Couldn't load '%s'", _FileName.c_str());
224 *_ppFile = (uint8*)-1;
228 // ***************************************************************************
229 void CAsyncFileManager::CFileLoad::getName (std::string &result) const
231 result = "FileLoad (" + _FileName + ")";
234 // ***************************************************************************
235 // MultipleFileLoad
236 // ***************************************************************************
238 // ***************************************************************************
239 CAsyncFileManager::CMultipleFileLoad::CMultipleFileLoad (const std::vector<std::string> &vFileNames,
240 const std::vector<uint8**> &vPtrs)
242 _FileNames = vFileNames;
243 _Ptrs = vPtrs;
246 // ***************************************************************************
247 void CAsyncFileManager::CMultipleFileLoad::run (void)
249 for (uint32 i = 0; i < _FileNames.size(); ++i)
251 FILE *f = nlfopen (_FileNames[i], "rb");
252 if (f != NULL)
254 uint32 filesize=CFile::getFileSize (f);
255 uint8 *ptr = new uint8[filesize];
256 if (fread (ptr, filesize, 1, f) != 1)
257 nlwarning("AFM: Couldn't read '%s'", _FileNames[i].c_str());
258 fclose (f);
260 *_Ptrs[i] = ptr;
262 else
264 nlwarning ("AFM: Couldn't load '%s'", _FileNames[i].c_str());
265 *_Ptrs[i] = (uint8*)-1;
271 // ***************************************************************************
272 void CAsyncFileManager::CMultipleFileLoad::getName (std::string &result) const
274 result = "MultipleFileLoad (";
275 uint i;
276 for (i=0; i<_FileNames.size (); i++)
278 if (i)
279 result += ", ";
280 result += _FileNames[i];
282 result += ")";
284 // ***************************************************************************
285 // Signal
286 // ***************************************************************************
288 // ***************************************************************************
289 CAsyncFileManager::CSignal::CSignal (bool *pSgn)
291 Sgn = pSgn;
292 *Sgn = false;
295 // ***************************************************************************
296 void CAsyncFileManager::CSignal::run (void)
298 *Sgn = true;
301 // ***************************************************************************
302 void CAsyncFileManager::CSignal::getName (std::string &result) const
304 result = "Signal";
307 } // NLMISC