2 #include <msp/core/algorithm.h>
3 #include "collection.h"
10 Collection::Collection():
14 Collection::~Collection()
16 for(CollectionItemTypeBase *t: types)
20 void Collection::add_var(const string &name, const CollectionItemTypeBase *type, const Variant &var)
22 insert_unique(items, name, var);
26 type->notify_item(name, var);
30 remove_existing(items, name);
35 const Variant &Collection::get_var(const string &name, const CollectionItemTypeBase *type)
37 const Variant *var = find_var(name, type);
41 throw key_error(name);
44 const Variant *Collection::find_var(const string &name, const CollectionItemTypeBase *type)
46 ItemMap::iterator i = items.find(name);
53 if(type->can_create())
55 type->create_item(*this, name);
56 loaded = items.count(name);
58 for(auto j=sources.begin(); (!loaded && j!=sources.end()); ++j)
60 (*j)->load(*this, *type, name);
61 loaded = items.count(name);
63 if(!loaded && fallback)
64 if(CollectionItemTypeBase *fb_type = fallback->get_type(*type))
65 if(fallback->get_status(name, *fb_type))
66 return fallback->find_var(name, fb_type);
70 return (i!=items.end() ? &i->second : 0);
73 void Collection::gather_items(vector<const Variant *> *vars, list<string> *names, const CollectionItemTypeBase &type, bool include_sources) const
75 for(const auto &kvp: items)
76 if(type.check_item_type(kvp.second))
79 vars->push_back(&kvp.second);
81 names->push_back(kvp.first);
84 if(include_sources && names)
85 gather_names_from_sources(*names, type);
88 unsigned Collection::get_status(const string &name, const CollectionItemTypeBase &type) const
90 ItemMap::const_iterator i = items.find(name);
93 auto j = find_if(sources, [&name, &type](const CollectionSource *s){ return s->is_loadable(type, name); });
97 if(CollectionItemTypeBase *fb_type = fallback->get_type(type))
98 return fallback->get_status(name, *fb_type);
102 return type.check_item_type(i->second);
105 CollectionItemTypeBase *Collection::get_type(const CollectionItemTypeBase &type) const
107 for(CollectionItemTypeBase *t: types)
108 if(t->is_same_type(type))
113 CollectionItemTypeBase *Collection::get_type_for_item(const Variant &var) const
115 for(CollectionItemTypeBase *t: types)
116 if(t->check_item_type(var))
121 void Collection::add_source(const CollectionSource &s)
123 sources.push_back(&s);
126 IO::Seekable *Collection::open_raw(const string &name) const
128 for(const CollectionSource *s: sources)
129 if(IO::Seekable *io = s->open(name))
135 void Collection::gather_names_from_sources(list<string> &names, const CollectionItemTypeBase &type) const
137 set<string> new_names;
138 for(const CollectionSource *s: sources)
139 for(const string &n: s->get_names(type))
142 names.insert(names.end(), new_names.begin(), new_names.end());
145 void Collection::load_items_from_sources(const CollectionItemTypeBase &type)
147 for(const CollectionSource *s: sources)
148 for(const string &n: s->get_names(type))
152 if(type.can_create())
154 type.create_item(*this, n);
155 loaded = items.count(n);
158 s->load(*this, type, n);
162 void Collection::set_fallback(Collection *f)
168 Collection::Loader::Loader(Collection &c):
171 for(const CollectionItemTypeBase *t: coll.types)
172 t->add_to_loader(*this);
176 CollectionItemTypeBase::~CollectionItemTypeBase()
178 for(ExtractorBase *e: extractors)
182 void CollectionItemTypeBase::set_keyword(const string &k)
189 void CollectionItemTypeBase::add_suffix(const string &s)
191 suffixes.push_back(s);
194 bool CollectionItemTypeBase::match_name(const string &name) const
196 for(const string &s: suffixes)
197 if(name.size()>s.size() && !name.compare(name.size()-s.size(), string::npos, s))
202 } // namespace DataFile