My Project
AssetManager.h
1 #pragma once
2 
3 #include "AssetEntity.h"
4 
5 namespace ParaEngine
6 {
12  template <class IDTYPE, class ClassImpType = IDTYPE, class ETYPE = AssetEntity>
14  {
15  public:
17  typedef std::map<std::string, ETYPE*> AssetItemsNameMap_t;
18  typedef std::map<AssetKey, ETYPE*> AssetItemsSet_t;
19 
20  AssetManager()
21  {
22  static_assert(std::is_convertible<IDTYPE*, AssetEntity*>::value, "Invalid Type for AssetManager!");
23  // since asset manager is kind of singleton pattern, we will always set reference count to 1 during creation.
24  addref();
25  }
26  virtual ~AssetManager()
27  {
28  Cleanup();
29  }
30 
31  ATTRIBUTE_DEFINE_CLASS(AssetManager);
32 
34  virtual IAttributeFields* GetChildAttributeObject(const std::string& sName){
35  return GetByName(sName);
36  };
38  virtual int GetChildAttributeObjectCount(int nColumnIndex = 0) { return (int)m_items.size(); };
40  virtual int GetChildAttributeColumnCount() { return 1; };
41  virtual IAttributeFields* GetChildAttributeObject(int nRowIndex, int nColumnIndex = 0){
42  if (nRowIndex < (int)m_items.size())
43  {
44  auto iter = m_items.begin();
45  std::advance(iter, nRowIndex);
46  return iter->second;
47  }
48  return NULL;
49  }
50 
51  inline static MyType_t& GetInstance() {
52  static MyType_t s_instance;
53  return s_instance;
54  }
55 
56  virtual const std::string& GetIdentifier() {
57  return m_sName;
58  }
59  virtual void SetIdentifier(const std::string& sName){
60  m_sName = sName;
61  }
62 
67  virtual void Cleanup()
68  {
70  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
71  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP)
72  {
73 #ifdef _DEBUG
74  ETYPE* pAsset =itCurCP->second;
75  if(pAsset->GetRefCount()>1){
76  OUTPUT_LOG("warning: asset <%s> exits with ref %d\n", pAsset->m_key.c_str(), pAsset->GetRefCount()-1);
77  }
78 #endif
79  // normally, it should have 0 reference count at this place. And a delete this operation is performed.
80  itCurCP->second->Release();
81 
82  // force deletion regardless of reference count.
83  //(*itCurCP)->Cleanup();
84  //delete ((IDTYPE*)(*itCurCP));
85  }
86  m_items.clear();
87 
88  // clean up named references
89  m_names.clear();
90 
91  m_lowercase_item_maps.clear();
92  }
93 
97  inline void GetLowerCaseString(std::string& outNameLowered, const AssetKey& key){
98  const char A = (char)'A';
99  const char Z = (char)'Z';
100  const char diff = (char)'a' - A;
101  int nLen = (int)key.size();
102  outNameLowered = key;
103  char c;
104  for (int i=0; i<nLen; ++i)
105  {
106  c = key[i];
107  if (c>=A && c<=Z)
108  outNameLowered[i] = c + diff;
109  }
110  }
111 
121  virtual bool DeleteEntity(ETYPE* entity)
122  {
123  // remove from the list
124  const AssetKey& key = entity->GetKey();
125 
126  // remove from lower cased name mapping.
127  std::string sNameLowered;
128  GetLowerCaseString(sNameLowered, key);
129  typename AssetItemsNameMap_t::iterator iter = m_lowercase_item_maps.find(sNameLowered);
130  if( iter != m_lowercase_item_maps.end())
131  {
132  // remove name mapping
133  if(iter->second != entity)
134  {
135  OUTPUT_LOG("warning: DeleteEntity %s with multiple candidates\n", key.c_str());
136  }
137  m_lowercase_item_maps.erase(iter);
138  }
139 
140  // remove anyway
141  typename AssetItemsSet_t::iterator itCur = m_items.find(key);
142  if(itCur!=m_items.end())
143  {
144  m_items.erase(itCur);
145  }
146 
147  // check references
148  if(entity->GetRefCount() > 1)
149  {
150  OUTPUT_LOG("warning: you are deleting an entity %s whose has unreleased external references\n", entity->GetKey().c_str());
151  }
152  // unload anyway.
153  entity->UnloadAsset();
154  // normally, it should have 0 reference count at this place. And a delete this operation is performed.
155  entity->Release();
156 
157  return true;
158  }
159 
166  void DeleteByName(const std::string& name)
167  {
168  typename AssetItemsNameMap_t::iterator iter = m_names.find(name);
169  if( iter != m_names.end())
170  {
171  // delete entity
172  DeleteEntity((*iter).second);
173  // remove name mapping
174  m_names.erase(iter);
175  }
176  }
177 
182  IDTYPE* GetByName(const std::string& name)
183  {
184  typename AssetItemsNameMap_t::iterator iter = m_names.find(name);
185  if( iter != m_names.end())
186  return (IDTYPE*)((*iter).second);
187  else
188  return NULL;
189  }
190 
195  ETYPE* get(const AssetKey& key)
196  {
197  // first search using asset key, if not found, we will search the lower cased AssetKey version.
198  typename AssetItemsSet_t::iterator iter = m_items.find(key);
199  if(iter != m_items.end())
200  {
201  return iter->second;
202  }
203  else
204  {
205  // search in lower cased
206  std::string sNameLowered;
207  GetLowerCaseString(sNameLowered, key);
208  typename AssetItemsNameMap_t::iterator iter1 = m_lowercase_item_maps.find(sNameLowered);
209  if( iter1 != m_lowercase_item_maps.end())
210  {
211  // remove name mapping
212  return iter1->second;
213  }
214 
215  }
216  return NULL;
217  }
218  public:
219 
224  IDTYPE* NewEntity(const AssetKey& key){
225  IDTYPE* pEntity = new ClassImpType(key);
226  return pEntity;
227  }
228 
230  bool AddEntity(const std::string& name, IDTYPE* pEntity)
231  {
232  const AssetKey& key = pEntity->GetKey();
233  ETYPE* pEntityOld = get(key);
234  if (pEntityOld)
235  {
236  if (pEntityOld == pEntity)
237  return true;
238  else
239  {
240  if (!DeleteEntity(pEntityOld))
241  {
242  return false;
243  }
244  }
245  }
246 
247  {
248  if (!name.empty())
249  {
250  // add a named asset reference.
251  m_names[name] = pEntity;
252  }
253  m_items[key] = pEntity;
254  pEntity->addref();
255 
256  // add a lower cased map
257  std::string sNameLowered;
258  GetLowerCaseString(sNameLowered, key);
259  m_lowercase_item_maps[sNameLowered] = pEntity;
260  }
261  return true;
262  }
263 
277  pair<IDTYPE*, bool> CreateEntity(const string& name, const AssetKey& key)
278  {
279  ETYPE* pEntity = get(key);
280  if(pEntity)
281  {
282  if( ! name.empty() )
283  {
286  ETYPE* pOld = GetByName(name);
287  if(pOld == NULL)
288  {
289  // add a named asset reference.
290  m_names[name] = pEntity;
291  }
292  }
294  return pair<IDTYPE*, bool>((IDTYPE*)pEntity, false);
295  }
296  else
297  {
298  pEntity = NewEntity(key);
299  if( ! name.empty() )
300  {
301  // add a named asset reference.
302  m_names[name] = pEntity;
303  }
304  m_items[key] = pEntity;
305  pEntity->addref();
306 
307  // add a lower cased map
308  std::string sNameLowered;
309  GetLowerCaseString(sNameLowered, key);
310  m_lowercase_item_maps[sNameLowered] = pEntity;
311 
312  return pair<IDTYPE*, bool>((IDTYPE*)pEntity, true);
313  }
314  }
315 
316 
320  IDTYPE* GetEntity(const string& name)
321  {
322  return (IDTYPE*)get(name);
323  }
324 
326  void LoadAsset(){
327  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
328  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP)
329  {
330  itCurCP->second->LoadAsset();
331  }
332  }
334  void UnloadAsset(){
335  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
336  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP)
337  {
338  itCurCP->second->UnloadAsset();
339  }
340  }
343  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
344  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP)
345  {
346  itCurCP->second->GarbageCollectMe();
347  }
348  }
349 
355  bool CheckRefresh(const std::string& sEntityName)
356  {
357  ETYPE* pEntity = GetEntity(sEntityName);
358  if(pEntity!=0){
359  pEntity->Refresh();
360  return true;
361  }
362  return false;
363  }
364 
370  virtual int PrintToFile(CParaFile* pOutputFile)
371  {
372  int i=0;
373  if (pOutputFile)
374  {
375  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
376  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP,++i)
377  {
378  pOutputFile->WriteString(itCurCP->second->GetKey());
379  pOutputFile->WriteString("\n");
380  }
381  }
382  return i;
383  }
384 
385  public:
386  virtual void InitDeviceObjects(){
387  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
388  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP)
389  {
390  itCurCP->second->InitDeviceObjects();
391  }
392  };
393  virtual void RestoreDeviceObjects(){
394  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
395  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP)
396  {
397  itCurCP->second->RestoreDeviceObjects();
398  }
399  }
400  virtual void InvalidateDeviceObjects(){
401  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
402  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP)
403  {
404  itCurCP->second->InvalidateDeviceObjects();
405  }
406  }
407  virtual void DeleteDeviceObjects(){
408  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
409  for( itCurCP = m_items.begin(); itCurCP != itEndCP; ++ itCurCP)
410  {
411  itCurCP->second->DeleteDeviceObjects();
412  }
413  }
417  virtual void RendererRecreated(){
418  typename AssetItemsSet_t::iterator itCurCP, itEndCP = m_items.end();
419  for (itCurCP = m_items.begin(); itCurCP != itEndCP; ++itCurCP)
420  {
421  itCurCP->second->RendererRecreated();
422  }
423  }
424  public:
426  std::string m_sName;
430  AssetItemsNameMap_t m_names;
434  AssetItemsSet_t m_items;
438  AssetItemsNameMap_t m_lowercase_item_maps;
439  };
440 }
virtual bool DeleteEntity(ETYPE *entity)
decrease the reference count on the entity, and if it is negative, the asset will be unloaded...
Definition: AssetManager.h:121
void LoadAsset()
initialize all assets created so far to accelerate loading during game play.
Definition: AssetManager.h:326
IDTYPE * GetByName(const std::string &name)
check if there is a object with a specified name, and return the pointer to it.
Definition: AssetManager.h:182
virtual int PrintToFile(CParaFile *pOutputFile)
print all asset file to a given file.
Definition: AssetManager.h:370
void UnloadAsset()
uninitialize all assets created so far to save some memory
Definition: AssetManager.h:334
different physics engine has different winding order.
Definition: EventBinding.h:32
virtual IAttributeFields * GetChildAttributeObject(const std::string &sName)
get attribute by child object.
Definition: AssetManager.h:34
virtual void Cleanup()
delete all asset item from memory.
Definition: AssetManager.h:67
bool CheckRefresh(const std::string &sEntityName)
check if the entity exist, if so call Refresh().
Definition: AssetManager.h:355
AssetManager manages a set of asset entities of a certain type.
Definition: AssetManager.h:13
IDTYPE * GetEntity(const string &name)
get the entity by its entity key name
Definition: AssetManager.h:320
AssetItemsSet_t m_items
A set of all asset entities.
Definition: AssetManager.h:434
AssetItemsNameMap_t m_lowercase_item_maps
mapping from lower cased AssetKey to asset entity.
Definition: AssetManager.h:438
IDTYPE * NewEntity(const AssetKey &key)
just create the entity instance without adding to the manager.
Definition: AssetManager.h:224
virtual int GetChildAttributeColumnCount()
we support multi-dimensional child object.
Definition: AssetManager.h:40
void GarbageCollectAll()
Garbage Collect(free resources of) all unused entity.
Definition: AssetManager.h:342
A common interface for all classes implementing IAttributeFields By implementing this class&#39;s virtual...
Definition: IAttributeFields.h:59
it presents a real or virtual file in ParaEngine.
Definition: ParaFile.h:31
bool AddEntity(const std::string &name, IDTYPE *pEntity)
insert entity to the manager.
Definition: AssetManager.h:230
void DeleteByName(const std::string &name)
delete the object by user specified name.
Definition: AssetManager.h:166
void addref() const
add reference count of the object.
Definition: PERef.h:15
std::string AssetKey
the unique key object for asset entity.
Definition: AssetEntity.h:13
PE_CORE_DECL int WriteString(const string &sStr)
write string to file.
Definition: ParaFile.cpp:1126
std::string m_sName
identifier
Definition: AssetManager.h:426
pair< IDTYPE *, bool > CreateEntity(const string &name, const AssetKey &key)
Create a new entity object and add it to the manager.
Definition: AssetManager.h:277
AssetItemsNameMap_t m_names
human readable name of asset object, which can be used as key to retrieve entity from its manager Int...
Definition: AssetManager.h:430
void GetLowerCaseString(std::string &outNameLowered, const AssetKey &key)
get the lower cased key string.
Definition: AssetManager.h:97
virtual int GetChildAttributeObjectCount(int nColumnIndex=0)
get the number of child objects (row count) in the given column.
Definition: AssetManager.h:38
virtual void RendererRecreated()
callback of listening the event that renderer was recreated on Android/WP8 all opengl related id has ...
Definition: AssetManager.h:417