template<typename T>
class CollectionItemType;
+template<typename T>
+class LoadableCollectionItemType;
+
+template<typename T, bool = HasLoader<T>::value>
+struct CollectionItemTypeChooser;
+
+template<typename T>
+struct CollectionItemTypeChooser<T, true>
+{ typedef LoadableCollectionItemType<T> Type; };
+
+template<typename T>
+struct CollectionItemTypeChooser<T, false>
+{ typedef CollectionItemType<T> Type; };
+
/**
A collection of objects that can be loaded from a datafile. Each object is
identified by a name, which must be unique across the entire collection.
*/
class Loader: public DataFile::Loader
{
- template<typename T> friend class CollectionItemType;
+ template<typename T> friend class LoadableCollectionItemType;
private:
Collection &coll;
/** Adds a type to the collection. The returned descriptor object reference
can be used to define how objects of that type can be loaded. */
template<typename T>
- CollectionItemType<T> &add_type();
+ typename CollectionItemTypeChooser<T>::Type &add_type();
/** Returns a mutable reference to an existing type descriptor. This can be
used to e.g. override the creator function of a type added by a base class. */
template<typename T>
- CollectionItemType<T> &modify_type();
+ typename CollectionItemTypeChooser<T>::Type &modify_type();
private:
/** Returns the descriptor for a type, or null if one isn't defined. An
public:
virtual ~CollectionItemTypeBase();
+protected:
void set_keyword(const std::string &);
- const std::string &get_keyword() const { return kwd; }
void add_suffix(const std::string &);
+public:
+ const std::string &get_keyword() const { return kwd; }
bool match_name(const std::string &) const;
virtual bool is_same_type(const CollectionItemTypeBase &) const = 0;
virtual bool check_item_type(const Variant &) const = 0;
virtual bool check_item_type(const Variant &var) const
{ return var.check_type<RefPtr<T> >(); }
- virtual void add_to_loader(Collection::Loader &loader) const
- { loader.add(kwd, &Collection::Loader::item<T, T>); }
+ virtual void add_to_loader(Collection::Loader &) const
+ { }
virtual bool can_create() const
{ return creat!=0; }
coll.add(name, obj);
}
+ virtual void load_item(Collection &, Parser &, const std::string &) const
+ {
+ throw std::runtime_error("this type cannot be loaded");
+ }
+};
+
+
+template<typename T>
+class LoadableCollectionItemType: public CollectionItemType<T>
+{
+public:
+ virtual void add_to_loader(Collection::Loader &loader) const
+ { loader.add(this->kwd, &Collection::Loader::item<T, T>); }
+
virtual void load_item(Collection &coll, Parser &parser, const std::string &name) const
{
RefPtr<T> obj = new T;
}
template<typename T>
-CollectionItemType<T> &Collection::add_type()
+typename CollectionItemTypeChooser<T>::Type &Collection::add_type()
{
- CollectionItemType<T> *type = new CollectionItemType<T>;
+ typename CollectionItemTypeChooser<T>::Type *type = new typename CollectionItemTypeChooser<T>::Type;
types.push_back(type);
return *type;
}
template<typename T>
-CollectionItemType<T> &Collection::modify_type()
+typename CollectionItemTypeChooser<T>::Type &Collection::modify_type()
{
for(TypeList::const_iterator j=types.begin(); j!=types.end(); ++j)
if(CollectionItemType<T> *t = dynamic_cast<CollectionItemType<T> *>(*j))