hash ID: add trivial implementation + impl based on LUID
This commit is contained in:
parent
3b8a851722
commit
85a9c99e52
7 changed files with 229 additions and 100 deletions
|
|
@ -30,7 +30,7 @@
|
|||
** be managed within this collection. Typically this results in this common base class
|
||||
** being almost worthless as an API or interface, causing lots of type casts when using
|
||||
** such a common object management facility. Passing additional context or API information
|
||||
** on a metaprogramming level through the management interface helps avoiding these
|
||||
** on a metaprogramming level through the management interface helps avoiding these
|
||||
** shortcomings.
|
||||
**
|
||||
** Here we build an ID facility with the following properties:
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
** and the IDs denoting specific subclasses, such that the latter can stand-in
|
||||
** for the generic ID.
|
||||
** - providing a Mixin, which allows any hierarchy to use this facility without
|
||||
** much code duplication.
|
||||
** much code duplication, including an adapter for tr1::unordered_map
|
||||
**
|
||||
** @see HashIndexed_test
|
||||
** @see Placement usage example
|
||||
|
|
@ -53,34 +53,78 @@
|
|||
#ifndef LIB_HASH_INDEXED_H
|
||||
#define LIB_HASH_INDEXED_H
|
||||
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
#include <cstdlib>
|
||||
extern "C" {
|
||||
#include "lib/luid.h"
|
||||
}
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
||||
// using std::tr1::shared_ptr;
|
||||
using std::rand;
|
||||
|
||||
/** Hash implementations usable for the HashIndexed mixin
|
||||
* as well as key within tr1::unordered_map */
|
||||
namespace hash {
|
||||
|
||||
/**
|
||||
* simple Hash implementation
|
||||
* directly incorporating the hash value.
|
||||
*/
|
||||
class Plain
|
||||
{
|
||||
const size_t hash_;
|
||||
|
||||
public:
|
||||
Plain (size_t val)
|
||||
: hash_(val)
|
||||
{ }
|
||||
|
||||
template<typename TY>
|
||||
Plain (TY const& something)
|
||||
: hash_(hash_value (something)) // ADL
|
||||
{ }
|
||||
|
||||
operator size_t() const { return hash_; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash implementation based on a lumiera unique object id (LUID)
|
||||
* When invoking the default ctor, a new LUID is generated
|
||||
*/
|
||||
class LuidH
|
||||
{
|
||||
lumiera_uid luid_;
|
||||
|
||||
public:
|
||||
LuidH ()
|
||||
{
|
||||
lumiera_uid_gen (&luid_);
|
||||
ENSURE (0 < lumiera_uid_hash(&luid_));
|
||||
}
|
||||
|
||||
typedef lumiera_uid* LUID;
|
||||
|
||||
operator size_t () const { return lumiera_uid_hash ((LUID)&luid_); }
|
||||
bool operator== (LuidH const& o) const { return lumiera_uid_eq ((LUID)&luid_, (LUID)&o.luid_); }
|
||||
bool operator!= (LuidH const& o) const { return !operator== (o); }
|
||||
|
||||
/** for passing to C APIs */
|
||||
LUID get() { return &luid_; }
|
||||
};
|
||||
|
||||
|
||||
/* === for use within unordered_map === */
|
||||
size_t hash_value (Plain const& plainHash) { return plainHash; }
|
||||
size_t hash_value (LuidH const& luid_Hash) { return luid_Hash; }
|
||||
|
||||
} // namespace "hash"
|
||||
|
||||
struct LuidH
|
||||
{
|
||||
long dummy_;
|
||||
|
||||
LuidH() : dummy_(rand()) {}
|
||||
|
||||
bool operator== (LuidH const& o) const { return dummy_ == o.dummy_; }
|
||||
bool operator!= (LuidH const& o) const { return dummy_ != o.dummy_; }
|
||||
};
|
||||
|
||||
|
||||
/************************************************************
|
||||
* A Mixin to add a private ID type to the target class,
|
||||
* together with storage to hold an instance of this ID,
|
||||
* getter and setter, and a templated version of the ID type
|
||||
* which can be used to pass on specific subclass type info.
|
||||
* which can be used to pass specific subclass type info.
|
||||
*/
|
||||
template<class BA, class IMP>
|
||||
struct HashIndexed
|
||||
|
|
@ -106,6 +150,22 @@ namespace lib {
|
|||
Id (T const& ref) : ID (ref) {}
|
||||
};
|
||||
|
||||
|
||||
/** enables use of BA objects as keys within tr1::unordered_map */
|
||||
struct UseEmbeddedHash
|
||||
: public std::unary_function<BA, size_t>
|
||||
{
|
||||
size_t operator() (BA const& obj) const { return obj.getID(); }
|
||||
};
|
||||
|
||||
/** trivial hash functor using the ID as hash */
|
||||
struct UseHashID
|
||||
: public std::unary_function<ID, size_t>
|
||||
{
|
||||
size_t operator() (ID const& id) const { return id; }
|
||||
};
|
||||
|
||||
|
||||
ID const&
|
||||
getID () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,35 +30,35 @@
|
|||
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
namespace asset {
|
||||
|
||||
using std::string;
|
||||
using std::ostream;
|
||||
|
||||
/** top-level distinction of different Kinds of Assets.
|
||||
* For convienience, this classification is slightly denormalized,
|
||||
* as AUDIO, and VIDEO are both asset::Media objects, EFFECT and CODEC
|
||||
* are asset::Proc objects, while STRUCT and META refer directly to
|
||||
* the corresponding Interfaces asset::Struct and asset::Meta.
|
||||
*/
|
||||
enum Kind
|
||||
{
|
||||
AUDIO,
|
||||
VIDEO,
|
||||
EFFECT,
|
||||
CODEC,
|
||||
STRUCT,
|
||||
META
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* 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
|
||||
* are asset::Proc objects, while STRUCT and META refer directly to
|
||||
* the corresponding Interfaces asset::Struct and asset::Meta.
|
||||
*/
|
||||
enum Kind
|
||||
{ AUDIO
|
||||
, VIDEO
|
||||
, EFFECT
|
||||
, CODEC
|
||||
, STRUCT
|
||||
, META
|
||||
};
|
||||
|
||||
/*************************************
|
||||
* Tree like classification of Assets.
|
||||
* By virtue of the Category, Assets can be organized in nested bins (folders).
|
||||
* By virtue of the Category, Assets can be organised in nested bins (folders).
|
||||
* This includes the distinction of different kinds of Assets, like Audio, Video, Effects...
|
||||
*
|
||||
* @todo could be far more elaborate. could be a singleton like centralized tree, while
|
||||
* just holding references to Catetory nodes in the individual Asset. At the moment,
|
||||
* we use just the most simplistic implementation and handle Category objects
|
||||
* @todo could be far more elaborate. could be a singleton like centralised tree, while
|
||||
* just holding references to Category nodes in the individual Asset. At the moment,
|
||||
* we just use the most simplistic implementation and handle Category objects
|
||||
* using value semantics.
|
||||
*/
|
||||
class Category
|
||||
|
|
@ -70,21 +70,22 @@ namespace asset
|
|||
string path_;
|
||||
|
||||
public:
|
||||
Category (const Kind root, string subfolder ="")
|
||||
Category (const Kind root, string subfolder ="")
|
||||
: kind_(root), path_(subfolder) {};
|
||||
|
||||
bool operator== (const Category& other) const { return kind_== other.kind_ && path_== other.path_; }
|
||||
bool operator!= (const Category& other) const { return kind_!= other.kind_ || path_!= other.path_; }
|
||||
|
||||
bool hasKind (Kind refKind) const { return kind_ == refKind; }
|
||||
bool isWithin (const Category&) const;
|
||||
void setPath (const string & newpath) { this->path_ = newpath; }
|
||||
bool operator== (Category const& other) const { return kind_== other.kind_ && path_== other.path_; }
|
||||
bool operator!= (Category const& other) const { return kind_!= other.kind_ || path_!= other.path_; }
|
||||
|
||||
bool hasKind (Kind refKind) const { return kind_ == refKind; }
|
||||
bool isWithin (Category const&) const;
|
||||
void setPath (string const& newpath) { this->path_ = newpath; }
|
||||
|
||||
|
||||
operator string () const;
|
||||
|
||||
|
||||
friend size_t hash_value (const Category& cat)
|
||||
|
||||
|
||||
friend size_t
|
||||
hash_value (Category const& cat)
|
||||
{
|
||||
size_t hash = 0;
|
||||
boost::hash_combine(hash, cat.kind_);
|
||||
|
|
@ -92,7 +93,8 @@ namespace asset
|
|||
return hash;
|
||||
}
|
||||
|
||||
int compare (const Category& co) const
|
||||
int
|
||||
compare (Category const& co) const
|
||||
{
|
||||
int res = int(kind_) - int(co.kind_);
|
||||
if (0 != res)
|
||||
|
|
@ -100,12 +102,12 @@ namespace asset
|
|||
else
|
||||
return path_.compare (co.path_);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
inline ostream& operator<< (ostream& os, const Category& cago) { return os << string(cago); }
|
||||
|
||||
|
||||
|
||||
|
||||
inline ostream& operator<< (ostream& os, const Category& cago) { return os << string(cago); }
|
||||
|
||||
|
||||
|
||||
} // namespace asset
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace asset {
|
|||
/* ===== hash implementations ===== */
|
||||
|
||||
size_t
|
||||
hash_value (const Asset::Ident& idi)
|
||||
hash_value (Asset::Ident const& idi)
|
||||
{
|
||||
size_t hash = 0;
|
||||
boost::hash_combine(hash, idi.org);
|
||||
|
|
@ -58,23 +58,23 @@ namespace asset {
|
|||
}
|
||||
|
||||
size_t
|
||||
hash_value (const Asset& asset)
|
||||
hash_value (Asset const& asset)
|
||||
{
|
||||
return asset.getID();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* trivial hash functor.
|
||||
/**
|
||||
* trivial hash functor
|
||||
* returns any hash value unmodified.
|
||||
* For building a hashtable with keys
|
||||
* For building a hashtable with keys
|
||||
* already containing valid hash values.
|
||||
*/
|
||||
struct IdentityHash
|
||||
struct IdentityHash
|
||||
: public std::unary_function<size_t, size_t>
|
||||
{
|
||||
size_t
|
||||
operator() (size_t val) const { return val; }
|
||||
operator() (size_t val) const { return val; }
|
||||
};
|
||||
|
||||
typedef std::tr1::unordered_map<size_t, PAsset, IdentityHash> IdHashtable;
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ namespace asset {
|
|||
|
||||
|
||||
/**
|
||||
* Factory specialized for creating Media Asset objects.
|
||||
* Factory specialised for creating Media Asset objects.
|
||||
*/
|
||||
class MediaFactory : public lumiera::Factory<asset::Media>
|
||||
{
|
||||
|
|
@ -148,7 +148,7 @@ namespace asset {
|
|||
PType operator() (const string& file, const Category& cat);
|
||||
PType operator() (const string& file, asset::Kind);
|
||||
|
||||
PType operator() (Asset::Ident& key, const char* file); ///< convienience overload using C-String
|
||||
PType operator() (Asset::Ident& key, const char* file); ///< convenience overload using C-String
|
||||
PType operator() (const char* file, const Category& cat);
|
||||
PType operator() (const char* file, asset::Kind);
|
||||
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ out: dtor ~TargetObj(12) successful
|
|||
END
|
||||
|
||||
|
||||
PLANNED "HashIndexed_test" HashIndexed_test <<END
|
||||
TEST "HashIndexed_test" HashIndexed_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -25,12 +25,7 @@
|
|||
|
||||
#include "lib/hash-indexed.hpp"
|
||||
|
||||
//#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
|
||||
//using boost::format;
|
||||
//using std::string;
|
||||
using std::cout;
|
||||
#include <tr1/unordered_map>
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
@ -38,15 +33,20 @@ namespace test{
|
|||
|
||||
/* == a hierarchy of test-dummy objects to use the HashIndexed::ID == */
|
||||
|
||||
struct Base
|
||||
struct DummyAncestor
|
||||
{
|
||||
long ii_;
|
||||
long xyz_;
|
||||
};
|
||||
|
||||
struct TestB : Base, HashIndexed<TestB,LuidH> ///< Base class to mix in the hash ID facility
|
||||
struct TestB; ///< Base class to mix in the hash ID facility
|
||||
typedef HashIndexed<TestB, hash::LuidH> Mixin; ///< actual configuration of the mixin
|
||||
|
||||
struct TestB : DummyAncestor, Mixin
|
||||
{
|
||||
TestB () {}
|
||||
TestB (ID const& refID) : HashIndexed<TestB,LuidH>(refID) {}
|
||||
TestB (ID const& refID) : Mixin (refID) {}
|
||||
|
||||
bool operator== (TestB const& o) const { return this->getID() == o.getID(); }
|
||||
};
|
||||
struct TestDA : TestB {};
|
||||
struct TestDB : TestB {};
|
||||
|
|
@ -56,13 +56,33 @@ namespace test{
|
|||
|
||||
/***************************************************************************
|
||||
* @test proof-of-concept test for a generic hash based and typed ID struct.
|
||||
* @see lib::HashIndexed::Id
|
||||
* - check the various ctors
|
||||
* - check default assignment works properly
|
||||
* - check assumptions about memory layout
|
||||
* - check equality comparison
|
||||
* - extract LUID and then cast LUID back into ID
|
||||
* - use the embedded hash ID (LUID) as hashtable key
|
||||
*
|
||||
* @see lib::HashIndexed::Id
|
||||
* @see mobject::Placement real world usage example
|
||||
*/
|
||||
class HashIndexed_test : public Test
|
||||
{
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
run (Arg)
|
||||
{
|
||||
checkBasicProperties();
|
||||
checkLUID_passing();
|
||||
|
||||
// ---key-type-------+-value-+-hash-function---
|
||||
buildHashtable<TestB::Id<TestDB>, TestDB, TestB::UseHashID> ();
|
||||
buildHashtable<TestDB, TestDB, TestB::UseEmbeddedHash>();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
checkBasicProperties ()
|
||||
{
|
||||
TestB::Id<TestDA> idDA;
|
||||
|
||||
|
|
@ -72,8 +92,8 @@ namespace test{
|
|||
TestB::Id<TestDB> idDB2 (idDB1);
|
||||
|
||||
ASSERT (sizeof (idDB1) == sizeof (idDA) );
|
||||
ASSERT (sizeof (TestB::ID) == sizeof (LuidH));
|
||||
ASSERT (sizeof (TestDA) == sizeof (LuidH) + sizeof (Base));
|
||||
ASSERT (sizeof (TestB::ID) == sizeof (hash::LuidH));
|
||||
ASSERT (sizeof (TestDA) == sizeof (hash::LuidH) + sizeof (DummyAncestor));
|
||||
|
||||
ASSERT (idDA == bb.getID() );
|
||||
ASSERT (idDB1 == idDB2 ); // equality handled by the hash impl (here LuidH)
|
||||
|
|
@ -84,12 +104,58 @@ namespace test{
|
|||
|
||||
d2 = d1;
|
||||
ASSERT (d1.getID() == d2.getID()); // default assignment operator works as expected
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
checkLUID_passing ()
|
||||
{
|
||||
TestB::Id<TestDA> idOrig;
|
||||
|
||||
lumiera_uid plainLUID;
|
||||
lumiera_uid_copy (&plainLUID, idOrig.get());
|
||||
|
||||
// now, maybe after passing it through a Layer barrier...
|
||||
TestB::ID const& idCopy = reinterpret_cast<TestB::ID & > (plainLUID);
|
||||
|
||||
ASSERT (idOrig == idCopy);
|
||||
}
|
||||
|
||||
|
||||
template<class KEY, class VAL, class HashFunc>
|
||||
void
|
||||
buildHashtable ()
|
||||
{
|
||||
typedef std::tr1::unordered_map<KEY, VAL, HashFunc> Hashtable;
|
||||
|
||||
Hashtable tab;
|
||||
|
||||
VAL o1; KEY key1 (o1);
|
||||
VAL o2; KEY key2 (o2);
|
||||
VAL o3; KEY key3 (o3);
|
||||
|
||||
tab[key1] = o1; // store copy into hashtable
|
||||
tab[key2] = o2;
|
||||
tab[key3] = o3;
|
||||
|
||||
ASSERT (&o1 != &tab[key1]); // indeed a copy...
|
||||
ASSERT (&o2 != &tab[key2]);
|
||||
ASSERT (&o3 != &tab[key3]);
|
||||
|
||||
ASSERT (o1.getID() == tab[key1].getID()); // but "equal" by ID
|
||||
ASSERT (o2.getID() == tab[key2].getID());
|
||||
ASSERT (o3.getID() == tab[key3].getID());
|
||||
|
||||
ASSERT (o1.getID() != tab[key2].getID());
|
||||
ASSERT (o1.getID() != tab[key3].getID());
|
||||
ASSERT (o2.getID() != tab[key3].getID());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (HashIndexed_test, "unit common");
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::test
|
||||
|
|
|
|||
|
|
@ -758,9 +758,9 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
|
|||
}
|
||||
//}}}</pre>
|
||||
</div>
|
||||
<div title="BindingMO" modifier="Ichthyostega" modified="200905210149" created="200905210144" tags="def design discuss SessionLogic" changecount="2">
|
||||
<div title="BindingMO" modifier="Ichthyostega" modified="200905222252" created="200905210144" tags="def design discuss SessionLogic" changecount="4">
|
||||
<pre>Sometimes, two entities within the [[Session]] are deliberately associated, and this association has to carry some specific mappings between properties or facilities within the entities to be linked together. When this connection isn't just the [[Placement]] of an object, and isn't just a logical or structural relationship either &mdash; then we create an explicit Binding object to be stored into the session.
|
||||
* Connecting a [[Sequence|EDL]] gets connected to a certain [[Timeline]] also establishes a mapping between the possible media stream channels produced by the sequence and the real output slots found within the timeline.
|
||||
* When connecting a [[Sequence|EDL]] to a certain [[Timeline]], we also establish a mapping between the possible media stream channels produced by the sequence and the real output slots found within the timeline.
|
||||
* similarly, using a sequence within a [[meta-clip|VirtualClip]] requires to remember such a mapping.
|
||||
* another example is the root [[scope|PlacementScope]], which (conceptually) is a link between the definition part of the Session and the graph of MObjects, which are the session's contents.
|
||||
|
||||
|
|
@ -2810,7 +2810,7 @@ Placements have //value semantics,// i.e. we don't stress the identity of a plac
|
|||
|
||||
</pre>
|
||||
</div>
|
||||
<div title="PlacementIndex" modifier="Ichthyostega" modified="200905192358" created="200905090053" tags="SessionLogic spec impl draft" changecount="10">
|
||||
<div title="PlacementIndex" modifier="Ichthyostega" modified="200905232251" created="200905090053" tags="SessionLogic spec impl draft" changecount="11">
|
||||
<pre>An implementation facility used to keep track of individual Placements and their relations.
|
||||
Especially, the [[Session]] maintains such an index, allowing to use the (opaque) PlacementRef tags for referring to a specific "instance" of an MObject, //placed// in a unique way into the current session. And, moreover, this index allows for one placement referring to another placement, so to implement a //relative// placement mode. Because there is an index behind the scenes, it is possible to actually access such a referral in the reverse direction, which is necessary for implementing the desired placement behaviour (if an object instance used as anchor is moved, all objects placed relatively to it have to move accordingly, which necessiates finding those other objects).
|
||||
|
||||
|
|
@ -2828,7 +2828,7 @@ Alternatively, we could try to use a ''structure based index''. Following this i
|
|||
* this way, the "index" could be reduced to being the session datastructure itself.
|
||||
|
||||
|
||||
!supported operations {{red{WIP}}}
|
||||
!supported operations
|
||||
The placement index is utilized by editing operations, by executing the build process and besides these core operations it allows resolving PlacementRef objects (which possibly may have crossed layer boundaries). From these use cases we derive the following main operations to support:
|
||||
* find the actual [[Placement]] object for a given ID
|
||||
* find the //scope//&nbsp; a given placement resides in. More specifically, find the [[placement defining this scope|PlacementScope]]
|
||||
|
|
@ -2836,20 +2836,21 @@ The placement index is utilized by editing operations, by executing the build pr
|
|||
* add a new placement to a scope given as parameter
|
||||
* remove a placement from index
|
||||
|
||||
//does a placement need to know it's own ID?// Obviously, there needs to be a way to find out the ID for a given placement, especially in the following situations:
|
||||
//does a placement need to know it's own ID?// &nbsp; Obviously, there needs to be a way to find out the ID for a given placement, especially in the following situations:
|
||||
* for most of the operations above, when querying some additional informations from index for a given placement
|
||||
* to create a PlacementRef (this is a variant of the "shared ptr from this"-problem)
|
||||
On second sight, this problem seems to be quite nasty, because either we have to keep a second indext table for the reversed lookup (memory address -> ID), or have to tie the placement by a backlink when adding it to the index/session datastructure, or (at least) it forces us to store a copy of the ID //within// the placement itself. The last possibility seems to create the least impact; but implementing it this way effectively gears the implementation towards a hashtable based approach.
|
||||
On second sight, this problem seems to be quite nasty, because either we have to keep a second index table for the reversed lookup (memory address -> ID), or have to tie the placement by a backlink when adding it to the index/session datastructure, or (at least) it forces us to store a copy of the ID //within// the placement itself. The last possibility seems to create the least impact; but implementing it this way effectively gears the implementation towards a hashtable based approach.
|
||||
|
||||
!implementation {{red{WIP}}}
|
||||
Consequently, we incorporate a random hash (implemented as {{{LUID}}}) into the individual placement, this way creating an distinguishable //placement identity,// which is retained on copying of the placement. The actual ID tag is complemented by a compile time type (template parameter), thus allowing to pass on additional context information through API calls.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="PlacementRef" modifier="Ichthyostega" modified="200905192350" created="200905090032" tags="def spec draft" changecount="3">
|
||||
<div title="PlacementRef" modifier="Ichthyostega" modified="200905232242" created="200905090032" tags="def spec draft" changecount="4">
|
||||
<pre>A generic reference mechanism for Placements, as added to the current session.
|
||||
While this reference itself is not tied to the actual memory layout (meaning it's //not// a disguised pointer), the implementation relies on a [[placement index facility|PlacementIndex]] for tracking and retrieving the actual Placement implementation object.
|
||||
While this reference itself is not tied to the actual memory layout (meaning it's //not// a disguised pointer), the implementation relies on a [[placement index facility|PlacementIndex]] for tracking and retrieving the actual Placement implementation object. As a plus, this approach allows to //reverse// the relation denoted by such a reference, inasmuch it is possible to retrieve all other placements referring to a given target placement.
|
||||
|
||||
!questions {{red{WIP}}}
|
||||
Currently (5/09) ichthyo is in doubt what implementation to use best. It is clear that the PlacementRef needs to incorporate a simple ID as the only actual data in memory, so it can be downcasted to a POD and passed as such via LayerSeparationInterfaces. And, of course, this ID tag should be the one used by PlacementIndex for organising the Placement index entries, thus enabling the PlacementRef to be passed immediately to the underlying index for resolution. Thus, the design decision boils down to the question how to implement the ID tag.
|
||||
* a flat random hash, e.g. using a {{{LUID}}}?
|
||||
* a structure based index, which also denotes the position in the (tree like) datastructure (Sequences within the session)?
|
||||
!implementation {{red{WIP}}}
|
||||
From the usage context it is clear that the PlacementRef needs to incorporate a simple ID as the only actual data in memory, so it can be downcasted to a POD and passed as such via LayerSeparationInterfaces. And, of course, this ID tag should be the one used by PlacementIndex for organising the Placement index entries, thus enabling the PlacementRef to be passed immediately to the underlying index for resolution. Thus, this design decision is interconnected with the implementation technique used for the index (&rarr; PlacementIndex). From the requirement of the ID tag to be contained in a fixed sized storage, and also from the expected kinds of queries Ichthyo (5/09) choose to incorporate a {{{LUID}}} as a random hash immediately into the placement and build the ID tag on top of it.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="PlacementScope" modifier="Ichthyostega" modified="200905210132" created="200905120304" tags="SessionLogic spec draft" changecount="5">
|
||||
|
|
@ -3547,14 +3548,14 @@ Currently as of 5/09, this is an ongoing [[implementation and planning effort|Pl
|
|||
<div title="SessionInterface" modifier="Ichthyostega" modified="200904242109" created="200904242108" tags="SessionLogic GuiIntegration design draft discuss" changecount="2">
|
||||
<pre>{{red{WIP}}}</pre>
|
||||
</div>
|
||||
<div title="SessionLogic" modifier="Ichthyostega" modified="200904252317" created="200904242110" tags="overview" changecount="10">
|
||||
<div title="SessionLogic" modifier="Ichthyostega" modified="200905232229" created="200904242110" tags="overview" changecount="11">
|
||||
<pre>The Session contains all informations, state and objects to be edited by the User (&rarr;[[def|Session]]).
|
||||
As such, the SessionInterface is the main entrance point to Proc-Layer functionality, both for the primary EditingOperations and for playback/rendering processes.
|
||||
|
||||
Currently (as of 5/09), Ichthyo is [[targeting|PlanningSessionInMem]] a first preliminary implementation of the [[Session in Memory|SessionDataMem]]
|
||||
|
||||
!Design and handling of Objects within the Session
|
||||
Objects are attached and manipulated by [[placements|Placement]]; thus the organisation of these placements is part of the session data layout. They behave like //instances// of a given object, and at the same time define the "non-substancial" properties of the object, like its positions and relations. [[References|MObjectRef]] to these placement entries are handed out as parameters, both down to the [[Builder]] and from there to the render proceeses within the engine, but also to external parts within the GUI and in plugins.</pre>
|
||||
Objects are attached and manipulated by [[placements|Placement]]; thus the organisation of these placements is part of the session data layout. Effectively, such a placement within the session behaves like an //instances// of a given object, and at the same time it defines the "non-substantial" properties of the object, e.g. its positions and relations. [[References|MObjectRef]] to these placement entries are handed out as parameters, both down to the [[Builder]] and from there to the render processes within the engine, but also to external parts within the GUI and in plugins. The actual implementation of these object references is built on top of the PlacementRef tags, thus relying on the PlacementIndex the session maintains to keep track of all placements and their relations.</pre>
|
||||
</div>
|
||||
<div title="SessionOverview" modifier="Ichthyostega" modified="200811011805" created="200709272105" tags="design" changecount="29">
|
||||
<pre><<<
|
||||
|
|
|
|||
Loading…
Reference in a new issue