rename Struct-Asset factory function to better reflect the semantics

This commit is contained in:
Fischlurch 2010-10-29 04:28:46 +02:00
parent da04e13213
commit 7c758b04db
14 changed files with 76 additions and 46 deletions

View file

@ -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;

View file

@ -58,7 +58,7 @@ namespace asset {
PPipe
Pipe::query (string properties)
{
return Struct::create (Query<Pipe> (properties));
return Struct::retrieve (Query<Pipe> (properties));
}
void

View file

@ -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

View file

@ -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

View file

@ -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 ="");
};

View file

@ -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)."
**

View file

@ -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

View file

@ -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"

View file

@ -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());

View file

@ -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

View file

@ -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

View file

@ -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());

View file

@ -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());

View file

@ -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 &quot;loaded&quot; or &quot;created&quot; 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&lt;Pipe&gt; (&quot;stream(mpeg)&quot;)}}}, yielding the first pipe found which declares to have stream type &quot;mpeg&quot;. The access point for this querying facility is on the ~StructFactory, which (as usual within Lumiera) can be invoked as {{{Struct::create(Query&lt;...&gt; ...}}}. 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&lt;Pipe&gt; (&quot;stream(mpeg)&quot;)}}}, yielding the first pipe found which declares to have stream type &quot;mpeg&quot;. 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&lt;TY&gt; ...}}}. 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&lt;TY&gt;}}}
{{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.