KrisLibrary  1.0.0
ResourceLibrary.h
1 #ifndef RESOURCE_LIBRARY_H
2 #define RESOURCE_LIBRARY_H
3 
4 #include <KrisLibrary/Logger.h>
5 #include "AnyCollection.h"
6 #include <memory>
7 #include <string>
8 #include <string.h>
9 #include <iostream>
10 #include <sstream>
11 #include <typeinfo>
12 #include <map>
13 #include <vector>
14 
15 class TiXmlElement;
16 
40 {
41  public:
42  ResourceBase();
43  ResourceBase(const std::string& name);
44  ResourceBase(const std::string& name,const std::string& fn);
45  virtual ~ResourceBase() {}
46  virtual bool Load(const std::string& fn);
47  virtual bool Load();
48  virtual bool Save(const std::string& fn);
49  virtual bool Save();
50  virtual bool Load(std::istream& in) { return false; }
51  virtual bool Save(std::ostream& out) { return false; }
52  virtual bool Load(TiXmlElement* in);
53  virtual bool Save(TiXmlElement* out);
54  virtual bool Load(AnyCollection& c);
55  virtual bool Save(AnyCollection& c);
58  virtual const char* Type() const { return typeid(*this).name(); }
61  virtual ResourceBase* Make() { return new ResourceBase; }
64  virtual ResourceBase* Copy() { return new ResourceBase(name,fileName); }
65 
66  std::string name,fileName;
67 };
68 
69 typedef std::shared_ptr<ResourceBase> ResourcePtr;
70 
71 
98 {
99  public:
101  template <class T>
102  void AddType();
104  template <class T>
105  void AddLoader(const std::string& ext);
106 
108  void Clear();
110  bool SaveXml(const std::string& fn);
112  bool LoadXml(const std::string& fn);
114  bool Save(TiXmlElement* e);
116  bool Load(TiXmlElement* e);
118  bool LazyLoadXml(const std::string& fn);
120  bool SaveJSON(std::ostream& s);
122  bool LoadJSON(std::istream& s);
124  bool LazyLoadJSON(std::istream& s);
126  bool Save(AnyCollection& c);
128  bool Load(AnyCollection& c);
130  bool LazyLoad(AnyCollection& c);
132  void AddBaseDirectory(const std::string& dir);
136  void ChangeBaseDirectory(const std::string& dir);
138  bool SaveAll();
140  bool SaveItem(const std::string& name);
142  bool LoadAll(const std::string& dir);
144  bool LazyLoadAll(const std::string& dir);
146  ResourcePtr LoadItem(const std::string& fn);
148  bool ReloadAll();
149 
150  //accessors
151  template <class T>
152  T* Get(const std::string& name,int index);
154  std::vector<ResourcePtr>& Get(const std::string& name);
156  std::vector<ResourcePtr>& GetByType(const std::string& type);
157  template <class T>
158  std::vector<ResourcePtr>& GetByType();
159  template <class T>
160  std::vector<T*> GetPtrsByType();
162  size_t Count(const std::string& name) const;
164  size_t CountByType(const std::string& type) const;
165  template <class T>
166  size_t CountByType() const;
168  std::vector<ResourcePtr> Enumerate() const;
169 
170  //modifiers
171  void Add(const ResourcePtr& resource);
172  bool Erase(const ResourcePtr& resource);
173  bool Erase(const std::string& name,int index=-1);
174 
175  //helpers
176  std::string DefaultFileName(const ResourcePtr& r);
177 
178  typedef std::map<std::string,std::vector<ResourcePtr> > Map;
179  Map knownTypes;
180  Map loaders;
181  Map itemsByName,itemsByType;
182 };
183 
184 
186 template <class T>
187 std::vector<T*> ResourcesByType(std::vector<ResourcePtr>& resources)
188 {
189  std::vector<T*> rtype;
190  for(size_t i=0;i<resources.size();i++) {
191  T* ptr = dynamic_cast<T*>(resources[i].get());
192  if(ptr) rtype.push_back(ptr);
193  }
194  return rtype;
195 }
196 
198 std::vector<ResourcePtr> ResourcesByType(std::vector<ResourcePtr>& resources,const std::string& type);
199 
201 std::vector<std::string> ResourceTypes(const std::vector<ResourcePtr>& resources);
202 
203 
204 
206 template <class T>
207 const char* BasicResourceTypeName() { return typeid(T).name(); }
208 
218 template <class T>
220 {
221  public:
222  BasicResource() {}
223  BasicResource(const T& val) : data(val) {}
224  BasicResource(const T& val,const std::string& name) : ResourceBase(name),data(val) {}
225  BasicResource(const T& val,const std::string& name,const std::string& fileName) : ResourceBase(name,fileName),data(val) {}
226  virtual ~BasicResource() {}
227  virtual bool Load(std::istream& in) {
228  in>>data;
229  if(in.bad()) {
230  return false;
231  }
232  return true;
233  }
234  virtual bool Save(std::ostream& out) {
235  out<<data<<std::endl;
236  return true;
237  }
238  virtual bool Load(const std::string& fn) { return ResourceBase::Load(fn); }
239  virtual bool Load() { return ResourceBase::Load(); }
240  virtual bool Save(const std::string& fn) { return ResourceBase::Save(fn); }
241  virtual bool Save() { return ResourceBase::Save(); }
242  virtual const char* Type() const { return BasicResourceTypeName<T>(); }
243  virtual ResourceBase* Make() { return new BasicResource<T>; }
244  virtual ResourceBase* Copy() { return new BasicResource<T>(data,name,fileName); }
245 
246  T data;
247 };
248 
249 template <> const char* BasicResourceTypeName<int>();
250 template <> const char* BasicResourceTypeName<double>();
251 template <> const char* BasicResourceTypeName<std::string>();
255 
256 
264 {
265  public:
267  CompoundResourceBase(const std::string& name) : ResourceBase(name) {}
268  CompoundResourceBase(const std::string& name,const std::string& fileName) : ResourceBase(name,fileName) {}
269  virtual ~CompoundResourceBase() {}
270 
272  virtual std::vector<std::string> CastTypes() const { return std::vector<std::string>(); }
274  virtual std::vector<std::string> ExtractTypes() const { return SubTypes(); }
276  virtual std::vector<std::string> SubTypes() const { return std::vector<std::string>(); }
277 
279  virtual ResourcePtr Cast(const char* type) { return NULL; }
280 
283  virtual bool Extract(const char* subtype,std::vector<ResourcePtr>& subobjects);
284 
289  virtual bool Pack(std::vector<ResourcePtr>& subobjects,std::string* errorMessage=NULL) { if(errorMessage) *errorMessage = std::string(Type())+"::Pack not implemented"; return false; }
290 
298  virtual bool Unpack(std::vector<ResourcePtr>& subobjects,bool* incomplete=NULL) { return false; }
299 };
300 
305 template <class T>
307 {
308  public:
309  typedef BasicResource<T> BaseType;
310  BasicArrayResource() {}
311  BasicArrayResource(const std::vector<T>& val) : data(val) {}
312  BasicArrayResource(const std::vector<T>& val,const std::string& name) : CompoundResourceBase(name),data(val) {}
313  BasicArrayResource(const std::vector<T>& val,const std::string& name,const std::string& fileName) : CompoundResourceBase(name,fileName),data(val) {}
314  virtual ~BasicArrayResource() {}
315  virtual bool Load(std::istream& in) {
316  size_t n;
317  in>>n;
318  if(in.bad()) return false;
319  data.resize(n);
320  for(size_t i=0;i<n;i++) {
321  in>>data[i];
322  if(in.bad()) return false;
323  }
324  return true;
325  }
326  virtual bool Save(std::ostream& out) {
327  out<<data.size()<<'\t';
328  for(size_t i=0;i<data.size();i++) {
329  out<<data[i];
330  if(i+1!=data.size()) out<<" ";
331  }
332  out<<std::endl;
333  return true;
334  }
335  virtual bool Load(const std::string& fn) { return ResourceBase::Load(fn); }
336  virtual bool Load() { return ResourceBase::Load(); }
337  virtual bool Save(const std::string& fn) { return ResourceBase::Save(fn); }
338  virtual bool Save() { return ResourceBase::Save(); }
339  virtual bool Load(AnyCollection& c) { return c["data"].asvector(data); }
340  virtual bool Save(AnyCollection& c) { c["data"] = data; return true;}
341  virtual const char* Type() const { return BasicResourceTypeName<std::vector<T> >(); }
342  virtual ResourceBase* Make() { return new BasicArrayResource<T>; }
343  virtual ResourceBase* Copy() { return new BasicArrayResource<T>(data,name,fileName); }
344 
345  //CompoundResourceBase methods
346  virtual std::vector<std::string> SubTypes() const { return std::vector<std::string>(1,BasicResourceTypeName<T>()); }
347  virtual bool Extract(const char* subtype,std::vector<ResourcePtr>& subobjects) {
348  if(0==strcmp(subtype,BasicResourceTypeName<T>()))
349  return Unpack(subobjects);
350  return false;
351  }
352  virtual bool Pack(std::vector<ResourcePtr>& subobjects,std::string* errorMessage=NULL) {
353  for(size_t i=0;i<subobjects.size();i++)
354  if(typeid(*subobjects[i]) != typeid(BaseType)) {
355  if(errorMessage) *errorMessage = std::string("Subobject does not have type ")+std::string(BasicResourceTypeName<T>());
356  return false;
357  }
358  data.resize(subobjects.size());
359  for(size_t i=0;i<subobjects.size();i++)
360  data[i] = dynamic_cast<BaseType*>(&*subobjects[i])->data;
361  return true;
362  }
363  virtual bool Unpack(std::vector<ResourcePtr>& subobjects,bool* incomplete=NULL) {
364  subobjects.resize(data.size());
365  for(size_t i=0;i<data.size();i++) {
366  subobjects[i] = std::make_shared<BaseType>(data[i]);
367  std::stringstream ss;
368  ss<<"data["<<i<<"]";
369  subobjects[i]->name = ss.str();
370  }
371  return true;
372  }
373 
374  std::vector<T> data;
375 };
376 
377 template <> const char* BasicResourceTypeName<std::vector<int> >();
378 template <> const char* BasicResourceTypeName<std::vector<double> >();
379 template <> const char* BasicResourceTypeName<std::vector<std::string> >();
383 
384 
389 {
390  public:
391  virtual bool Load(const std::string& fn);
392  virtual bool Save(const std::string& fn);
393  virtual bool Load(AnyCollection& c);
394  virtual bool Save(AnyCollection& c);
395  virtual const char* Type() const { return "ResourceLibrary"; }
396  virtual ResourceBase* Make() { return new ResourceLibraryResource; }
397  virtual ResourceBase* Copy();
398  virtual std::vector<std::string> SubTypes() const;
399  virtual bool Extract(const char* subtype,std::vector<ResourcePtr>& subobjects);
400  virtual bool Pack(std::vector<ResourcePtr>& subobjects,std::string* errorMessage=NULL);
401  virtual bool Unpack(std::vector<ResourcePtr>& subobjects,bool* incomplete=NULL);
402 
403  ResourceLibrary library;
404 };
405 
406 template <class T>
408 {
409  ResourcePtr res(new T);
410  if(knownTypes.count(res->Type()) == 0) {
411  knownTypes[res->Type()].push_back(res);
412  }
413  else {
414  //potential conflict? check raw string
415  if(knownTypes[res->Type()][0]->Type() != res->Type())
416  LOG4CXX_ERROR(KrisLibrary::logger(),"ResourceLibrary: Potential conflict with type "<<res->Type());
417  knownTypes[res->Type()][0] = res;
418  }
419 }
420 
421 template <class T>
422 void ResourceLibrary::AddLoader(const std::string& ext)
423 {
424  AddType<T>();
425  ResourcePtr res(new T);
426  loaders[ext].push_back(res);
427 }
428 
429 template <class T>
430 T* ResourceLibrary::Get(const std::string& name,int index)
431 {
432  std::vector<ResourcePtr>& items=Get(name);
433  if(index < 0 || index > (int)items.size()) return NULL;
434  return dynamic_cast<T*>(items[index].get());
435 }
436 
437 template <class T>
438 std::vector<ResourcePtr>& ResourceLibrary::GetByType()
439 {
440  T temp;
441  return GetByType(temp.Type());
442 }
443 
444 template <class T>
445 std::vector<T*> ResourceLibrary::GetPtrsByType()
446 {
447  std::vector<ResourcePtr>& items = GetByType<T>();
448  std::vector<T*> cast_items(items.size());
449  for(size_t i=0;i<items.size();i++)
450  cast_items[i] = dynamic_cast<T*>(items[i].get());
451  return cast_items;
452 }
453 
454 template <class T>
455 size_t ResourceLibrary::CountByType() const
456 {
457  T temp;
458  return CountByType(temp.Type());
459 }
460 
461 #endif
virtual ResourceBase * Make()
Definition: ResourceLibrary.h:396
A flexible hierarchical collection of AnyValues, which can be easily initialized to contain primitive...
Definition: AnyCollection.h:73
virtual const char * Type() const
Definition: ResourceLibrary.h:242
A basic data type.
Definition: ResourceLibrary.h:219
virtual std::vector< std::string > CastTypes() const
Returns a list of subtypes that can be used in Cast.
Definition: ResourceLibrary.h:272
virtual std::vector< std::string > SubTypes() const
Returns a list of subtypes that will be produced in Unpack.
Definition: ResourceLibrary.h:276
virtual ResourceBase * Make()
Definition: ResourceLibrary.h:342
virtual ResourceBase * Copy()
Definition: ResourceLibrary.h:244
virtual const char * Type() const
Definition: ResourceLibrary.h:395
virtual bool Pack(std::vector< ResourcePtr > &subobjects, std::string *errorMessage=NULL)
Definition: ResourceLibrary.h:289
std::vector< ResourcePtr > & GetByType(const std::string &type)
Get by type.
Definition: ResourceLibrary.cpp:633
A basic array data type.
Definition: ResourceLibrary.h:306
virtual bool Extract(const char *subtype, std::vector< ResourcePtr > &subobjects)
Definition: ResourceLibrary.h:347
virtual ResourceBase * Copy()
Definition: ResourceLibrary.h:343
A generic "resource" that can be saved/loaded to disk.
Definition: ResourceLibrary.h:39
size_t CountByType(const std::string &type) const
Count by type.
Definition: ResourceLibrary.cpp:645
virtual const char * Type() const
Definition: ResourceLibrary.h:341
void AddType()
Adds a new type not associated with a given filename.
Definition: ResourceLibrary.h:407
virtual ResourceBase * Make()
Definition: ResourceLibrary.h:61
virtual ResourcePtr Cast(const char *type)
Definition: ResourceLibrary.h:279
virtual bool Pack(std::vector< ResourcePtr > &subobjects, std::string *errorMessage=NULL)
Definition: ResourceLibrary.h:352
virtual bool Unpack(std::vector< ResourcePtr > &subobjects, bool *incomplete=NULL)
Definition: ResourceLibrary.h:363
void AddLoader(const std::string &ext)
Adds a new type associated with the given file extension ext.
Definition: ResourceLibrary.h:422
virtual ResourceBase * Make()
Definition: ResourceLibrary.h:243
virtual const char * Type() const
Definition: ResourceLibrary.h:58
The logging system used in KrisLibrary.
A resource that is composed of multiple sub-objects, which can themselves be considered resources...
Definition: ResourceLibrary.h:263
virtual std::vector< std::string > ExtractTypes() const
Returns a list of subtypes that can be used in Extract.
Definition: ResourceLibrary.h:274
A resource that contains a ResourceLibrary. Useful for hierarchical resource libraries.
Definition: ResourceLibrary.h:388
virtual bool Unpack(std::vector< ResourcePtr > &subobjects, bool *incomplete=NULL)
Definition: ResourceLibrary.h:298
virtual ResourceBase * Copy()
Definition: ResourceLibrary.h:64
virtual std::vector< std::string > SubTypes() const
Returns a list of subtypes that will be produced in Unpack.
Definition: ResourceLibrary.h:346
Definition: PropertyMap.cpp:9
A collection of resources, which may be loaded/saved as separate files in a directory or inlined into...
Definition: ResourceLibrary.h:97