X-Git-Url: http://git.tdb.fi/?p=libs%2Fdatafile.git;a=blobdiff_plain;f=source%2Fcollection.h;h=aa3c18a0fcc1a5e27f5d4ddc1278b58e65904877;hp=0cd799abf060e399a20c55027371917e14f563c5;hb=fbf76ed98dbd2cca6785efe2dd489d717fa5dce6;hpb=f19f861eb6858f396d574f0d45c5e967221a384b diff --git a/source/collection.h b/source/collection.h index 0cd799a..aa3c18a 100644 --- a/source/collection.h +++ b/source/collection.h @@ -104,10 +104,11 @@ public: if(!item) throw std::invalid_argument("Collection::add(item)"); - RefPtr::Type> ptr(item); + typedef typename RemoveConst::Type NCT; + RefPtr ptr(item); try { - insert_unique(items, name, ptr); + add_var(name, get_type(name), ptr); } catch(...) { @@ -153,6 +154,7 @@ public: } private: + void add_var(const std::string &, const CollectionItemTypeBase *, const Variant &); const Variant &get_var(const std::string &, const CollectionItemTypeBase *); const Variant *find_var(const std::string &, const CollectionItemTypeBase *); @@ -363,6 +365,7 @@ public: virtual bool can_create() const = 0; virtual void create_item(Collection &, const std::string &) const = 0; virtual void load_item(Collection &, Parser &, const std::string &) const = 0; + virtual void notify_item(Collection &, const std::string &, const Variant &) const = 0; template bool can_extract() const @@ -412,6 +415,26 @@ private: { return (dynamic_cast(coll).*func)(name); } }; + struct NotifyeeBase + { + virtual ~NotifyeeBase() { } + + virtual void notify(Collection &, const std::string &, T &) const = 0; + }; + + template + struct Notifyee: NotifyeeBase + { + typedef void (C::*FuncPtr)(const std::string &, T &); + + FuncPtr func; + + Notifyee(FuncPtr f): func(f) { } + + virtual void notify(Collection &coll, const std::string &name, T &item) const + { (dynamic_cast(coll).*func)(name, item); } + }; + template struct Extractor: CollectionItemTypeBase::Extractor { @@ -420,6 +443,7 @@ private: }; CreatorBase *creat; + std::vector notif; public: CollectionItemType(): @@ -429,6 +453,8 @@ public: ~CollectionItemType() { delete creat; + for(typename std::vector::const_iterator i=notif.begin(); i!=notif.end(); ++i) + delete *i; } /** Sets a datafile keyword for this item type. The Collection's loader @@ -472,6 +498,13 @@ public: return *this; } + template + CollectionItemType ¬ify(void (C::*func)(const std::string &, T &)) + { + notif.push_back(new Notifyee(func)); + return *this; + } + virtual bool is_same_type(const CollectionItemTypeBase &other) const { return dynamic_cast *>(&other); } @@ -497,6 +530,13 @@ public: { throw std::runtime_error("this type cannot be loaded"); } + + virtual void notify_item(Collection &coll, const std::string &name, const Variant &var) const + { + RefPtr obj = var.value >(); + for(typename std::vector::const_iterator i=notif.begin(); i!=notif.end(); ++i) + (*i)->notify(coll, name, *obj); + } };