Lumiera  0.pre.03
»edit your freedom«
assetmanager.cpp
Go to the documentation of this file.
1 /*
2  AssetManager - Facade for the Asset subsystem
3 
4  Copyright (C) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
29 #include "steam/assetmanager.hpp"
30 #include "steam/asset/db.hpp"
31 
32 #include "lib/sync.hpp"
33 #include "lib/util-foreach.hpp"
34 #include "lib/format-string.hpp"
35 
36 #include <functional>
37 
38 using std::static_pointer_cast;
39 using std::function;
40 using std::placeholders::_1;
41 using util::for_each;
42 using util::_Fmt;
43 
44 using lib::Depend;
45 using lib::Sync;
46 
47 
48 namespace steam {
49 namespace asset {
50  namespace error = lumiera::error;
51 
56  struct IDErr
58  {
59  using error::Invalid::Invalid;
60  };
61 
62 
63  // ------pre-defined-common-error-cases---------------
64  //
65  LUMIERA_ERROR_DEFINE (UNKNOWN_ASSET_ID, "non-registered Asset ID");
66  LUMIERA_ERROR_DEFINE (WRONG_ASSET_KIND, "wrong Asset kind, unable to cast");
67 
68  struct UnknownID : IDErr
69  {
70  UnknownID (ID<Asset> aID)
71  : IDErr(_Fmt("Query for Asset with ID=%d, which up to now "
72  "hasn't been created or encountered.") % aID
73  ,LERR_(UNKNOWN_ASSET_ID))
74  { }
75  };
76 
77  struct WrongKind : IDErr
78  {
80  : IDErr (_Fmt("Request for Asset(%s), specifying an Asset kind, "
81  "that doesn't match the actual type (and can't be "
82  "casted either).") % idi
83  ,LERR_(WRONG_ASSET_KIND))
84  { }
85  };
86 
87 
88 
89 
90 
95 
96  AssetManager::AssetManager ()
97  : registry (Depend<asset::DB>() ())
98  { }
99 
100 
101 
103  ID<Asset>
105  {
106  return asset::hash_value (idi);
107  }
108 
109 
110 
116  template<class KIND>
117  ID<KIND>
118  AssetManager::reg (KIND* obj, const Asset::Ident& idi)
119  {
120  AssetManager& _aMang (AssetManager::instance());
121  DB& registry (_aMang.registry);
123  ID<KIND> asset_id (getID (idi));
124 
125  DB::Lock guard{&registry};
127  lib::P<KIND> smart_ptr (obj, &destroy);
128 
129  registry.put (asset_id, smart_ptr);
130  return asset_id;
131  }
132 
133 
138  template<class KIND>
141  {
142  if (lib::P<KIND> obj = registry.get (id))
143  return obj;
144  else
145  if (known (id)) // provide Ident tuple of existing Asset
146  throw WrongKind (registry.get(ID<Asset>(id))->ident);
147  else
148  throw UnknownID (id);
149  }
150 
157  template<class KIND>
159  AssetManager::wrap (const KIND& asset)
160  {
161  ENSURE (instance().known(asset.id),
162  "unregistered asset instance encountered.");
163  return static_pointer_cast<KIND,Asset>
164  (instance().registry.get (asset.id));
165  }
166 
167 
168 
172  bool
174  {
175  return bool(registry.get (ID<Asset>(id)));
176  } // query most general Asset ID-kind and use implicit
177  // conversion from smart-ptr to bool (test if empty)
178 
179 
183  bool
185  {
186  PAsset pA = registry.get (id);
187  return ( pA && pA->ident.category.isWithin(cat));
188  }
189 
190 
191  namespace { // details implementing AssetManager::remove
192 
193  void
194  recursive_call (AssetManager* instance, PAsset& pA)
195  {
196  instance->remove (pA->getID());
197  }
198 
199  function<void(PAsset&)>
200  detach_child_recursively ()
201  {
202  return bind( &recursive_call, &AssetManager::instance(), _1 );
203  }
204  }
205 
210  void
212  {
213  PAsset asset = getAsset (id);
214  for_each (asset->dependants, detach_child_recursively());
215  asset->unlink();
216  registry.del(id);
217  }
218 
219 
220  void
222  {
223  INFO (progress, "Clearing the Asset registry...");
224  registry.clear();
225  }
226 
227 
228  list<PcAsset>
230  {
231  list<PcAsset> res;
232  registry.asList (res);
233  res.sort();
234  return res;
235  }
236 
237 
238 }} // namespace steam::asset
239 
240 
241 
242 
243  /************************************************************/
244  /* explicit template instantiations for various Asset Kinds */
245  /************************************************************/
246 
247 #include "steam/asset/media.hpp"
248 #include "steam/asset/clip.hpp"
249 #include "steam/asset/proc.hpp"
250 #include "steam/asset/struct.hpp"
251 #include "steam/asset/pipe.hpp"
252 #include "steam/asset/meta.hpp"
253 #include "steam/asset/procpatt.hpp"
254 #include "steam/asset/timeline.hpp"
255 #include "steam/asset/sequence.hpp"
258 
259 namespace steam {
260 namespace asset {
261  using lib::P;
262 
263  template ID<Asset> AssetManager::reg (Asset* obj, const Asset::Ident& idi);
264 
265 
266  template P<Asset> AssetManager::getAsset (const ID<Asset>& id);
267  template P<Media> AssetManager::getAsset (const ID<Media>& id);
268  template P<Proc> AssetManager::getAsset (const ID<Proc>& id);
269  template P<Struct> AssetManager::getAsset (const ID<Struct>& id);
270  template P<Meta> AssetManager::getAsset (const ID<Meta>& id);
271  template P<Pipe> AssetManager::getAsset (const ID<Pipe>& id);
272 
273  template P<Asset> AssetManager::wrap (const Asset& asset);
274  template P<Media> AssetManager::wrap (const Media& asset);
275  template P<Clip> AssetManager::wrap (const Clip& asset);
276  template P<Pipe> AssetManager::wrap (const Pipe& asset);
277  template P<ProcPatt> AssetManager::wrap (const ProcPatt& asset);
278  template P<Timeline> AssetManager::wrap (const Timeline& asset);
279  template P<Sequence> AssetManager::wrap (const Sequence& asset);
280 
281  using meta::TimeGrid;
282  using meta::ErrorLog;
283  template P<TimeGrid> AssetManager::wrap (const TimeGrid& asset);
284  template P<ErrorLog> AssetManager::wrap (const ErrorLog& asset);
285 
286 
287 }} // namespace steam::asset
Facility for monitor object based locking.
Definition: sync.hpp:217
Interface: a grid and scale definition for time quantisation.
Definition: time-grid.hpp:86
static ID< Asset > getID(const Asset::Ident &)
provide the unique ID for given Asset::Ident tuple
Steam-Layer Interface: Asset Lookup and Organisation.
Definition of a structural asset to express patterns of wiring or processing Processing patterns can ...
A "processing pipe" represented as Asset.
"Processing Pattern" is a structural Asset representing information how to build some part of the ren...
Definition: procpatt.hpp:61
TODO type comment.
Definition: sequence.hpp:92
key abstraction: media-like assets
Definition: media.hpp:72
Media data represented a specific kind of Asset.
Tree like classification of Assets.
Definition: category.hpp:75
void remove(IDA id)
remove the given asset from the internal DB.
Front-end for printf-style string template interpolation.
scoped guard to control the actual locking.
Definition: sync.hpp:234
Facade for the Asset subsystem.
Steam-Layer implementation namespace root.
A front-end for using printf-style formatting.
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:289
structural asset corresponding to the part of the model forming a processing pipe for generating medi...
Definition: pipe.hpp:79
static lib::Depend< AssetManager > instance
get at the system-wide asset manager instance.
AssetManager error responses, caused by querying invalid Asset IDs from the internal DB...
Object Monitor based synchronisation.
Implementation of the registry holding all Asset instances known to the Asset Manager subsystem...
Definition: db.hpp:98
An entity to collect, possibly filter and persist incident records.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:196
Structural building block of the session: a sequence of clips.
Internal and organisational metadata.
Data processing Plugins and Codecs can be treated as a specific Kind of Asset.
a POD comprised of all the information sufficiently identifying any given Asset.
Definition: asset.hpp:158
list< PcAsset > listContent() const
extract a sorted list of all registered Assets
Superinterface describing especially bookkeeping properties.
Definition: asset.hpp:148
void for_each(CON const &elements, FUN function, P1 &&bind1, ARGS &&...args)
Accept binding for arbitrary function arguments.
Definition of Asset representation for a media clip.
Implementation of the Asset database.
lib::P< KIND > getAsset(const ID< KIND > &id)
find and return corresponding object
bookkeeping (Asset) view of a media clip.
Definition: asset/clip.hpp:44
To establish a reference scale for quantised time values.
static lib::P< KIND > wrap(const KIND &asset)
retrieve the registered smart-ptr for any asset
Customised refcounting smart pointer template, built upon std::shared_ptr, but forwarding type relati...
Definition: trait.hpp:78
The asset subsystem of the Steam-Layer.
Definition: wrapperptr.hpp:44
Receive, collect, filter and possibly persist incident records.
Definition: error-log.hpp:74
Asset representation of structural elements within the model.
Perform operations "for each element" of a collection.
static ID< KIND > reg(KIND *obj, const Asset::Ident &idi)
registers an asset object in the internal DB, providing its unique key.
Top level structural element within the session.
void clear()
deregister and evict all known Assets.
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition: error.h:80