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)")); answer_->insert (entry_Struct<Pipe> ("pipe(master), stream(video)"));
item<Pipe> (answer_, "") = item<Pipe>(answer_,"pipe(master), stream(video)");// use as default 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 * /* under some circumstances we need to emulate the behaviour *
* of a real resolution engine in a more detailed manner. * * 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... */ /** special case: create a new pipe with matching pipe and stream IDs on the fly when referred... */
bool bool
@ -130,14 +132,14 @@ namespace lumiera {
answer_->insert (entry<Pipe> (q, newPipe)); answer_->insert (entry<Pipe> (q, newPipe));
return true; 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 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 const ProcPatt cPP;
typedef WrapReturn<cPP>::Wrapper Ptr; 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)); answer_->insert (entry<cPP> (q, newPP));
return true; return true;
} }

View file

@ -49,12 +49,9 @@
namespace lumiera namespace lumiera {
{ namespace query {
namespace query
{
using asset::Pipe; using asset::Pipe;
using asset::ProcPatt; using asset::ProcPatt;
using asset::PProcPatt; 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 */ /** a traits-class to define the smart-ptr to wrap the result */
template<class TY> template<class TY>
@ -81,16 +77,18 @@ namespace lumiera
/** helper detecting if a query actually intended to retrieve a "default" object. /** 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" ... */ * parse and evaluate the query. @note query is modified if "default" ... */
inline bool inline bool
is_defaults_query (string& query) is_defaults_query (string& query)
{ {
return !isnil (removeTerm ("default", query)); return !isnil (removeTerm ("default", query));
} }
} // details (end) } // details (end)
/** /**
* the actual table holding preconfigured answers * the actual table holding preconfigured answers
* packaged as boost::any objects. * packaged as boost::any objects.
@ -112,7 +110,7 @@ namespace lumiera
bool detect_case (typename WrapReturn<TY>::Wrapper&, Query<TY>& q); 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_matching_new_Pipe (Query<Pipe>& q, string const& pipeID, string const& streamID);
bool fabricate_just_new_Pipe (Query<Pipe>& q); 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> template<class TY>
bool set_new_mock_solution (Query<TY>& q, typename WrapReturn<TY>::Wrapper& candidate); bool set_new_mock_solution (Query<TY>& q, typename WrapReturn<TY>::Wrapper& candidate);
@ -184,7 +182,7 @@ namespace lumiera
if (!isnil (extractID("make", q))) if (!isnil (extractID("make", q)))
return false; // let the query fail here, return false; // let the query fail here,
// so the invoking factory will go ahead // 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 pipeID = extractID("pipe", q);
const string streamID = extractID("stream", q); const string streamID = extractID("stream", q);
@ -210,7 +208,7 @@ namespace lumiera
const string streamID = extractID("stream", q); const string streamID = extractID("stream", q);
if (!candidate && !isnil(streamID)) if (!candidate && !isnil(streamID))
return fabricate_ProcPatt_on_demand (q, streamID); return fabricate_ProcPatt_on_demand (q);
q.clear(); q.clear();
return false; return false;
@ -240,13 +238,11 @@ namespace lumiera
public: 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::query
} // namespace lumiera
#endif #endif

View file

@ -29,8 +29,8 @@
namespace asset namespace asset {
{
using lumiera::P; using lumiera::P;
class Pipe; class Pipe;

View file

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

View file

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

View file

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

View file

@ -24,8 +24,12 @@
#include "lib/test/run.hpp" #include "lib/test/run.hpp"
#include "proc/mobject/session.hpp" #include "proc/mobject/session.hpp"
//#include "proc/mobject/session/fixture.hpp" // TODO only temporarily needed //#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/lumitime.hpp"
#include "lib/query.hpp"
#include "lib/util.hpp" #include "lib/util.hpp"
#include <iostream> #include <iostream>
@ -42,12 +46,24 @@ namespace test {
using proc_interface::AssetManager; using proc_interface::AssetManager;
using proc_interface::PAsset; using proc_interface::PAsset;
using asset::PTimeline;
using asset::PSequence;
using asset::Pipe;
using lumiera::Query;
using lumiera::Time; using lumiera::Time;
/******************************************************************************** /********************************************************************************
* @test verify retrieval and instance management of the top level facade objects * @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 session-structure-test.cpp
* @see Timeline * @see Timeline
@ -63,52 +79,57 @@ namespace test {
ASSERT (Session::current.isUp()); ASSERT (Session::current.isUp());
verify_retrieval(); verify_retrieval();
verify_creation();
} }
void void
verify_retrieval() 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; PSess sess = Session::current;
ASSERT (sess->isValid()); ASSERT (sess->isValid());
uint num_timelines = sess->timelines.size();
ASSERT (0 < num_timelines);
ASSERT (0 < sess->timelines.size()); Query<Timeline> special = "id(aSillyName), sequence("
Timeline& til = sess->timelines[0]; + sess->sequences[0]->getNameID()
+ "), pipe(ambiance).";
ASSERT (0 < sess->sequences.size()); PTimeline specialTimeline (asset::Struct::create (special));
Sequence& seq = sess->sequences[0]; 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 ASSERT (specialTimeline.use_count() == 3); // we, the AssetManager and the session
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()));
} }
}; };

View file

@ -5794,7 +5794,7 @@ function addKeyDownHandlers(e)
<div title="TiddlyWiki" modifier="Ichthyostega" created="200706220430" changecount="1"> <div title="TiddlyWiki" modifier="Ichthyostega" created="200706220430" changecount="1">
<pre>http://tiddlywiki.com/</pre> <pre>http://tiddlywiki.com/</pre>
</div> </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: <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 time axis in abolute time ({{red{WIP 1/10}}}: not clear if this is an entity or just a conceptual definition)
* a PlayControler * a PlayControler
@ -5808,6 +5808,8 @@ Within the Project, there may be ''multiple timelines'', to be viewed and render
!Façade and implementation !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. 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> </pre>
</div> </div>
<div title="TimelineSequences" modifier="Ichthyostega" modified="200811022211" created="200811011836" tags="design draft discuss img" changecount="14"> <div title="TimelineSequences" modifier="Ichthyostega" modified="200811022211" created="200811011836" tags="design draft discuss img" changecount="14">