From 07146ad373fd7d7236eb21da91caf802dec905d6 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 24 Mar 2010 05:00:06 +0100 Subject: [PATCH] WIP parts of the EntryID implementation, refactor struct asset name generation --- src/proc/asset/entry-id.hpp | 106 +++++++++++++++- src/proc/asset/struct-factory-impl.hpp | 42 ++----- src/proc/asset/struct-scheme.hpp | 118 ++++++++++++++++++ tests/components/proc/asset/entry-id-test.cpp | 14 +-- 4 files changed, 238 insertions(+), 42 deletions(-) create mode 100644 src/proc/asset/struct-scheme.hpp diff --git a/src/proc/asset/entry-id.hpp b/src/proc/asset/entry-id.hpp index caeee79ae..08c4d9c54 100644 --- a/src/proc/asset/entry-id.hpp +++ b/src/proc/asset/entry-id.hpp @@ -44,21 +44,123 @@ #include "proc/asset.hpp" +#include "proc/asset/struct-scheme.hpp" +#include "lib/hash-indexed.hpp" +#include "lib/util.hpp" +#include namespace asset { + + using std::string; + namespace idi { + + using lib::hash::LuidH; + + typedef size_t HashVal; + + /** build up a hash value, packaged as LUID. + * @param sym symbolic ID-string to be hashed + * @param seed (optional) hash value to combine with the sym. + * @note This is a half baked preliminary solution. The issue here + * is that LUID has a fixed size of 128bit, whereas the hash values + * of the std library (and boost) have the smaller and platform dependent + * type of \c size_t. This hack here assumes that size_t corresponds to void*, + * which is correct for i386 and AMD64. LUID provides a hook for embedding a + * void* (setting the trailing bits to zero). Finally we reinterpret the + * char[] of the LUID as a LuidH class, which is ugly, but granted to work. + * @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 + */ + inline LuidH + buildHash (string const& sym, HashVal seed =0) + { + boost::hash_combine(seed, sym); + lumiera_uid tmpLUID; + lumiera_uid_set_ptr (&tmpLUID, reinterpret_cast (&seed)); + return reinterpret_cast (tmpLUID); + } + } + + + /** + * type erased baseclass + * for building a combined hash and symbolic ID. + */ + class BareEntryID + { + typedef lib::hash::LuidH LuidH; + + string symbol_; + LuidH hash_; + + public: + explicit + BareEntryID (string const& symbolID, HashVal seed =0) /////////////TODO couldn't this be protected? + : symbol_(util::sanitise(symbolID)) + , hash_(buildHash (symbol_, seed)) + { } + + + bool + isValid() const + { + return bool(hash_); + } + + string const& + getSym() const + { + return symbol_; + } + + LuidH const& + getHash() const + { + return hash_; + } + }; /** * thin ID with blah * * @see mobject::session::Track */ - template - class ID + template + class EntryID + : public BareEntryID { public: + EntryID() + : BareEntryID (idi::generateSymbolID(), getTypeHash()) + { } + + explicit + EntryID (string const& symbolID) + : BareEntryID (symbolID, getTypeHash()) + { } + + + /** generate an Asset identification tuple + * based on this EntryID's symbolic ID and type information. + * The remaining fields are filled in with hardwired defaults. + */ + Asset::Ident + getIdent() const + { + Category cat (STRUCT, idi::StructTraits::catFolder); + return Asset::Ident (name, cat); + } + + static idi::HashVal + getTypeHash() + { + Category cat (STRUCT, idi::StructTraits::catFolder); + return hash_value (cat); + } }; diff --git a/src/proc/asset/struct-factory-impl.hpp b/src/proc/asset/struct-factory-impl.hpp index eb3a08b25..6cf87e215 100644 --- a/src/proc/asset/struct-factory-impl.hpp +++ b/src/proc/asset/struct-factory-impl.hpp @@ -45,6 +45,8 @@ #include "proc/asset/track.hpp" #include "proc/asset/pipe.hpp" +#include "proc/asset/struct-scheme.hpp" + #include "lib/symbol.hpp" #include "lib/error.hpp" #include "lib/util.hpp" @@ -65,36 +67,9 @@ using lumiera::query::extractID; namespace asset { + using idi::StructTraits; - namespace { // structural asset ID scheme ///////////////////////////////////////////////////////////TICKET #565 - - template - struct Traits - { - static Symbol namePrefix; - static Symbol catFolder; - static Symbol idSymbol; - }; - - template<> Symbol Traits::namePrefix = "track"; - template<> Symbol Traits::catFolder = "tracks"; - template<> Symbol Traits::idSymbol = "track"; - - template<> Symbol Traits::namePrefix = "pipe"; - template<> Symbol Traits::catFolder = "pipes"; - template<> Symbol Traits::idSymbol = "pipe"; - - template<> Symbol Traits::namePrefix = "patt"; - template<> Symbol Traits::catFolder = "build-templates"; - template<> Symbol Traits::idSymbol = "procPatt"; - - template<> Symbol Traits::namePrefix = "tL"; - template<> Symbol Traits::catFolder = "timelines"; - template<> Symbol Traits::idSymbol = "timeline"; - - template<> Symbol Traits::namePrefix = "seq"; - template<> Symbol Traits::catFolder = "sequences"; - template<> Symbol Traits::idSymbol = "sequence"; + namespace { Symbol genericIdSymbol ("id"); @@ -102,6 +77,7 @@ namespace asset { + /** * Implementation details, especially concerning how configuration * queries are resolved and when to create new objects automatically. @@ -122,7 +98,7 @@ namespace asset { // does the query somehow specify the desired name-ID? string nameID = extractID (genericIdSymbol, query); if (isnil (nameID)) - nameID = extractID (Traits::idSymbol, query); + nameID = extractID (StructTraits::idSymbol, query); if (isnil (nameID)) { // no name-ID contained in the query... @@ -130,15 +106,15 @@ namespace asset { static int i=0; static format namePattern ("%s.%d"); static format predPattern ("%s(%s), "); - nameID = str(namePattern % Traits::namePrefix % (++i) ); + nameID = str(namePattern % StructTraits::namePrefix % (++i) ); name.insert(0, - str(predPattern % Traits::idSymbol % nameID )); + str(predPattern % StructTraits::idSymbol % nameID )); } ENSURE (!isnil (name)); ENSURE (!isnil (nameID)); ENSURE (contains (name, nameID)); - Category cat (STRUCT, Traits::catFolder); + Category cat (STRUCT, StructTraits::catFolder); return Asset::Ident (name, cat ); ///////////////////////TICKET #565 the ID field should be just the ID, the query should go into a dedicated "capabilities" field. } diff --git a/src/proc/asset/struct-scheme.hpp b/src/proc/asset/struct-scheme.hpp new file mode 100644 index 000000000..6c7b09a23 --- /dev/null +++ b/src/proc/asset/struct-scheme.hpp @@ -0,0 +1,118 @@ +/* + STRUCT-SCHEME.hpp - naming and designation scheme for structural assets + + Copyright (C) Lumiera.org + 2010, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +/** @file struct-scheme.hpp + ** Naming and labelling scheme for structural assets. + ** Preconfigured traits data for the relevant types encountered in + ** Lumiera's session data model. + ** + ** @see struct-factory-impl.hpp + ** @see entry-id.hpp + ** + */ + + +#ifndef ASSET_STRUCT_SCHEME_H +#define ASSET_STRUCT_SCHEME_H + + +//#include "proc/mobject/session.hpp" +//#include "proc/mobject/mobject.hpp" + +#include "lib/symbol.hpp" +//#include "lib/error.hpp" +//#include "lib/util.hpp" + +//#include + +#include +using boost::format; +/////////////////////////////////////////////////////////TODO needs to be pushed down into a *.cpp + +//using mobject::Session; +//using mobject::MObject; + +using lib::Symbol; +//using util::isnil; +//using util::contains; +//using asset::Query; +//using lumiera::query::LUMIERA_ERROR_CAPABILITY_QUERY; +//using lumiera::query::extractID; + +namespace asset{ + + class Track; + class Pipe; + class ProcPatt; + class Timeline; + class Sequence; + + namespace idi { + + // structural asset ID scheme ///////////////////////////////////////////////////////////TICKET #565 + + template + struct StructTraits + { + static Symbol namePrefix; + static Symbol catFolder; + static Symbol idSymbol; + }; + + template<> Symbol Traits::namePrefix = "track"; + template<> Symbol Traits::catFolder = "tracks"; + template<> Symbol Traits::idSymbol = "track"; + + template<> Symbol Traits::namePrefix = "pipe"; + template<> Symbol Traits::catFolder = "pipes"; + template<> Symbol Traits::idSymbol = "pipe"; + + template<> Symbol Traits::namePrefix = "patt"; + template<> Symbol Traits::catFolder = "build-templates"; + template<> Symbol Traits::idSymbol = "procPatt"; + + template<> Symbol Traits::namePrefix = "tL"; + template<> Symbol Traits::catFolder = "timelines"; + template<> Symbol Traits::idSymbol = "timeline"; + + template<> Symbol Traits::namePrefix = "seq"; + template<> Symbol Traits::catFolder = "sequences"; + template<> Symbol Traits::idSymbol = "sequence"; + + + + + template + inline string + generateSymbolID() + { + static uint i=0; + static format namePattern ("%s.%02d"); + /////////////////////////////////////////////////////////TODO needs to be pushed down into a *.cpp + + return str(namePattern % StructTraits::namePrefix % (++i) ); + } + + +}} // namespace asset::idi +#endif diff --git a/tests/components/proc/asset/entry-id-test.cpp b/tests/components/proc/asset/entry-id-test.cpp index 7d2583630..c8d958cca 100644 --- a/tests/components/proc/asset/entry-id-test.cpp +++ b/tests/components/proc/asset/entry-id-test.cpp @@ -46,7 +46,7 @@ using lumiera::error::LUMIERA_ERROR_WRONG_TYPE; namespace asset{ namespace test { - namespace { // Test data... + namespace { // Test definitions... struct Dummy { }; @@ -90,9 +90,9 @@ namespace test { DummyID dID1; DummyID dID2("strange"); DummyID dID3; - CHECK (dID1); - CHECK (dID2); - CHECK (dID3); + CHECK (dID1.isValid()); + CHECK (dID2.isValid()); + CHECK (dID3.isValid()); CHECK (dID1 != dID2); CHECK (dID2 != dID1); CHECK (dID2 != dID3); CHECK (dID3 != dID2); CHECK (dID1 != dID3); CHECK (dID3 != dID1); @@ -100,9 +100,9 @@ namespace test { TrackID tID1; TrackID tID2; TrackID tID3("special"); - CHECK (tID1); - CHECK (tID2); - CHECK (tID3); + CHECK (tID1.isValid()); + CHECK (tID2.isValid()); + CHECK (tID3.isValid()); CHECK (tID1 != tID2); CHECK (tID2 != tID1); CHECK (tID2 != tID3); CHECK (tID3 != tID2); CHECK (tID1 != tID3); CHECK (tID3 != tID1);