WIP: test driven brainstorming regarding sequence/timeline handling

This commit is contained in:
Fischlurch 2010-03-01 05:36:18 +01:00
parent c2cbe4c9e8
commit 4594ddde3a
8 changed files with 103 additions and 75 deletions

View file

@ -101,6 +101,8 @@ namespace lumiera {
answer_->insert (entry_Struct<Pipe> ("pipe(master), stream(video)"));
item<Pipe> (answer_, "") = item<Pipe>(answer_,"pipe(master), stream(video)");// use as default
answer_->insert (entry_Struct<Pipe> ("pipe(ambiance)"));
}
@ -108,7 +110,7 @@ namespace lumiera {
/* under some circumstances we need to emulate the behaviour *
* of a real resolution engine in a more detailed manner. *
* These case are hard wired in code below */
* The code below implements these cases hard wired. */
/** special case: create a new pipe with matching pipe and stream IDs on the fly when referred... */
bool
@ -130,14 +132,14 @@ namespace lumiera {
answer_->insert (entry<Pipe> (q, newPipe));
return true;
}
/** special case: create/retrieve new rocessing pattern for given stream ID... */
/** special case: create/retrieve new processing pattern for given stream ID... */
bool
MockTable::fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q, string const& streamID)
MockTable::fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q)
{
typedef const ProcPatt cPP;
typedef WrapReturn<cPP>::Wrapper Ptr;
Ptr newPP (Struct::create (Query<cPP> ("make(PP), "+q)));
Ptr newPP (Struct::create (Query<cPP> ("make(PP), "+q))); // magic token: bail out and invoke factory for new object
answer_->insert (entry<cPP> (q, newPP));
return true;
}

View file

@ -49,12 +49,9 @@
namespace lumiera
{
namespace query
{
namespace lumiera {
namespace query {
using asset::Pipe;
using asset::ProcPatt;
using asset::PProcPatt;
@ -69,8 +66,7 @@ namespace lumiera
namespace // internal details
{
namespace { // internal details
/** a traits-class to define the smart-ptr to wrap the result */
template<class TY>
@ -81,16 +77,18 @@ namespace lumiera
/** helper detecting if a query actually intended to retrieve a "default" object.
* This implementation is quite crude, of cours it would be necessary to actually
* This implementation is quite crude, of course it would be necessary actually to
* parse and evaluate the query. @note query is modified if "default" ... */
inline bool
is_defaults_query (string& query)
{
return !isnil (removeTerm ("default", query));
}
} // details (end)
/**
* the actual table holding preconfigured answers
* packaged as boost::any objects.
@ -112,7 +110,7 @@ namespace lumiera
bool detect_case (typename WrapReturn<TY>::Wrapper&, Query<TY>& q);
bool fabricate_matching_new_Pipe (Query<Pipe>& q, string const& pipeID, string const& streamID);
bool fabricate_just_new_Pipe (Query<Pipe>& q);
bool fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q, string const& streamID);
bool fabricate_ProcPatt_on_demand (Query<const ProcPatt>& q);
template<class TY>
bool set_new_mock_solution (Query<TY>& q, typename WrapReturn<TY>::Wrapper& candidate);
@ -184,7 +182,7 @@ namespace lumiera
if (!isnil (extractID("make", q)))
return false; // let the query fail here,
// so the invoking factory will go ahead
// and create a new object.
// and create a new object. (prevents infinite recursion)
const string pipeID = extractID("pipe", q);
const string streamID = extractID("stream", q);
@ -210,7 +208,7 @@ namespace lumiera
const string streamID = extractID("stream", q);
if (!candidate && !isnil(streamID))
return fabricate_ProcPatt_on_demand (q, streamID);
return fabricate_ProcPatt_on_demand (q);
q.clear();
return false;
@ -240,13 +238,11 @@ namespace lumiera
public:
// TODO: implementation of any additional functions on the ConfigRules inteface goes here
// TODO: implementation of any additional functions on the ConfigRules interface goes here
};
} // namespace query
} // namespace lumiera
}} // namespace lumiera::query
#endif

View file

@ -29,8 +29,8 @@
namespace asset
{
namespace asset {
using lumiera::P;
class Pipe;
@ -44,9 +44,9 @@ namespace asset
ID (size_t id);
ID (const Pipe&);
};
/**
* structural asset corresponding to some
* processing pipe for generating media output
@ -64,13 +64,13 @@ namespace asset
{
return static_cast<const ID<Pipe>& > (Asset::getID());
}
protected:
Pipe (const Asset::Ident&, PProcPatt& wiring, const string& pipeID, wstring shortName =wstring(), wstring longName =wstring()) ;
friend class StructFactory;
friend class StructFactoryImpl;
public:
const string& getPipeID() const { return pipeID_; }
const PProcPatt& getProcPatt() const { return wiringTemplate; }
@ -87,10 +87,10 @@ namespace asset
//
inline ID<Pipe>::ID(size_t id) : ID<Struct> (id) {};
inline ID<Pipe>::ID(const Pipe& pipe) : ID<Struct> (pipe.getID()) {};
} // namespace asset
#endif

View file

@ -33,6 +33,7 @@ namespace asset {
/** create an empty default configured Sequence */
Sequence::Sequence (const Asset::Ident& idi)
: Struct (idi)
// : track (makeDefaultTrack ())
// , clips (0)
{

View file

@ -33,6 +33,7 @@ namespace asset {
/** TODO??? */
Timeline::Timeline (const Asset::Ident& idi)
: Struct (idi)
// : track (makeDefaultTrack ())
// , clips (0)
{

View file

@ -24,7 +24,9 @@
#include "lib/test/run.hpp"
#include "proc/mobject/session.hpp"
#include "proc/mobject/session/fixture.hpp" // TODO only temporarily needed
#include "proc/assetmanager.hpp"
#include "proc/assetmanager.hpp" //////??
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "lib/lumitime.hpp"
#include "lib/util.hpp"
@ -42,6 +44,9 @@ namespace test {
using proc_interface::AssetManager;
using proc_interface::PAsset;
using asset::PTimeline;
using asset::PSequence;
using lumiera::Time;
@ -88,23 +93,23 @@ namespace test {
UNIMPLEMENTED ("how to refer to tracks...");
ASSERT (0 < sess->timelines.size());
Timeline& til = sess->timelines[0];
PTimeline til = sess->timelines[0];
ASSERT (0 < sess->sequences.size());
Sequence& seq = sess->sequences[0];
PSequence seq = sess->sequences[0];
ASSERT (isSameObject (seq, til.getSequence()));
ASSERT (isSameObject (seq, til->getSequence()));
//verify default timeline
Axis& axis = til.getAxis();
Axis& axis = til->getAxis();
ASSERT (Time(0) == axis.origin());
ASSERT (Time(0) == til.length()); ////////////////////////TICKET #177
ASSERT (Time(0) == til->length()); ////////////////////////TICKET #177
//verify global pipes
//TODO
//verify default sequence
Track rootTrack = seq.rootTrack();
Track rootTrack = seq->rootTrack();
ASSERT (rootTrack->isValid());
ASSERT (Time(0) == rootTrack->length());
ASSERT (0 == rootTrack->subTracks.size());

View file

@ -24,8 +24,12 @@
#include "lib/test/run.hpp"
#include "proc/mobject/session.hpp"
//#include "proc/mobject/session/fixture.hpp" // TODO only temporarily needed
#include "proc/assetmanager.hpp"
#include "proc/assetmanager.hpp" ///??
#include "proc/asset/timeline.hpp"
#include "proc/asset/sequence.hpp"
#include "proc/asset/pipe.hpp"
#include "lib/lumitime.hpp"
#include "lib/query.hpp"
#include "lib/util.hpp"
#include <iostream>
@ -42,13 +46,25 @@ namespace test {
using proc_interface::AssetManager;
using proc_interface::PAsset;
using asset::PTimeline;
using asset::PSequence;
using asset::Pipe;
using lumiera::Query;
using lumiera::Time;
/********************************************************************************
* @test verify retrieval and instance management of the top level facade objects
* as integrated with the session and high-level model.
*
* as integrated with the session and high-level model. Both sequences and
* timelines are at the same time structural assets and act as facades
* on the session API. Thus we can query specific instances from the
* struct factory or alternatively access them through the session.
* Moreover we can create new top level elements in the session
* just by querying the respective asset.
*
* @todo specify how deletion is handled
*
* @see session-structure-test.cpp
* @see Timeline
* @see Sequence
@ -63,52 +79,57 @@ namespace test {
ASSERT (Session::current.isUp());
verify_retrieval();
verify_creation();
}
void
verify_retrieval()
{
PSess sess = Session::current;
ASSERT (sess->isValid());
ASSERT (0 < sess->timelines.size());
PTimeline defaultTimeline = sess->defaults (Query<Timeline> ()); //////////////////////TICKET #549
Query<Timeline> query1 = "id("+defaultTimeline->getNameID()+").";
PTimeline queriedTimeline = asset::Struct::create (query1);
ASSERT (queriedTimeline);
ASSERT (queriedTimeline == defaultTimeline); // retrieved the existing timeline asset again
ASSERT (queriedTimeline == sess->timelines[0]);
Query<Sequence> query2 = "id("+defaultTimeline->getSequence()->getNameID()+").";
PSequence queriedSequence = asset::Struct::create (query2);
ASSERT (queriedSequence);
ASSERT (queriedSequence == sess->sequences[0]);
ASSERT (queriedSequence == sess->timelines[0]->getSequence());
ASSERT (queriedSequence == defaultTimeline->getSequence());
}
void
verify_creation()
{
PSess sess = Session::current;
ASSERT (sess->isValid());
uint num_timelines = sess->timelines.size();
ASSERT (0 < num_timelines);
ASSERT (0 < sess->timelines.size());
Timeline& til = sess->timelines[0];
Query<Timeline> special = "id(aSillyName), sequence("
+ sess->sequences[0]->getNameID()
+ "), pipe(ambiance).";
ASSERT (0 < sess->sequences.size());
Sequence& seq = sess->sequences[0];
PTimeline specialTimeline (asset::Struct::create (special));
ASSERT (specialTimeline);
ASSERT (num_timelines + 1 == sess->timelines.size());
ASSERT (specialTimeline == session->timelines[num_timelines]); // new one got appended at the end
ASSERT (isSameObject (seq, til.getSequence()));
// verify the properties
ASSERT (specialTimeline->getSequence() == sess->sequences[0]); // the already existing sequence got bound into that timeline too
ASSERT (contains (specialTimeline->pipes, Pipe::query("pipe(ambiance)")));
//verify default timeline
Axis& axis = til.getAxis();
ASSERT (Time(0) == axis.origin());
ASSERT (Time(0) == til.length()); ////////////////////////TICKET #177
//verify global pipes
//TODO
//verify default sequence
Track rootTrack = seq.rootTrack();
ASSERT (rootTrack->isValid());
ASSERT (Time(0) == rootTrack->length());
ASSERT (0 == rootTrack->subTracks.size());
ASSERT (0 == rootTrack->clips.size());
//TODO verify the output slots of the sequence
//TODO now use the generic query API to discover the same structure.
ASSERT (til == *(sess->all<Timeline>()));
ASSERT (seq == *(sess->all<Sequence>()));
ASSERT (rootTrack == *(sess->all<Track>()));
ASSERT (! sess->all<Clip>());
QueryFocus& focus = sess->focus();
ASSERT (rootTrack == focus.getObject());
focus.navigate (til);
ASSERT (til.getBinding() == focus.getObject());
ASSERT (rootTrack == *(focus.children()));
ASSERT (specialTimeline.use_count() == 3); // we, the AssetManager and the session
}
};

View file

@ -5794,7 +5794,7 @@ function addKeyDownHandlers(e)
<div title="TiddlyWiki" modifier="Ichthyostega" created="200706220430" changecount="1">
<pre>http://tiddlywiki.com/</pre>
</div>
<div title="Timeline" modifier="Ichthyostega" modified="201002270504" created="200706250721" tags="def" changecount="11">
<div title="Timeline" modifier="Ichthyostega" modified="201003010218" created="200706250721" tags="def" changecount="14">
<pre>Timeline is the top level element within the [[Session (Project)|Session]]. It is visible within a //timeline view// in the GUI and represents the effective (resulting) arrangement of media objects, to be rendered for output or viewed in a Monitor (viewer window). A timeline is comprised of:
* a time axis in abolute time ({{red{WIP 1/10}}}: not clear if this is an entity or just a conceptual definition)
* a PlayControler
@ -5808,6 +5808,8 @@ Within the Project, there may be ''multiple timelines'', to be viewed and render
!Façade and implementation
Actually, Timeline is both an interface and acts as façade. Its an interface, because we'll need &quot;timeline views&quot; ({{red{really? is that a reason to create a hierarchy right here, or shouldn't that be rather conceptual?}}}. It is a façade to the raw structures in the model, in this case a {{{Placement&lt;BindingMO&gt;}}} attached immediately below the [[root scope|ModelRootMO]]. The implementation of the timeline(s) is maintained as StructAsset {{red{Really? or should this be a ~MetaAsset??}}} within the AssetManager, managed by shared-ptr.
Besides building on the asset management, implementing Timeline (and Sequence) as StructAsset yields another benefit: ~StructAssets can be retrieved by query, allowing to specify more details of the configuration immediately on creation. //But on the short term, this approach causes problems:// there is no real inference engine integrated into Lumiera yet (as of 2/2010 the plan is to get an early alpha working end to end first). For now we're bound to use the {{{fake-configrules}}} and to rely on a hard wired simulation of the intended behaviour of a real query resolution. Just some special magic queries will work for now, but that's enough to get ahead.
</pre>
</div>
<div title="TimelineSequences" modifier="Ichthyostega" modified="200811022211" created="200811011836" tags="design draft discuss img" changecount="14">