CreateAsset_test now passes the compiler, after quite some tinkering....

This commit is contained in:
Fischlurch 2007-09-12 06:53:12 +02:00
parent 26374ce409
commit 814f6fc734
7 changed files with 136 additions and 53 deletions

View file

@ -26,9 +26,28 @@
** and the asset::ID primary key wrapper. Normally, Assets should be handled
** using asset::PAsset, a ref counting smart pointer.
**
** These classes are placed into namespace asset and proc_interface.
** These classes are placed into namespace asset and proc_interface.
**
** Assets are handled by a hierarchy of interfaces. Below the top level Asset interface
** there are interfaces for various different <i>Kinds</i> of Assets, like asset::Media,
** asset::Proc, etc. Code utilizing the specific properties of e.g. Media assets, will
** be implemented directly against the asset::Media interface. To make this feasible
** while at the same time being able to handle all asset Kinds in a uniform manner,
** we use a hierarchy of ID classes. These IDs are actually just thin wrappers around
** a hash value, but they carry a template parameter specifying the Asset Kind and the
** Asset Kind subinterfaces provide a overloaded getID method with a covariant return
** value. For example the asset::Media#getID returns an ID<Media>. By using the
** templated query function AssetManager#getAsset, we can get at references to the more
** specific subinterface asset::media just by using the ID value in a typesafe manner.
** This helps avoiding dynamic typing and switch-on-type, leading to much more robust,
** extensible and clear code.
**
** (Implementation detail: as g++ is not able to handle member function template
** instantiations completely automatic, we need to trigger some template instantiations
** at the end of assetmanager.cpp )
**
** @see assetmanager.hpp
** @see media.hpp
*/
@ -70,6 +89,7 @@ namespace asset
* @see Asset
* @see AssetManager#getID generating ID values
* @see asset::Media
* @see ID<asset::Media>
*/
template<class KIND>
class ID
@ -85,16 +105,9 @@ namespace asset
class AssetManager;
typedef const ID<Asset>& IDA;
class Media;
template<>
class ID<Media> : public ID<Asset>
{
public:
ID (size_t id);
ID (const Media&);
};
/**
* Superinterface describing especially bookeeping properties.
@ -105,7 +118,7 @@ namespace asset
* <li>asset::Struct representing structural components used in the sesion (e.g. Tracks)</li>
* <li>asset::Meta representing meta objects created while editing (e.g. Automation)</li>
* </ul>
* And of course, there are various concret Asset subclasses, like asset::Clip,
* And of course there are various concret Asset subclasses, like asset::Clip,
* asset::Effect, asset::Codec, asset::Track, asset::Dataset.
* @note Assets objects have a strict unique identity and because of this are non-copyable.
* You can not create an Asset derived object without registering it with the AssetManager
@ -168,7 +181,7 @@ namespace asset
const Ident ident; ///< Asset identification tuple
virtual const ID<Asset>& getID() const { return id; }
private:
protected:
const ID<Asset> id; ///< Asset primary key.
@ -256,8 +269,8 @@ namespace proc_interface
{
using asset::Asset;
using asset::Category;
// using asset::ID;
// using asset::IDA;
using asset::ID;
using asset::IDA;
using asset::PAsset;
}

View file

@ -81,11 +81,10 @@ namespace asset
{
IdHashtable table;
friend class AssetManager;
DB () : table() {}
~DB () {}
friend class cinelerra::singleton::Static<DB>;
};

View file

@ -57,20 +57,28 @@ namespace asset
return "";
}
}
MediaFactory Media::create; ///< storage for the static MediaFactory instance
MediaFactory Media::create;
/** Factory method for Media Asset instances. Depending on the filename given,
* either a asset::Media object or an "Unknown" placeholder will be provided. If
* the given Category already contains an "Unkown", we just get the
* corresponding smart-ptr. Otherwise a new asset::Unknown is created. */
* corresponding smart-ptr. Otherwise a new asset::Unknown is created.
* @return an Media smart ptr linked to the internally registered smart ptr
* created as a side effect of calling the concrete Media subclass ctor.
*/
MediaFactory::PType
MediaFactory::operator() (Asset::Ident& key, const string& file)
{
asset::Media* pM (0);
AssetManager& aMang = AssetManager::instance();
TODO ("check and fix Category if necessary");
if (isnil (file))
{
if (isnil (key.name)) key.name="nil";
@ -86,11 +94,13 @@ namespace asset
TODO ("file exists?");
pM = new Media (key,file);
}
ASSERT (pM);
ENSURE (key.category.hasKind (VIDEO) || key.category.hasKind(AUDIO));
ENSURE (isnil (key.name));
ENSURE (dynamic_cast<Media*>(pM) || (isnil (file) && dynamic_cast<Unknown*>(pM)));
return PType (pM, &destroy);
return aMang.getAsset (pM->getID()); // note: because we query with an ID<Media>,
// we get a Media smart ptr.
}
@ -101,7 +111,14 @@ namespace asset
MediaFactory::operator() (const string& file, Category& cat)
{
Asset::Ident key(extractName(file), cat, "cin3", 1);
return MediaFactory::operator() (key, file);
return operator() (key, file);
}
MediaFactory::PType
MediaFactory::operator() (const string& file, asset::Kind kind)
{
Category cat(kind);
return operator() (file, cat);
}
@ -109,16 +126,22 @@ namespace asset
MediaFactory::operator() (const char* file, Category& cat)
{
if (!file) file = "";
return operator() (file,cat);
return operator() (string(file),cat);
}
MediaFactory::PType
MediaFactory::operator() (const char* file, asset::Kind kind)
{
if (!file) file = "";
return operator() (string(file),kind);
}
MediaFactory::PType
MediaFactory::operator() (Asset::Ident& key, const char* file)
{
if (!file) file = "";
return operator() (key,file);
return operator() (key, string(file));
}
} // namespace asset

View file

@ -21,6 +21,17 @@
*/
/** @file media.hpp
** Media data is a specific Kind of Asset.
** For the different <i>Kinds</i> of Assets, we use sub-intefaces inheriting
** from the general Asset interface. To be able to get asset::Media instances
** directly from the AssetManager, we define a specialization of the Asset ID.
**
** @see asset.hpp for explanation
** @see MediaFactory creating concrete asset::Media instances
**
*/
#ifndef ASSET_MEDIA_H
#define ASSET_MEDIA_H
@ -36,8 +47,16 @@ namespace asset
class MediaFactory;
template<>
class ID<Media> : public ID<Asset>
{
public:
ID (size_t id);
ID (const Media&);
};
/**
* key abstraction: media-like assets
*/
@ -46,27 +65,29 @@ namespace asset
string filename_;
public:
virtual const ID<Media>& getID() const { return getID(); }
static MediaFactory create;
const string& getFilename () { return filename_; }
const string& getFilename () const { return filename_; }
virtual const ID<Media>& getID() const ///< @return ID of kind Media
{
return static_cast<const ID<Media>& > (Asset::getID());
}
protected:
Media (const Asset::Ident& idi, const string& file) : Asset(idi), filename_(file) {}
friend class MediaFactory;
};
// definition of ID<Media> ctors is possible now,
// after providing full definition of class Media
/*
ID<Media>::ID(size_t id)
: ID<Asset> (id) {};
ID<Media>::ID(const Media& media)
: ID<Asset> (media.getID()) {};
*/
inline ID<Media>::ID(size_t id) : ID<Asset> (id) {};
inline ID<Media>::ID(const Media& media) : ID<Asset> (media.getID()) {};
/**
* Factory specialized for createing Media Asset objects.
*/
@ -77,9 +98,11 @@ namespace asset
PType operator() (Asset::Ident& key, const string& file="");
PType operator() (const string& file, Category& cat);
PType operator() (const string& file, asset::Kind);
PType operator() (Asset::Ident& key, const char* file); ///< convienience overload using cString
PType operator() (Asset::Ident& key, const char* file); ///< convienience overload using C-String
PType operator() (const char* file, Category& cat);
PType operator() (const char* file, asset::Kind);
protected:
static void destroy (Media* m) { delete m; }

View file

@ -23,7 +23,6 @@
#include "proc/assetmanager.hpp"
#include "proc/asset/db.hpp"
#include "common/singleton.hpp"
//#include <boost/functional/hash.hpp>
@ -35,14 +34,10 @@ namespace asset
/** get at the system-wide asset manager instance.
* Implemented as singleton.
*/
AssetManager&
AssetManager::instance ()
{
return *(new AssetManager); //////////////////////////////TODO Singleton<AssetManager>::instance();
}
Singleton<AssetManager> AssetManager::instance;
AssetManager::AssetManager ()
: registry (*(new DB)) //(Singleton<asset::DB>::instance())
: registry (Singleton<asset::DB>() ())
{ }
@ -61,7 +56,7 @@ namespace asset
*/
template<class KIND>
ID<KIND>
AssetManager::reg (KIND& obj, const Asset::Ident& idi)
AssetManager::reg (KIND* obj, const Asset::Ident& idi)
throw(cinelerra::error::Invalid)
{
UNIMPLEMENTED ("AssetManager::reg");
@ -110,6 +105,32 @@ namespace asset
{
}
} // namespace asset
/************************************************************/
/* explicit template instantiations for various Asset Kinds */
/************************************************************/
#include "proc/asset/media.hpp"
#include "proc/asset/proc.hpp"
#include "proc/asset/struct.hpp"
#include "proc/asset/meta.hpp"
namespace asset
{
template ID<Asset> AssetManager::reg (Asset* obj, const Asset::Ident& idi);
template shared_ptr<Asset> AssetManager::getAsset (const ID<Asset>& id) throw(cinelerra::error::Invalid);
template shared_ptr<Media> AssetManager::getAsset (const ID<Media>& id) throw(cinelerra::error::Invalid);
template shared_ptr<Proc> AssetManager::getAsset (const ID<Proc>& id) throw(cinelerra::error::Invalid);
template shared_ptr<Struct> AssetManager::getAsset (const ID<Struct>& id) throw(cinelerra::error::Invalid);
template shared_ptr<Meta> AssetManager::getAsset (const ID<Meta>& id) throw(cinelerra::error::Invalid);
} // namespace asset

View file

@ -38,6 +38,7 @@
#include "proc/asset.hpp"
#include "common/error.hpp"
#include "common/singleton.hpp"
#include <cstddef>
#include <string>
@ -62,7 +63,7 @@ namespace asset
public:
static AssetManager& instance();
static cinelerra::Singleton<AssetManager> instance;
/** provide the unique ID for given Asset::Ident tuple */
static ID<Asset> getID (const Asset::Ident&);
@ -90,12 +91,14 @@ namespace asset
* @internal used by the Asset base class ctor to create Asset::id.
*/
template<class KIND>
static ID<KIND> reg (KIND& obj, const Asset::Ident& idi)
static ID<KIND> reg (KIND* obj, const Asset::Ident& idi)
throw(cinelerra::error::Invalid);
friend Asset::Asset (const Asset::Ident& idi);
AssetManager ();
friend class cinelerra::singleton::Static<AssetManager>;
};

View file

@ -60,13 +60,12 @@ namespace asset
void createMedia()
{
/* typedef shared_ptr<asset::Media> PM;
typedef shared_ptr<asset::Media> PM;
Category cat(VIDEO,"bin1");
Asset::Ident key("Name-1", cat, "ichthyo", 5);
PM mm1 = asset::Media::create(key,"testfile.mov");
PM mm2 = asset::Media::create(key);
Category vid(VIDEO);////////////////////////////////////////////////FIXME
PM mm3 = asset::Media::create("testfile2.mov", vid);
PM mm3 = asset::Media::create("testfile2.mov", VIDEO);
// Assets have been registered and can be retrieved by ID
AssetManager& aMang = AssetManager::instance();
@ -76,11 +75,11 @@ namespace asset
ASSERT (aMang.getAsset (mm1->getID()) != mm2);
// PAsset aa1 = aMang.getAsset (ID<Asset>(mm1->getID())); // note we get an Asset ref
// ASSERT (aa1 == mm1);
PAsset aa1 = aMang.getAsset (ID<Asset>(mm1->getID())); // note we get an Asset ref
ASSERT (aa1 == mm1);
PM mX1 = aMang.getAsset (mm1->getID()); // ..and now we get a Media ref
ASSERT (mX1 == mm1);
// ASSERT (mX1 == aa1);
ASSERT (mX1 == aa1);
ASSERT (aMang.known (mm1->getID()));
ASSERT (aMang.known (mm2->getID()));
@ -89,7 +88,7 @@ namespace asset
ASSERT ( !aMang.known (mm3->getID(), Category(AUDIO))); // not found within AUDIO-Category
try
{ // can't be found if specifying wrong Asset kind....
// aMang.getAsset (ID<asset::Proc>(mm1->getID()));
aMang.getAsset (ID<asset::Proc>(mm1->getID()));
NOTREACHED;
}
catch (cinelerra::error::Invalid) { }
@ -116,6 +115,8 @@ namespace asset
ASSERT (mm1->getFilename() == "testfile.mov");
ASSERT (isnil (mm2->getFilename()));
ASSERT (mm3->getFilename() == "testfile2.mov");
/*
////////////////////////////////////////////////////////////////////////////////TODO fuck the compiler!!!
*/
}
};