00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "proc/assetmanager.hpp"
00025 #include "proc/asset/db.hpp"
00026
00027 #include "common/multithread.hpp"
00028 #include "common/util.hpp"
00029
00030 #include <boost/function.hpp>
00031
00032 #include <boost/format.hpp>
00033 #include <boost/bind.hpp>
00034
00035 using std::tr1::static_pointer_cast;
00036 using boost::function;
00037 using boost::format;
00038 using boost::bind;
00039 using util::for_each;
00040
00041 using lumiera::Singleton;
00042 using lumiera::Thread;
00043
00044
00045 namespace asset
00046 {
00047
00052 class IDErr : public lumiera::error::Invalid
00053 {
00054 public:
00055 IDErr (const char* eID, format fmt)
00056 : lumiera::error::Invalid(fmt.str(),eID) {}
00057 };
00058
00059
00060
00061
00062 LUMIERA_ERROR_DEFINE (UNKNOWN_ASSET_ID, "non-registered Asset ID");
00063 LUMIERA_ERROR_DEFINE (WRONG_ASSET_KIND, "wrong Asset kind, unable to cast");
00064
00065 class UnknownID : public IDErr
00066 {
00067 public:
00068 UnknownID (ID<Asset> aID) : IDErr (LUMIERA_ERROR_UNKNOWN_ASSET_ID,
00069 format("Query for Asset with ID=%d, which up to now "
00070 "hasn't been created or encountered.") % aID) {}
00071 };
00072
00073 class WrongKind : public IDErr
00074 {
00075 public:
00076 WrongKind (Asset::Ident idi) : IDErr (LUMIERA_ERROR_WRONG_ASSET_KIND,
00077 format("Request for Asset(%s), specifying an Asset kind, "
00078 "that doesn't match the actual type (and can't be "
00079 "casted either).") % string(idi)) {}
00080 };
00081
00082
00083
00084
00085
00089 Singleton<AssetManager> AssetManager::instance;
00090
00091 AssetManager::AssetManager ()
00092 : registry (Singleton<asset::DB>() ())
00093 { }
00094
00095
00096
00098 ID<Asset>
00099 AssetManager::getID (const Asset::Ident& idi)
00100 {
00101 return asset::hash_value (idi);
00102 }
00103
00104
00105
00110 template<class KIND>
00111 ID<KIND>
00112 AssetManager::reg (KIND* obj, const Asset::Ident& idi)
00113 throw(lumiera::error::Invalid)
00114 {
00115 AssetManager& _aMang (AssetManager::instance());
00116 TODO ("check validity of Ident Category");
00117 ID<KIND> asset_id (getID (idi));
00118
00119 Thread::Lock<DB> guard SIDEEFFECT;
00120 TODO ("handle duplicate Registrations");
00121 P<KIND> smart_ptr (obj, &destroy);
00122
00123 _aMang.registry.put (asset_id, smart_ptr);
00124 return asset_id;
00125 }
00126
00127
00132 template<class KIND>
00133 P<KIND>
00134 AssetManager::getAsset (const ID<KIND>& id)
00135 throw(lumiera::error::Invalid)
00136 {
00137 if (P<KIND> obj = registry.get (id))
00138 return obj;
00139 else
00140 if (known (id))
00141 throw WrongKind (registry.get(ID<Asset>(id))->ident);
00142 else
00143 throw UnknownID (id);
00144 }
00145
00152 template<class KIND>
00153 P<KIND>
00154 AssetManager::wrap (const KIND& asset)
00155 {
00156 ENSURE (instance().known(asset.id),
00157 "unregistered asset instance encountered.");
00158 return static_pointer_cast<KIND,Asset>
00159 (instance().registry.get (asset.id));
00160 }
00161
00162
00163
00167 bool
00168 AssetManager::known (IDA id)
00169 {
00170 return ( registry.get (ID<Asset>(id)) );
00171 }
00172
00173
00174
00178 bool
00179 AssetManager::known (IDA id, const Category& cat)
00180 {
00181 PAsset pA = registry.get (id);
00182 return ( pA && pA->ident.category.isWithin(cat));
00183 }
00184
00185
00186 void
00187 recursive_call (AssetManager* instance, PAsset& pA)
00188 {
00189 instance->remove (pA->getID());
00190 }
00191
00192 function<void(PAsset&)>
00193 detach_child_recursively ()
00194 {
00195 return bind( &recursive_call, &AssetManager::instance(), _1 );
00196 }
00197
00202 void
00203 AssetManager::remove (IDA id)
00204 {
00205 PAsset asset = getAsset (id);
00206 for_each (asset->dependants, detach_child_recursively());
00207 asset->unlink();
00208 registry.del(id);
00209 }
00210
00211
00212
00213 list<PcAsset>
00214 AssetManager::listContent() const
00215 {
00216 list<PcAsset> res;
00217 registry.asList (res);
00218 res.sort();
00219 return res;
00220 }
00221
00222
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232 #include "proc/asset/media.hpp"
00233 #include "proc/asset/clip.hpp"
00234 #include "proc/asset/proc.hpp"
00235 #include "proc/asset/struct.hpp"
00236 #include "proc/asset/track.hpp"
00237 #include "proc/asset/pipe.hpp"
00238 #include "proc/asset/meta.hpp"
00239 #include "proc/asset/procpatt.hpp"
00240
00241
00242 namespace asset
00243 {
00244
00245 template ID<Asset> AssetManager::reg (Asset* obj, const Asset::Ident& idi);
00246
00247
00248 template P<Asset> AssetManager::getAsset (const ID<Asset>& id) throw(lumiera::error::Invalid);
00249 template P<Media> AssetManager::getAsset (const ID<Media>& id) throw(lumiera::error::Invalid);
00250 template P<Proc> AssetManager::getAsset (const ID<Proc>& id) throw(lumiera::error::Invalid);
00251 template P<Struct> AssetManager::getAsset (const ID<Struct>& id) throw(lumiera::error::Invalid);
00252 template P<Meta> AssetManager::getAsset (const ID<Meta>& id) throw(lumiera::error::Invalid);
00253
00254 template P<Asset> AssetManager::wrap (const Asset& asset);
00255 template P<Media> AssetManager::wrap (const Media& asset);
00256 template P<Clip> AssetManager::wrap (const Clip& asset);
00257 template P<Track> AssetManager::wrap (const Track& asset);
00258 template P<Pipe> AssetManager::wrap (const Pipe& asset);
00259 template P<ProcPatt> AssetManager::wrap (const ProcPatt& asset);
00260
00261
00262 }