2 #include <msp/core/algorithm.h>
3 #include "collection.h"
10 Collection::~Collection()
12 for(CollectionItemTypeBase *t: types)
16 void Collection::add_var(const string &name, const CollectionItemTypeBase *type, const Variant &var)
18 insert_unique(items, name, var);
22 type->notify_item(name, var);
26 remove_existing(items, name);
31 const Variant &Collection::get_var(const string &name, const CollectionItemTypeBase *type)
33 const Variant *var = find_var(name, type);
37 throw key_error(name);
40 const Variant *Collection::find_var(const string &name, const CollectionItemTypeBase *type)
42 ItemMap::iterator i = items.find(name);
49 if(type->can_create())
51 type->create_item(*this, name);
52 loaded = items.count(name);
54 for(auto j=sources.begin(); (!loaded && j!=sources.end()); ++j)
56 (*j)->load(*this, *type, name);
57 loaded = items.count(name);
59 if(!loaded && fallback)
60 if(CollectionItemTypeBase *fb_type = fallback->get_type(*type))
61 if(fallback->get_status(name, *fb_type))
62 return fallback->find_var(name, fb_type);
66 return (i!=items.end() ? &i->second : nullptr);
69 void Collection::gather_items(vector<const Variant *> *vars, list<string> *names, const CollectionItemTypeBase &type, bool include_sources) const
71 for(const auto &kvp: items)
72 if(type.check_item_type(kvp.second))
75 vars->push_back(&kvp.second);
77 names->push_back(kvp.first);
80 if(include_sources && names)
81 gather_names_from_sources(*names, type);
84 unsigned Collection::get_status(const string &name, const CollectionItemTypeBase &type) const
86 ItemMap::const_iterator i = items.find(name);
89 auto j = find_if(sources, [&name, &type](const CollectionSource *s){ return s->is_loadable(type, name); });
93 if(CollectionItemTypeBase *fb_type = fallback->get_type(type))
94 return fallback->get_status(name, *fb_type);
98 return type.check_item_type(i->second);
101 CollectionItemTypeBase *Collection::get_type(const CollectionItemTypeBase &type) const
103 for(CollectionItemTypeBase *t: types)
104 if(t->is_same_type(type))
109 CollectionItemTypeBase *Collection::get_type_for_item(const Variant &var) const
111 for(CollectionItemTypeBase *t: types)
112 if(t->check_item_type(var))
117 void Collection::add_source(const CollectionSource &s)
119 sources.push_back(&s);
122 IO::Seekable *Collection::open_raw(const string &name) const
124 for(const CollectionSource *s: sources)
125 if(IO::Seekable *io = s->open(name))
131 void Collection::gather_names_from_sources(list<string> &names, const CollectionItemTypeBase &type) const
133 set<string> new_names;
134 for(const CollectionSource *s: sources)
135 for(const string &n: s->get_names(type))
138 names.insert(names.end(), new_names.begin(), new_names.end());
141 void Collection::load_items_from_sources(const CollectionItemTypeBase &type)
143 for(const CollectionSource *s: sources)
144 for(const string &n: s->get_names(type))
148 if(type.can_create())
150 type.create_item(*this, n);
151 loaded = items.count(n);
154 s->load(*this, type, n);
158 void Collection::set_fallback(Collection *f)
164 Collection::Loader::Loader(Collection &c):
167 for(const CollectionItemTypeBase *t: coll.types)
168 t->add_to_loader(*this);
172 CollectionItemTypeBase::~CollectionItemTypeBase()
174 for(ExtractorBase *e: extractors)
178 void CollectionItemTypeBase::set_keyword(const string &k)
185 void CollectionItemTypeBase::add_suffix(const string &s)
187 suffixes.push_back(s);
190 bool CollectionItemTypeBase::match_name(const string &name) const
192 for(const string &s: suffixes)
193 if(name.size()>s.size() && !name.compare(name.size()-s.size(), string::npos, s))
198 } // namespace DataFile