]> git.tdb.fi Git - libs/datafile.git/blob - source/directorycollection.h
Give DirectoryCollection the ability to add files as future objects
[libs/datafile.git] / source / directorycollection.h
1 #ifndef MSP_DATAFILE_DIRECTORYCOLLECTION_H_
2 #define MSP_DATAFILE_DIRECTORYCOLLECTION_H_
3
4 #include <msp/fs/path.h>
5 #include "collection.h"
6
7 namespace Msp {
8 namespace DataFile {
9
10 /**
11 A Collection that can automatically load items from files in a directory.
12 */
13 class DirectoryCollection: public Collection
14 {
15 private:
16         template<typename T, bool = NeedsCollection<typename T::Loader>::value>
17         class ItemLoader;
18
19         std::list<FS::Path> dirs;
20
21 public:
22         DirectoryCollection();
23
24 protected:
25         void set_directory(const FS::Path &);
26         void add_directory(const FS::Path &);
27
28         /** Examines the names of files in the designated directories and adds any
29         applicable ones as future objects. */
30         void load_names();
31
32         template<typename T>
33         CollectionItemType<T> &add_type()
34         {
35                 return Collection::add_type<T>().creator(&DirectoryCollection::create<T>);
36         }
37
38 private:
39         template<typename T>
40         T *create(const std::string &name)
41         {
42                 FS::Path file;
43                 if(lookup_file(name, file))
44                 {
45                         RefPtr<T> item = new T;
46                         ItemLoader<T> ldr(*item, *this);
47                         IO::BufferedFile in(file.str());
48                         Parser parser(in, file.str());
49                         ldr.load(parser);
50                         return item.release();
51                 }
52                 else
53                         return 0;
54         }
55
56 protected:
57         bool lookup_file(const std::string &, FS::Path &) const;
58 };
59
60 template<typename T>
61 class DirectoryCollection::ItemLoader<T, false>: public T::Loader
62 {
63 public:
64         ItemLoader(T &o, Collection &):
65                 T::Loader(o)
66         { }
67 };
68
69 template<typename T>
70 class DirectoryCollection::ItemLoader<T, true>: public T::Loader
71 {
72 public:
73         ItemLoader(T &o, Collection &c):
74                 T::Loader(o, dynamic_cast<typename T::Loader::Collection &>(c))
75         { }
76 };
77
78 } // namespace DataFile
79 } // namespace Msp
80
81 #endif