rename Struct-Asset factory function to better reflect the semantics
This commit is contained in:
parent
da04e13213
commit
7c758b04db
14 changed files with 76 additions and 46 deletions
|
|
@ -71,7 +71,7 @@ namespace lumiera {
|
|||
|
||||
string capabilities (caps);
|
||||
Query<STRU> query (capabilities);
|
||||
Ptr obj = Struct::create (query);
|
||||
Ptr obj = Struct::retrieve (query);
|
||||
return AnyPair(query.asKey(), obj);
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ namespace lumiera {
|
|||
{
|
||||
typedef WrapReturn<Pipe>::Wrapper Ptr;
|
||||
|
||||
Ptr newPipe (Struct::create (pipeID, streamID));
|
||||
Ptr newPipe (Struct::retrieve (pipeID, streamID));
|
||||
answer_->insert (entry<Pipe> (q, newPipe));
|
||||
return true; // denotes query will now succeed...
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ namespace lumiera {
|
|||
{
|
||||
typedef WrapReturn<Pipe>::Wrapper Ptr;
|
||||
|
||||
Ptr newPipe (Struct::create (Query<Pipe> (string("make(PP), ")+q)));
|
||||
Ptr newPipe (Struct::retrieve (Query<Pipe> (string("make(PP), ")+q)));
|
||||
answer_->insert (entry<Pipe> (q, newPipe));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -147,7 +147,7 @@ namespace lumiera {
|
|||
typedef const ProcPatt cPP;
|
||||
typedef WrapReturn<cPP>::Wrapper Ptr;
|
||||
|
||||
Ptr newPP (Struct::create (Query<cPP> ("make(PP), "+q))); // magic token: bail out and invoke factory for new object
|
||||
Ptr newPP (Struct::retrieve (Query<cPP> ("make(PP), "+q))); // magic token: bail out and invoke factory for new object
|
||||
answer_->insert (entry<cPP> (q, newPP));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -176,10 +176,10 @@ namespace lumiera {
|
|||
break;
|
||||
}
|
||||
|
||||
if (!newTimeline) // no suitable Timeline found: create and attach new one
|
||||
newTimeline = Struct::create (Query<aTl> ("make(TL), "+query));
|
||||
// "make" magic token: bail out and invoke factory for new object
|
||||
answer_->insert (entry<aTl> (query, newTimeline)); // learn the found/created Timeline as new solution
|
||||
if (!newTimeline) // no suitable Timeline found: create and attach new one
|
||||
newTimeline = Struct::retrieve (Query<aTl> ("make(TL), "+query));
|
||||
// "make" magic token: bail out and invoke factory for new object
|
||||
answer_->insert (entry<aTl> (query, newTimeline)); // learn the found/created Timeline as new solution
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +208,7 @@ namespace lumiera {
|
|||
}
|
||||
|
||||
if (!newSequence)
|
||||
newSequence = Struct::create (Query<aSq> ("make(SQ), "+query)); // no suitable found: create and attach new Sequence
|
||||
newSequence = Struct::retrieve (Query<aSq> ("make(SQ), "+query)); // no suitable found: create and attach new Sequence
|
||||
|
||||
answer_->insert (entry<aSq> (query, newSequence));
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace asset {
|
|||
PPipe
|
||||
Pipe::query (string properties)
|
||||
{
|
||||
return Struct::create (Query<Pipe> (properties));
|
||||
return Struct::retrieve (Query<Pipe> (properties));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
** Like every structural asset, the creation of sequences happens automatically
|
||||
** on referral; Sequences can be queried from the StructFactory, providing additional
|
||||
** requested capabilities. Commonly clients will retrieve a given sequence by query
|
||||
** on the name-ID of the sequence: \c Struct::create(Query<Sequence> ("id(theName)."))
|
||||
** on the name-ID of the sequence: \c Struct::retrieve(Query<Sequence> ("id(theName)."))
|
||||
** Additionally, a specific root track may be requested: \c "id(theName),rootTrack(trackID)."
|
||||
**
|
||||
** @see Session
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace asset {
|
|||
|
||||
|
||||
/** storage for the static StructFactory instance */
|
||||
StructFactory Struct::create;
|
||||
StructFactory Struct::retrieve;
|
||||
|
||||
|
||||
/** using private implementation detail class */
|
||||
|
|
@ -77,8 +77,27 @@ namespace asset {
|
|||
{ }
|
||||
|
||||
|
||||
/** invoke the factory to create new Structural Asset.
|
||||
* This function skips the query and retrieval of existing
|
||||
* instances and immediately creates a new one.
|
||||
* @param nameID (optional) an ID to use; if omitted an ID
|
||||
* will be default created, based on the kind of Asset.
|
||||
* @throw error::Invalid in case of ID clash with an existing Asset
|
||||
* @return an Struct smart ptr linked to the internally registered smart ptr
|
||||
* created as a side effect of calling the concrete Struct subclass ctor.
|
||||
*/
|
||||
template<class STRU>
|
||||
P<STRU>
|
||||
StructFactory::newInstance (Symbol nameID)
|
||||
{
|
||||
Query<STRU> desired_name (isnil(nameID)? "" : "id("+nameID+")");
|
||||
STRU* pS = impl_->fabricate (desired_name);
|
||||
return AssetManager::instance().wrap (*pS);
|
||||
}
|
||||
|
||||
/** Factory method for Structural Asset instances.
|
||||
|
||||
|
||||
/** Retrieve a suitable Structural Asset instance, possibly create.
|
||||
* First tries to resolve the asset by issuing an capability query.
|
||||
* If unsuccessful, use some internally specialised ctor call.
|
||||
* @todo work out the struct asset naming scheme! /////////////////////////////////TICKET #565
|
||||
|
|
@ -90,11 +109,11 @@ namespace asset {
|
|||
* for both. The final algorithm to be implemented later should fabricate
|
||||
* \em first, and then then query as a second step to define the capabilities.
|
||||
* @return an Struct smart ptr linked to the internally registered smart ptr
|
||||
* created as a side effect of calling the concrete Struct subclass ctor.
|
||||
* created as a side effect of calling the concrete Struct subclass ctor.
|
||||
*/
|
||||
template<class STRU>
|
||||
P<STRU>
|
||||
StructFactory::operator() (const Query<STRU>& capabilities)
|
||||
StructFactory::operator() (Query<STRU> const& capabilities)
|
||||
{
|
||||
P<STRU> res;
|
||||
QueryHandler<STRU>& typeHandler = ConfigRules::instance();
|
||||
|
|
@ -157,5 +176,10 @@ namespace asset {
|
|||
template PTimeline StructFactory::operator() (const Query<Timeline>& query);
|
||||
template PSequence StructFactory::operator() (const Query<Sequence>& query);
|
||||
|
||||
template P<Pipe> StructFactory::newInstance (Symbol);
|
||||
template PProcPatt StructFactory::newInstance (Symbol);
|
||||
template PTimeline StructFactory::newInstance (Symbol);
|
||||
template PSequence StructFactory::newInstance (Symbol);
|
||||
|
||||
|
||||
} // namespace asset
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
** into the "bookkeeping view" as a specific Kind of Asset.
|
||||
** For the different \em kinds of Assets, we use sub-interfaces inheriting
|
||||
** from the general Asset interface, each of which expose a distinguishing feature.
|
||||
** In the case of structural assets, the key point is a naming scheme allowing for
|
||||
** retrieval of instances with specific capabilities; structural assets are created
|
||||
** In the case of structural assets, the key point is the ability to retrieve an
|
||||
** instance based on a capabilities query; structural assets are typically created
|
||||
** on demand, just by referral. Thus, the collection of these assets provides a map
|
||||
** for exploring the current session's structure and allow for tweaking of the
|
||||
** default behaviour.
|
||||
|
|
@ -63,6 +63,7 @@
|
|||
#include "lib/query.hpp"
|
||||
#include "lib/factory.hpp"
|
||||
#include "lib/singleton.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <string>
|
||||
|
|
@ -74,6 +75,7 @@ namespace asset {
|
|||
using std::string;
|
||||
using boost::scoped_ptr;
|
||||
using lumiera::Query;
|
||||
using lib::Symbol;
|
||||
|
||||
class Struct;
|
||||
class StructFactory;
|
||||
|
|
@ -98,13 +100,13 @@ namespace asset {
|
|||
* for later referral, search and attachment of metadata.
|
||||
*
|
||||
* Examples being tracks, sequences, timelines, pipes, processing patterns
|
||||
*
|
||||
* @todo WIP as of 1/2010. Need to integrate Sequences and Timelines
|
||||
* @note embedded access point to instance creation or retrieval
|
||||
* through the static field #retrieve
|
||||
*/
|
||||
class Struct : public Asset
|
||||
{
|
||||
public:
|
||||
static StructFactory create;
|
||||
static StructFactory retrieve;
|
||||
|
||||
virtual const ID<Struct>&
|
||||
getID() const ///< @return ID of kind asset::Struct
|
||||
|
|
@ -149,11 +151,13 @@ namespace asset {
|
|||
typedef P<asset::Struct> PType;
|
||||
|
||||
template<class STRU>
|
||||
P<STRU> operator() (const Query<STRU>& query); ////////////TODO for now we're just using a fake config query with preconfigured hardwired answers
|
||||
P<STRU> operator() (Query<STRU> const& query);
|
||||
|
||||
P<Pipe> operator() (string pipeID, string streamID);
|
||||
// P<Timeline> operator() (MORef<Binding>); ///////////TODO doesn't this create circular includes?? Any better idea how to refer to an existing binding?
|
||||
|
||||
template<class STRU>
|
||||
P<STRU> newInstance (Symbol nameID ="");
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
** Like every structural asset, the creation of timelines happens automatically
|
||||
** on referral; Timelines can be queried from the StructFactory, providing additional
|
||||
** requested capabilities. Commonly clients will retrieve a given timeline by query
|
||||
** on the name-ID of the timeline: \c Struct::create(Query<Timeline>("id(theName)."))
|
||||
** on the name-ID of the timeline: \c Struct::retrieve(Query<Timeline>("id(theName)."))
|
||||
** Additionally, the binding to a specific sequence may be established alongside:
|
||||
** \c "timeline(theTimelineName),bindSequence(theTimelineName,sequenceID)."
|
||||
**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
LUMIERA.hpp - global definitions and common types for the Proc-Layer
|
||||
COMMON.hpp - global definitions and common types for the Proc-Layer
|
||||
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
|
|
@ -22,10 +22,12 @@
|
|||
|
||||
*/
|
||||
|
||||
/** @file lumiera.hpp
|
||||
/** @file common.hpp
|
||||
** Basic set of definitions and includes commonly used together.
|
||||
** Including lumiera.hpp gives you a common set of elementary declarations
|
||||
** widely used within the C++ code of the Proc-Layer.
|
||||
** Including common.hpp gives you a common set of elementary declarations
|
||||
** widely used within the C++ code of the Proc-Layer. Besides that, this
|
||||
** header is used to attach the doxygen documentation comments for all
|
||||
** the primary Proc-Layer namespaces
|
||||
**
|
||||
** @see main.cpp
|
||||
** @see pre.hpp
|
||||
|
|
@ -34,8 +36,8 @@
|
|||
|
||||
|
||||
|
||||
#ifndef LUMIERA_H
|
||||
#define LUMIERA_H
|
||||
#ifndef PROC_COMMON_H
|
||||
#define PROC_COMMON_H
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ namespace asset
|
|||
normaliseID (pID_sane);
|
||||
ASSERT (pID_sane != pID);
|
||||
|
||||
PPipe thePipe = asset::Struct::create (pID,sID);
|
||||
PPipe thePipe = asset::Struct::retrieve (pID,sID);
|
||||
|
||||
ASSERT (thePipe);
|
||||
ASSERT (thePipe->getProcPatt());
|
||||
|
|
@ -139,9 +139,9 @@ namespace asset
|
|||
// several variants to query for "the default pipe"
|
||||
pipe2 = Session::current->defaults(Query<Pipe> ());
|
||||
ASSERT (pipe2 == pipe1);
|
||||
pipe2 = asset::Struct::create (Query<Pipe> ());
|
||||
pipe2 = asset::Struct::retrieve (Query<Pipe> ());
|
||||
ASSERT (pipe2 == pipe1);
|
||||
pipe2 = asset::Struct::create (Query<Pipe> ("pipe(default)"));
|
||||
pipe2 = asset::Struct::retrieve (Query<Pipe> ("pipe(default)"));
|
||||
ASSERT (pipe2 == pipe1);
|
||||
|
||||
string sID = popa->queryStreamID(); // sort of a "default stream type"
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ namespace asset {
|
|||
|
||||
// create Pipes explicitly
|
||||
// (without utilising default queries)
|
||||
PPipe pipe1 = Struct::create (newID("pipe"), newID("stream"));
|
||||
PPipe pipe2 = Struct::create (newID("pipe"), sID );
|
||||
PPipe pipe1 = Struct::retrieve (newID("pipe"), newID("stream"));
|
||||
PPipe pipe2 = Struct::retrieve (newID("pipe"), sID );
|
||||
|
||||
ASSERT (pipe1 != pipe2);
|
||||
ASSERT (sID == pipe2->getProcPatt()->queryStreamID());
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@ namespace test {
|
|||
ASSERT (pipe2 == pipe1);
|
||||
pipe2 = Session::current->defaults(Query<Pipe> ());
|
||||
ASSERT (pipe2 == pipe1);
|
||||
pipe2 = asset::Struct::create (Query<Pipe> ());
|
||||
pipe2 = asset::Struct::retrieve (Query<Pipe> ());
|
||||
ASSERT (pipe2 == pipe1);
|
||||
pipe2 = asset::Struct::create (Query<Pipe> ("default(P)"));
|
||||
pipe2 = asset::Struct::retrieve (Query<Pipe> ("default(P)"));
|
||||
ASSERT (pipe2 == pipe1);
|
||||
}
|
||||
|
||||
|
|
@ -169,7 +169,7 @@ namespace test {
|
|||
ASSERT (3 == pipe1.use_count()); // that's the problem; it should be 2
|
||||
|
||||
QueryHandler<Pipe>& typeHandler = ConfigRules::instance();
|
||||
PPipe pipe2 = asset::Struct::create (pID, "quatsch");
|
||||
PPipe pipe2 = asset::Struct::retrieve (pID, "quatsch");
|
||||
|
||||
typeHandler.resolve (pipe2, query_for_pID); // in the mock impl this has the side effect
|
||||
ASSERT (pipe2); // of replacing the mock entry
|
||||
|
|
|
|||
|
|
@ -181,13 +181,13 @@ namespace test {
|
|||
uint num_timelines = sess->timelines.size();
|
||||
CHECK (0 < num_timelines);
|
||||
|
||||
PTimeline specialTimeline (asset::Struct::create (Query<Timeline> ("id(testical)")));
|
||||
PTimeline specialTimeline (asset::Struct::retrieve (Query<Timeline> ("id(testical)")));
|
||||
CHECK (specialTimeline);
|
||||
CHECK (num_timelines + 1 == sess->timelines.size());
|
||||
CHECK (specialTimeline == sess->timelines[num_timelines]); // got appended at the end of the tracking table
|
||||
CHECK (specialTimeline.use_count() == 4); // we, the AssetManager and the session /////TODO plus one for fake-configrules
|
||||
|
||||
PTimeline anotherTimeline (asset::Struct::create (Query<Timeline> ()));
|
||||
PTimeline anotherTimeline (asset::Struct::retrieve (Query<Timeline> ()));
|
||||
CHECK (num_timelines + 2 == sess->timelines.size());
|
||||
CHECK (specialTimeline == sess->timelines[num_timelines]);
|
||||
CHECK (anotherTimeline == sess->timelines[num_timelines+1]); // new one got appended at the end
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ namespace test {
|
|||
CHECK (track3 == focus.getObject());
|
||||
|
||||
RTrack track31 = sess->attach(
|
||||
asset::Struct::create (Query<asset::Track> ("id(track31)")));
|
||||
asset::Struct::retrieve (Query<asset::Track> ("id(track31)")));
|
||||
|
||||
|
||||
CHECK (track31 == focus.getObject());
|
||||
|
|
|
|||
|
|
@ -105,13 +105,13 @@ namespace test {
|
|||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #499
|
||||
Query<Timeline> query1 = "id("+defaultTimeline->getNameID()+").";
|
||||
|
||||
PTimeline queriedTimeline = asset::Struct::create (query1);
|
||||
PTimeline queriedTimeline = asset::Struct::retrieve (query1);
|
||||
CHECK (queriedTimeline);
|
||||
CHECK (queriedTimeline == defaultTimeline); // retrieved the existing timeline asset again
|
||||
CHECK (queriedTimeline == sess->timelines[0]);
|
||||
|
||||
Query<Sequence> query2 = "id("+defaultTimeline->getSequence()->getNameID()+").";
|
||||
PSequence queriedSequence = asset::Struct::create (query2);
|
||||
PSequence queriedSequence = asset::Struct::retrieve (query2);
|
||||
CHECK (queriedSequence);
|
||||
CHECK (queriedSequence == sess->sequences[0]);
|
||||
CHECK (queriedSequence == sess->timelines[0]->getSequence());
|
||||
|
|
@ -134,7 +134,7 @@ namespace test {
|
|||
+ sess->sequences[0]->getNameID()
|
||||
+ "), pipe(ambiance).";
|
||||
|
||||
PTimeline specialTimeline (asset::Struct::create (special));
|
||||
PTimeline specialTimeline (asset::Struct::retrieve (special));
|
||||
CHECK (specialTimeline);
|
||||
CHECK (num_timelines + 1 == sess->timelines.size());
|
||||
CHECK (specialTimeline == session->timelines[num_timelines]); // new one got appended at the end
|
||||
|
|
@ -196,7 +196,7 @@ namespace test {
|
|||
|
||||
// create a new Timeline to play with, using the default sequence...
|
||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #499
|
||||
PTimeline aTimeline (asset::Struct::create (Query<Timeline> ("sequence("+
|
||||
PTimeline aTimeline (asset::Struct::retrieve (Query<Timeline> ("sequence("+
|
||||
+ sess->sequences[0]->getNameID()
|
||||
+ ").")));
|
||||
CHECK (num_timelines + 1 == sess->timelines.size());
|
||||
|
|
@ -235,7 +235,7 @@ namespace test {
|
|||
uint num_sequences = sess->sequences.size();
|
||||
|
||||
// create a new timeline, bound to a new sequence...
|
||||
PTimeline aTimeline (asset::Struct::create (Query<Timeline> ()));
|
||||
PTimeline aTimeline (asset::Struct::retrieve (Query<Timeline> ()));
|
||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #499
|
||||
PSequence aSequence (aTimeline->getSequence());
|
||||
CHECK (num_timelines + 1 == sess->timelines.size());
|
||||
|
|
|
|||
|
|
@ -5110,7 +5110,7 @@ Instead, we should try to just connect the various subsystems via Interfaces and
|
|||
* to shield the rendering code of all complexities of thread communication and synchronization, we use the StateProxy
|
||||
</pre>
|
||||
</div>
|
||||
<div title="StructAsset" modifier="Ichthyostega" modified="201002280044" created="200709221353" tags="def classes img" changecount="18">
|
||||
<div title="StructAsset" modifier="Ichthyostega" modified="201010290143" created="200709221353" tags="def classes img" changecount="19">
|
||||
<pre>Structural Assets are intended mainly for internal use, but the user should be able to see and query them. They are not "loaded" or "created" directly, rather they //leap into existence // by creating or extending some other structures in the session, hence the name. Some of the structural Asset parametrisation can be modified to exert control on some aspects of the Proc Layer's (default) behaviour.
|
||||
* [[Processing Patterns|ProcPatt]] encode information how to set up some parts of the render network to be created automatically: for example, when building a clip, we use the processing pattern how to decode and pre-process the actual media data.
|
||||
* [[Tracks|Track]] are one of the dimensions used for organizing the session data. They serve as an Anchor to attach parametrisation of output pipe, overlay mode etc. By [[placing|Placement]] to a track, a media object inherits placement properties from this track.
|
||||
|
|
@ -5123,7 +5123,7 @@ Instead, we should try to just connect the various subsystems via Interfaces and
|
|||
The Asset name field of structural Assets utilizes a special naming scheme, which allows to derive the name based on the capabilities of the structural asset. For example, by default all media clips with a given media stream type (e.g. H264) will use the same [[processing Pattern|ProcPatt]] for rendering. {{red{todo: work out the details of this naming scheme??}}}
|
||||
|
||||
!querying
|
||||
Structural assets can be queried by specifying the specific type (Pipe, Track, ProcPatt) and a query goal. For example, you can {{{Query<Pipe> ("stream(mpeg)")}}}, yielding the first pipe found which declares to have stream type "mpeg". The access point for this querying facility is on the ~StructFactory, which (as usual within Lumiera) can be invoked as {{{Struct::create(Query<...> ...}}}. Given such a query, first an attempt is made to satisfy it by retrieving an existing object (which might bind variables as a side effect). On failure, a new structural asset of the requested type will be created to satisfy the given goal.
|
||||
Structural assets can be queried by specifying the specific type (Pipe, Track, ProcPatt) and a query goal. For example, you can {{{Query<Pipe> ("stream(mpeg)")}}}, yielding the first pipe found which declares to have stream type "mpeg". The access point for this querying facility is on the ~StructFactory, which (as usual within Lumiera) can be invoked as static member {{{Struct::retrieve(Query<TY> ...}}}. Given such a query, first an attempt is made to satisfy it by retrieving an existing object of type TY (which might bind variables as a side effect). On failure, a new structural asset of the requested type will be created to satisfy the given goal. In case you want to bypass the resolution step and create a new asset right away, use {{{Struct::retrieve.newInstance<TY>}}}
|
||||
|
||||
{{red{Note:}}} in the current implementation no real resolution engine is used (as of 2/2010); rather, we're just able to retrieve a hard-wired answer or create a new asset, simply pattern matching on parts of the query.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue