EntryID: fix symbol generation and improve ordering

This commit is contained in:
Fischlurch 2010-03-29 03:27:47 +02:00
parent b21db07aff
commit c691213003
5 changed files with 79 additions and 35 deletions

View file

@ -33,13 +33,13 @@
namespace asset {
using lib::Literal;
using std::string;
using std::ostream;
/**
/**
* top-level distinction of different Kinds of Assets.
* For convenience, this classification is slightly denormalised,
* as AUDIO, and VIDEO are both asset::Media objects, EFFECT and CODEC
@ -67,9 +67,7 @@ namespace asset {
*/
class Category
{
public:
private:
Kind kind_;
string path_;
@ -87,15 +85,8 @@ namespace asset {
operator string () const;
friend size_t hash_value (Category const&);
friend size_t
hash_value (Category const& cat)
{
size_t hash = 0;
boost::hash_combine(hash, cat.kind_);
boost::hash_combine(hash, cat.path_);
return hash;
}
int
compare (Category const& co) const
@ -109,7 +100,21 @@ namespace asset {
};
inline ostream& operator<< (ostream& os, const Category& cago) { return os << string(cago); }
inline ostream&
operator<< (ostream& os, const Category& cat)
{
return os << string(cat);
}
inline size_t
hash_value (Category const& cat)
{
size_t hash = 0;
boost::hash_combine(hash, cat.kind_);
boost::hash_combine(hash, cat.path_);
return hash;
}

View file

@ -80,13 +80,14 @@ namespace asset {
* @todo several unsolved design problems. How to deal with std hash values in
* conjunction with LUID. How to create a LuidH instance, if not generating
* a new random value
* @warning this code isn't portable and breaks if sizeof(size_t) < sizeof(void*)
*/
inline LuidH
buildHash (string const& sym, HashVal seed =0)
{
boost::hash_combine(seed, sym);
lumiera_uid tmpLUID;
lumiera_uid_set_ptr (&tmpLUID, reinterpret_cast<void*> (&seed));
lumiera_uid_set_ptr (&tmpLUID, reinterpret_cast<void*> (seed));
return reinterpret_cast<LuidH&> (tmpLUID);
}
}
@ -102,6 +103,7 @@ namespace asset {
* for building a combined hash and symbolic ID.
*/
class BareEntryID
: public boost::equality_comparable<BareEntryID>
{
typedef lib::hash::LuidH LuidH;
@ -166,16 +168,20 @@ namespace asset {
* @see mobject::session::Track
*/
template<class TY>
class EntryID
: boost::totally_ordered1< EntryID<TY>
, BareEntryID // common baseclass
>
struct EntryID
: BareEntryID
, boost::totally_ordered< EntryID<TY> >
{
public:
/** case-1: auto generated symbolic ID */
EntryID()
: BareEntryID (idi::generateSymbolID<TY>(), getTypeHash())
{ }
/** case-2: explicitly specify a symbolic ID to use.
* The type information TY will be included automatically
* into the generated hash-ID. This hash is reproducible.
*/
explicit
EntryID (string const& symbolID)
: BareEntryID (symbolID, getTypeHash())
@ -197,7 +203,9 @@ namespace asset {
getTypeHash()
{
Category cat (STRUCT, idi::StructTraits<TY>::catFolder);
return hash_value (cat);
asset::Category const& catz(cat);
size_t haha = hash_value (catz);
return haha;
}
@ -229,12 +237,17 @@ namespace asset {
}
friend ostream& operator<< (ostream& os, EntryID const& id) { return os << string(id); }
friend bool operator== (EntryID const& i1, EntryID const& i2) { return i1.getSym() == i2.getSym(); }
friend bool operator< (EntryID const& i1, EntryID const& i2) { return i1.getSym() < i2.getSym(); }
friend bool operator< (EntryID const& i1, EntryID const& i2) { return i1.getSym() < i2.getSym(); }
};
inline bool
operator== (BareEntryID const& i1, BareEntryID const& i2)
{
return i1.getHash() == i2.getHash();
}
/** try to upcast this BareEntryID to a fully typed EntryID.

View file

@ -61,6 +61,14 @@ using lib::Symbol;
//using lumiera::query::LUMIERA_ERROR_CAPABILITY_QUERY;
//using lumiera::query::extractID;
namespace mobject {
namespace session {
class Track;
class Clip;
}}
namespace asset{
class Track;
@ -70,7 +78,7 @@ namespace asset{
class Sequence;
namespace idi {
// structural asset ID scheme ///////////////////////////////////////////////////////////TICKET #565
template<class STRU>
@ -81,9 +89,18 @@ namespace asset{
static Symbol idSymbol;
};
template<> Symbol StructTraits<Track>::namePrefix = "track";
template<> Symbol StructTraits<Track>::catFolder = "tracks";
template<> Symbol StructTraits<Track>::idSymbol = "track";
///////////////////////////////////////////////////////////////////////////////////////////TICKET #581 intending to abandon asset::Track in favour of a plain EntryID
template<> Symbol StructTraits<asset::Track>::namePrefix = "track";
template<> Symbol StructTraits<asset::Track>::catFolder = "tracks";
template<> Symbol StructTraits<asset::Track>::idSymbol = "track";
template<> Symbol StructTraits<mobject::session::Track>::namePrefix = "track";
template<> Symbol StructTraits<mobject::session::Track>::catFolder = "tracks";
template<> Symbol StructTraits<mobject::session::Track>::idSymbol = "track";
template<> Symbol StructTraits<mobject::session::Clip>::namePrefix = "clip";
template<> Symbol StructTraits<mobject::session::Clip>::catFolder = "clips";
template<> Symbol StructTraits<mobject::session::Clip>::idSymbol = "clip";
template<> Symbol StructTraits<Pipe>::namePrefix = "pipe";
template<> Symbol StructTraits<Pipe>::catFolder = "pipes";
@ -117,7 +134,7 @@ namespace asset{
generateSymbolID()
{
static uint i=0;
static format namePattern ("%s.%02d");
static format namePattern ("%s.%03d");
/////////////////////////////////////////////////////////TODO needs to be pushed down into a *.cpp
return str(namePattern % StructTraits<STRU>::namePrefix % (++i) );

View file

@ -34,6 +34,7 @@
#include <iostream>
#include <string>
using lib::test::showSizeof;
using lib::test::randStr;
using util::isSameObject;
using util::for_each;
@ -86,7 +87,6 @@ namespace test {
void
checkCreation ()
{
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #582
DummyID dID1;
DummyID dID2("strange");
DummyID dID3;
@ -107,13 +107,22 @@ namespace test {
CHECK (tID2 != tID3); CHECK (tID3 != tID2);
CHECK (tID1 != tID3); CHECK (tID3 != tID1);
cout << dID1 << dID2 << dID3 << endl;
cout << tID1 << tID2 << tID3 << endl;
cout << dID1 << endl;
cout << dID2 << endl;
cout << dID3 << endl;
cout << tID1 << endl;
cout << tID2 << endl;
cout << tID3 << endl;
cout << showSizeof<TrackID>() << endl;
cout << showSizeof<BareEntryID>() << endl;
CHECK (sizeof(TrackID) == sizeof(BareEntryID));
CHECK (sizeof(TrackID) == sizeof(lumiera_uid) + sizeof(void*));
DummyID x (dID2); // copy ctor
CHECK (x == dID2);
CHECK (!isSameObject (x, dID2));
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #582
}
@ -236,7 +245,7 @@ namespace test {
/** Register this test class... */
LAUNCHER (EntryID_test, "unit common");
LAUNCHER (EntryID_test, "unit asset");
}} // namespace asset::test

View file

@ -4148,7 +4148,7 @@ The session and the models rely on dependent objects beeing kept updated and con
&amp;rarr; see [[details here...|ModelDependencies]]
</pre>
</div>
<div title="SessionInterface" modifier="Ichthyostega" modified="201003140244" created="200904242108" tags="SessionLogic GuiIntegration design draft discuss" changecount="47">
<div title="SessionInterface" modifier="Ichthyostega" modified="201003272138" created="200904242108" tags="SessionLogic GuiIntegration design draft discuss" changecount="48">
<pre>&quot;Session Interface&quot;, when used in a more general sense, denotes a compound of several interfaces and facilities, together forming the primary access point to the user visible contents and state of the editing project.
* the API of the session class
* the accompanying management interface (SessionManager API)
@ -4217,7 +4217,7 @@ When adding an object, a [[scope|PlacementScope]] needs to be specified. Thus it
* how is all of this related to the LayerSeparationInterfaces, here SessionFacade und EditFacade?
&lt;&lt;&lt;
__preliminary notes__: {{red{3/2010}}} Discovery functions accessible from the session API are always written such as to return ~MObjectRefs. These expose generic functions for modifying the structure: {{{attach(MObjectRef)}}} and {{{purge()}}}. The session API exposes variations of these functions. Actually, all these functions do dispatch the respective commands automatically. To the contrary, the raw functions for adding and removing placements are located on the PlacementIndex; the're accessible as SessionServices &amp;mdash; which are intended for Proc-Layer's internal use solely. This separation isn't meant to be airtight, just an reminder for proper use.
__preliminary notes__: {{red{3/2010}}} Discovery functions accessible from the session API are always written such as to return ~MObjectRefs. These expose generic functions for modifying the structure: {{{attach(MObjectRef)}}} and {{{purge()}}}. The session API exposes variations of these functions. Actually, all these functions do dispatch the respective commands automatically. To the contrary, the raw functions for adding and removing placements are located on the PlacementIndex; they are accessible as SessionServices &amp;mdash; which are intended for Proc-Layer's internal use solely. This separation isn't meant to be airtight, just an reminder for proper use.
Currently, I'm planning to modify MObjectRef to return only a const ref to the underlying facilities by default. Then, there would be a subclass which is //mutation enabled.// But this subclass will check for the presence of a mutation-permission token &amp;mdash; which is exposed via thread local storage, but //only within a command dispatch.// Again, no attempt is made to make this barrier airtight. Indeed, for tests, the mutation-permission token can just be created in the local scope. After all, this is not conceived as an authorisation scheme, rather as a automatic sanity check. It's the liability of the client code to ensure any mutation is dispatched.
&lt;&lt;&lt;