return get_item(items, name);
}
+void Collection::gather_items(list<const Variant *> *vars, list<string> *names, const CollectionItemTypeBase &type, bool include_sources) const
+{
+ for(ItemMap::const_iterator i=items.begin(); i!=items.end(); ++i)
+ if(type.check_item_type(i->second))
+ {
+ if(vars)
+ vars->push_back(&i->second);
+ if(names)
+ names->push_back(i->first);
+ }
+
+ if(include_sources && names)
+ gather_names_from_sources(*names, type);
+}
+
+unsigned Collection::get_status(const string &name, const CollectionItemTypeBase &type) const
+{
+ ItemMap::const_iterator i = items.find(name);
+ if(i==items.end())
+ {
+ for(SourceList::const_iterator j=sources.begin(); j!=sources.end(); ++j)
+ if((*j)->is_loadable(type, name))
+ return 2;
+ return 0;
+ }
+
+ return type.check_item_type(i->second);
+}
+
CollectionItemTypeBase *Collection::get_type_for_item(const Variant &var) const
{
for(TypeList::const_iterator i=types.begin(); i!=types.end(); ++i)
sources.push_back(&s);
}
+void Collection::gather_names_from_sources(list<string> &names, const CollectionItemTypeBase &type) const
+{
+ for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
+ {
+ std::list<std::string> available_names = (*i)->get_names(type);
+ for(std::list<std::string>::iterator j=available_names.begin(); j!=available_names.end(); ++j)
+ if(!items.count(*j))
+ names.push_back(*j);
+ }
+}
+
+void Collection::load_items_from_sources(const CollectionItemTypeBase &type)
+{
+ for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
+ {
+ std::list<std::string> available_names = (*i)->get_names(type);
+ for(std::list<std::string>::iterator j=available_names.begin(); j!=available_names.end(); ++j)
+ if(!items.count(*j))
+ (*i)->load(*this, type, *j);
+ }
+}
+
Collection::Loader::Loader(Collection &c):
coll(c)
T &extract(const Variant &var) const;
template<typename T>
- void collect_items(std::list<T *> *objects, std::list<std::string> *names, std::list<std::string> *future_names) const
+ std::list<T *> extract_list(const std::list<const Variant *> &vars) const
{
- typedef RefPtr<typename RemoveConst<T>::Type> RPNCT;
+ std::list<T *> result;
+ for(std::list<const Variant *>::const_iterator i=vars.begin(); i!=vars.end(); ++i)
+ result.push_back(&extract<T>(**i));
+ return result;
+ }
- for(ItemMap::const_iterator i=items.begin(); i!=items.end(); ++i)
- if(i->second.check_type<RPNCT>())
- {
- if(objects)
- objects->push_back(i->second.value<RPNCT>().get());
- if(names)
- names->push_back(i->first);
- }
-
- if(future_names)
- if(CollectionItemTypeBase *type = get_type<T>())
- {
- for(SourceList::const_iterator i=sources.begin(); i!=sources.end(); ++i)
- {
- std::list<std::string> available_names = (*i)->get_names(*type);
- for(std::list<std::string>::iterator j=available_names.begin(); j!=available_names.end(); ++j)
- if(!items.count(*j))
- future_names->push_back(*j);
- }
- }
+ void gather_items(std::list<const Variant *> *, std::list<std::string> *, const CollectionItemTypeBase &, bool) const;
+
+ template<typename T>
+ void gather_items(std::list<const Variant *> *vars, std::list<std::string> *names, const CollectionItemTypeBase *type, bool include_sources) const
+ {
+ if(type || (type = get_type<T>()))
+ gather_items(vars, names, *type, include_sources);
+ else
+ gather_items(vars, names, CollectionItemType<T>(), false);
}
public:
template<typename T>
std::list<std::string> get_names() const
{
- std::list<std::string> result;
- collect_items<T>(0, &result, 0);
- return result;
+ std::list<std::string> names;
+ gather_items<typename RemoveConst<T>::Type>(0, &names, 0, false);
+ return names;
}
/** Returns a list of the names of objects of one type in the collection or
template<typename T>
std::list<std::string> get_names()
{
- std::list<std::string> result;
- collect_items<T>(0, &result, &result);
- return result;
+ std::list<std::string> names;
+ gather_items<typename RemoveConst<T>::Type>(0, &names, 0, true);
+ return names;
}
/// Returns a list of objects of one type in the collection.
template<typename T>
std::list<T *> get_list() const
{
- std::list<T *> result;
- collect_items<T>(&result, 0, 0);
- return result;
+ std::list<const Variant *> vars;
+ gather_items<typename RemoveConst<T>::Type>(&vars, 0, 0, false);
+ return extract_list<T>(vars);
}
/** Returns a list of objects of one type, loading them from sources if
template<typename T>
std::list<T *> get_list()
{
- std::list<T *> result;
- std::list<std::string> future;
- collect_items<T>(&result, 0, &future);
- for(std::list<std::string>::iterator i=future.begin(); i!=future.end(); ++i)
- result.push_back(&get<T>(*i));
- return result;
+ CollectionItemTypeBase *type = get_type<typename RemoveConst<T>::Type>();
+ if(type)
+ load_items_from_sources(*type);
+
+ std::list<const Variant *> vars;
+ gather_items<typename RemoveConst<T>::Type>(&vars, 0, type, true);
+ return extract_list<T>(vars);
}
private:
+ unsigned get_status(const std::string &, const CollectionItemTypeBase &) const;
+
template<typename T>
unsigned get_status(const std::string &name) const
{
- ItemMap::const_iterator i = items.find(name);
- if(i==items.end())
- {
- if(CollectionItemTypeBase *type = get_type<T>())
- {
- for(SourceList::const_iterator j=sources.begin(); j!=sources.end(); ++j)
- if((*j)->is_loadable(*type, name))
- return 2;
- }
- return 0;
- }
-
- typedef RefPtr<typename RemoveConst<T>::Type> RPNCT;
- if(!i->second.check_type<RPNCT>())
- return 0;
+ // XXX Should go through all applicable types
+ if(CollectionItemTypeBase *type = get_type<T>())
+ return get_status(name, *type);
- return 1;
+ ItemMap::const_iterator i = items.find(name);
+ return (i!=items.end() && i->second.check_type<RefPtr<T> >());
}
public:
/// Checks whether a typed object exists in the collection.
template<typename T>
bool contains(const std::string &name) const
- { return get_status<T>(name)==1; }
+ { return get_status<typename RemoveConst<T>::Type>(name)==1; }
/** Checks whether a typed object exists in the collection or is loadable
from a source. */
template<typename T>
bool contains(const std::string &name)
- { return get_status<T>(name)>0; }
+ { return get_status<typename RemoveConst<T>::Type>(name)>0; }
/// Returns the name of an item in the collection.
template<typename T>
CollectionItemTypeBase *get_type_for_item(const Variant &) const;
void add_source(CollectionSource &);
+
+ void gather_names_from_sources(std::list<std::string> &, const CollectionItemTypeBase &) const;
+
+ void load_items_from_sources(const CollectionItemTypeBase &);
};
template<typename T>