1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
19 #include "nel/misc/file.h"
20 #include "nel/misc/path.h"
21 #include "nel/misc/async_file_manager.h"
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();
54 // ***************************************************************************
56 void CAsyncFileManager::terminate ()
58 if (_Instance
!= NULL
)
60 INelContext::getInstance().releaseSingletonPointer("CAsyncFileManager", _Instance
);
67 void CAsyncFileManager::addLoadTask(IRunnable
*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
87 rTaskQueue
.erase (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 ();
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())
119 CMeshLoad *pML = dynamic_cast<CMeshLoad*>(pR);
122 if (pML->MeshName == sMeshName)
124 // Delete mesh load task
126 rTaskQueue.erase (it);
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
);
186 // Delete signal task
188 rTaskQueue
.erase (it
);
196 // ***************************************************************************
198 // ***************************************************************************
200 // ***************************************************************************
201 CAsyncFileManager::CFileLoad::CFileLoad (const std::string
& sFileName
, uint8
**ppFile
)
203 _FileName
= sFileName
;
207 // ***************************************************************************
208 void CAsyncFileManager::CFileLoad::run (void)
210 FILE *f
= nlfopen (_FileName
, "rb");
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());
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 // ***************************************************************************
236 // ***************************************************************************
238 // ***************************************************************************
239 CAsyncFileManager::CMultipleFileLoad::CMultipleFileLoad (const std::vector
<std::string
> &vFileNames
,
240 const std::vector
<uint8
**> &vPtrs
)
242 _FileNames
= vFileNames
;
246 // ***************************************************************************
247 void CAsyncFileManager::CMultipleFileLoad::run (void)
249 for (uint32 i
= 0; i
< _FileNames
.size(); ++i
)
251 FILE *f
= nlfopen (_FileNames
[i
], "rb");
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());
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 (";
276 for (i
=0; i
<_FileNames
.size (); i
++)
280 result
+= _FileNames
[i
];
284 // ***************************************************************************
286 // ***************************************************************************
288 // ***************************************************************************
289 CAsyncFileManager::CSignal::CSignal (bool *pSgn
)
295 // ***************************************************************************
296 void CAsyncFileManager::CSignal::run (void)
301 // ***************************************************************************
302 void CAsyncFileManager::CSignal::getName (std::string
&result
) const