Add test to cover the very basic MObject interface
This commit is contained in:
parent
b9e99a2be2
commit
48605827a6
7 changed files with 216 additions and 94 deletions
|
|
@ -95,12 +95,12 @@ namespace mobject {
|
|||
|
||||
virtual Time& getLength() =0; ///< @todo how to deal with the time/length field?? ////TICKET #448
|
||||
|
||||
virtual bool operator== (const MObject& oo) const =0;
|
||||
virtual bool operator== (const MObject& oo) const =0; ///< needed for handling by lumiera::P
|
||||
|
||||
protected:
|
||||
|
||||
virtual string initShortID() const =0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ namespace mobject {
|
|||
namespace session {
|
||||
|
||||
/** default/fallback implementation of equality
|
||||
* using literal object identity (same address)
|
||||
* using literal object identity (same address).
|
||||
* Required to enable handling by lumiera::P
|
||||
*/
|
||||
bool
|
||||
AbstractMO::operator== (const MObject& oo) const
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@ PLANNED "DeleteClip_test" DeleteClip_test <<END
|
|||
END
|
||||
|
||||
|
||||
TEST "verify MObject interface" MObjectInterface_test <<END
|
||||
out: Clip\.[0-9]{3}
|
||||
out: Label\.[0-9]{3}
|
||||
out: DummyMO\.[0-9]{3}
|
||||
END
|
||||
|
||||
|
||||
PLANNED "SessionElementTracker_test" SessionElementTracker_test <<END
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@
|
|||
/** @file mediaacessmock.cpp
|
||||
** Mock implementation of the Interface normally used to query media file
|
||||
** informations from the data backend. The Mock implementation instead holds
|
||||
** a map of fixed response which will be deliverd when querying some magic
|
||||
** a map of fixed response which will be delivered when querying some magic
|
||||
** filenames.
|
||||
**
|
||||
**
|
||||
** @see mediaaccessmocktest.cpp validating the Mock
|
||||
** @see MediaAccessFactory the real thing
|
||||
**
|
||||
|
|
@ -51,75 +51,72 @@ using std::vector;
|
|||
using std::map;
|
||||
|
||||
|
||||
namespace backend_interface
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
namespace backend_interface {
|
||||
namespace test {
|
||||
|
||||
typedef MediaAccessFacade::FileHandle FileHandle;
|
||||
typedef MediaAccessFacade::ChanHandle ChanHandle;
|
||||
|
||||
|
||||
namespace // implementation details
|
||||
{
|
||||
typedef vector<ChanDesc> Response;
|
||||
const ChanDesc NULLResponse;
|
||||
|
||||
|
||||
namespace { // implementation details
|
||||
|
||||
struct TestCases : map<string,Response>
|
||||
{
|
||||
TestCases ()
|
||||
{
|
||||
// ------------------------------------------------------------------TESTCASES
|
||||
(*this)["test-1"].push_back (ChanDesc ("video","ID", genH()));
|
||||
|
||||
(*this)["test-2"].push_back (ChanDesc ("video","H264", genH()));
|
||||
(*this)["test-2"].push_back (ChanDesc ("audio-L","PCM", genH()));
|
||||
(*this)["test-2"].push_back (ChanDesc ("audio-R","PCM", genH()));
|
||||
// ------------------------------------------------------------------TESTCASES
|
||||
}
|
||||
|
||||
bool known (string key)
|
||||
{
|
||||
const_iterator i = find (key);
|
||||
return (i != end());
|
||||
}
|
||||
private:
|
||||
int _i_;
|
||||
ChanHandle genH()
|
||||
{
|
||||
return reinterpret_cast<ChanHandle> (++_i_);
|
||||
}
|
||||
};
|
||||
|
||||
// instantiate TestCasses table
|
||||
TestCases testCases;
|
||||
|
||||
} // (end) implementation namespace
|
||||
|
||||
|
||||
FileHandle
|
||||
MediaAccessMock::queryFile (const char* name) throw(Invalid)
|
||||
{
|
||||
if (isnil (name))
|
||||
throw Invalid ("empty filename passed to MediaAccessFacade.");
|
||||
typedef vector<ChanDesc> Response;
|
||||
const ChanDesc NULLResponse;
|
||||
|
||||
if (!testCases.known(name))
|
||||
return 0;
|
||||
else
|
||||
return reinterpret_cast<void*> (&testCases[name]);
|
||||
}
|
||||
|
||||
ChanDesc
|
||||
MediaAccessMock::queryChannel (FileHandle h, uint chanNo) throw()
|
||||
{
|
||||
const Response* res (reinterpret_cast<Response*> (h));
|
||||
struct TestCases : map<string,Response>
|
||||
{
|
||||
TestCases ()
|
||||
{
|
||||
// ------------------------------------------------------------------TESTCASES
|
||||
(*this)["test-1"].push_back (ChanDesc ("video","ID", genH()));
|
||||
|
||||
(*this)["test-2"].push_back (ChanDesc ("video","H264", genH()));
|
||||
(*this)["test-2"].push_back (ChanDesc ("audio-L","PCM", genH()));
|
||||
(*this)["test-2"].push_back (ChanDesc ("audio-R","PCM", genH()));
|
||||
// ------------------------------------------------------------------TESTCASES
|
||||
}
|
||||
|
||||
bool known (string key)
|
||||
{
|
||||
const_iterator i = find (key);
|
||||
return (i != end());
|
||||
}
|
||||
private:
|
||||
int _i_;
|
||||
ChanHandle genH()
|
||||
{
|
||||
return reinterpret_cast<ChanHandle> (++_i_);
|
||||
}
|
||||
};
|
||||
|
||||
if (!res || res->size() <= chanNo)
|
||||
return NULLResponse;
|
||||
else
|
||||
return (*res)[chanNo];
|
||||
}
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace backend_interface
|
||||
// instantiate TestCasses table
|
||||
TestCases testCases;
|
||||
|
||||
} // (end) implementation namespace
|
||||
|
||||
|
||||
FileHandle
|
||||
MediaAccessMock::queryFile (const char* name) throw(Invalid)
|
||||
{
|
||||
if (isnil (name))
|
||||
throw Invalid ("empty filename passed to MediaAccessFacade.");
|
||||
|
||||
if (!testCases.known(name))
|
||||
return 0;
|
||||
else
|
||||
return reinterpret_cast<void*> (&testCases[name]);
|
||||
}
|
||||
|
||||
ChanDesc
|
||||
MediaAccessMock::queryChannel (FileHandle h, uint chanNo) throw()
|
||||
{
|
||||
const Response* res (reinterpret_cast<Response*> (h));
|
||||
|
||||
if (!res || res->size() <= chanNo)
|
||||
return NULLResponse;
|
||||
else
|
||||
return (*res)[chanNo];
|
||||
}
|
||||
|
||||
|
||||
}} // namespace backend_interface::test
|
||||
|
|
|
|||
|
|
@ -30,23 +30,20 @@
|
|||
|
||||
|
||||
|
||||
namespace backend_interface
|
||||
{
|
||||
namespace test
|
||||
namespace backend_interface {
|
||||
namespace test {
|
||||
|
||||
/**
|
||||
* Mock implementation of the MediaAccessFacade.
|
||||
* Provides preconfigured responses for some Test-Filenames.
|
||||
*/
|
||||
class MediaAccessMock : public MediaAccessFacade
|
||||
{
|
||||
/**
|
||||
* Mock implementation of the MediaAccessFacade.
|
||||
* Provides preconfigured responses for some Test-Filenames.
|
||||
*/
|
||||
class MediaAccessMock : public MediaAccessFacade
|
||||
{
|
||||
public:
|
||||
FileHandle queryFile (const char* name) throw(lumiera::error::Invalid);
|
||||
ChanDesc queryChannel (FileHandle, uint chanNo) throw();
|
||||
};
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace backend_interface
|
||||
public:
|
||||
FileHandle queryFile (const char* name) throw(lumiera::error::Invalid);
|
||||
ChanDesc queryChannel (FileHandle, uint chanNo) throw();
|
||||
};
|
||||
|
||||
|
||||
}} // namespace backend_interface::test
|
||||
#endif
|
||||
|
|
|
|||
120
tests/components/proc/mobject/mobject-interface-test.cpp
Normal file
120
tests/components/proc/mobject/mobject-interface-test.cpp
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
MObjectInterface(Test) - covers behaviour common to all MObjects
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2010, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
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.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/lumitime.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
|
||||
#include "proc/asset/media.hpp"
|
||||
#include "proc/mobject/mobject.hpp"
|
||||
#include "proc/mobject/session/mobjectfactory.hpp"
|
||||
//#include "proc/mobject/mobject-ref.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
//#include "proc/mobject/placement-ref.hpp"
|
||||
//#include "proc/mobject/session/placement-index.hpp"
|
||||
//#include "proc/mobject/session/session-service-mock-index.hpp"
|
||||
//#include "proc/mobject/session/clip.hpp"
|
||||
//#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
//#include "lib/test/test-helper.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
namespace mobject {
|
||||
namespace test {
|
||||
|
||||
// using lib::test::showSizeof;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using lib::Symbol;
|
||||
|
||||
|
||||
using lumiera::Time;
|
||||
// using session::Clip;
|
||||
// using session::PMedia;
|
||||
|
||||
|
||||
using namespace mobject::test;
|
||||
typedef TestPlacement<DummyMO> PDummy;
|
||||
|
||||
|
||||
/*********************************************************************************
|
||||
* @test cover the common behaviour of all MObjects.
|
||||
* @note the MObject interface is still very preliminary (as of 10/10).
|
||||
* It is expected to support some kind of metadata and object serialisation
|
||||
*
|
||||
* @see mobject::MObject
|
||||
* @see mobject::Placement
|
||||
*/
|
||||
class MObjectInterface_test : public Test
|
||||
{
|
||||
|
||||
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
PMO testClip1 = asset::Media::create("test-1", asset::VIDEO)->createClip();
|
||||
PMO testClip2 = asset::Media::create("test-2", asset::VIDEO)->createClip();
|
||||
|
||||
// set up a tie to fixed start positions (i.e. "properties of placement")
|
||||
testClip1.chain(Time(10));
|
||||
testClip2.chain(Time(20));
|
||||
|
||||
Symbol labelType ("dummyLabel");
|
||||
PMO testLabel1 = MObject::create (labelType);
|
||||
|
||||
testLabel1.chain(Time(30));
|
||||
|
||||
PDummy testDummy1(*new DummyMO);
|
||||
PDummy testDummy2(*new TestSubMO1);
|
||||
|
||||
ASSERT (testClip1->isValid());
|
||||
ASSERT (testClip2->isValid());
|
||||
ASSERT (testLabel1->isValid());
|
||||
ASSERT (testDummy1->isValid());
|
||||
ASSERT (testDummy2->isValid());
|
||||
|
||||
Time lenC1 = testClip1->getLength();
|
||||
Time lenC2 = testClip2->getLength();
|
||||
Time lenL1 = testLabel1->getLength();
|
||||
|
||||
cout << testClip1->shortID() << endl;
|
||||
cout << testClip2->shortID() << endl;
|
||||
cout << testLabel1->shortID() << endl;
|
||||
cout << testDummy1->shortID() << endl;
|
||||
cout << testDummy2->shortID() << endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (MObjectInterface_test, "unit session");
|
||||
|
||||
|
||||
}} // namespace mobject::test
|
||||
|
|
@ -1437,7 +1437,7 @@ More often than not, these emerge from immediate solutions, being percieved as e
|
|||
&rarr; [[accessing and integrating configuration queries|ConfigQueryIntegration]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="ConfigQueryIntegration" modifier="Ichthyostega" modified="201004030043" created="200804070247" tags="overview draft impl img" changecount="23">
|
||||
<div title="ConfigQueryIntegration" modifier="Ichthyostega" modified="201010140133" created="200804070247" tags="overview draft impl img" changecount="24">
|
||||
<pre>* planning to embed a YAP Prolog engine
|
||||
* currently just integrated by a table driven mock
|
||||
* the baseline is a bit more clear by now (4/08)
|
||||
|
|
@ -1465,7 +1465,7 @@ At various places, instead of requiring a fixed set of capabilities, it is possi
|
|||
<br/>
|
||||
<br/>
|
||||
|
||||
Access point is the interface {{{ConfigRules}}}, which allowes to resolve a ConfigQuery resulting in an object with properties configured such as to fulfill the query. This whole subsystem employes quite some generic programming, because actually we don't deal with "objects", but rather with similar instantiations of the same functionality for a collection of different object types. For the purpose of resolving these queries, the actual kind of object is not so much of importance, but on the caller sinde, of course we want to deal with the result of the queries in a typesafe manner.
|
||||
Access point is the interface {{{ConfigRules}}}, which allowes to resolve a ConfigQuery resulting in an object with properties configured such as to fulfill the query. This whole subsystem employes quite some generic programming, because actually we don't deal with "objects", but rather with similar instantiations of the same functionality for a collection of different object types. For the purpose of resolving these queries, the actual kind of object is not so much of importance, but on the caller side, of course we want to deal with the result of the queries in a typesafe manner.
|
||||
Examples for //participating object kinds// are [[pipes|Pipe]], [[processing patterns|ProcPatt]], effect instances, [[tags|Tag]], [[labels|Label]], [[automation data sets|AutomationData]],...
|
||||
@@clear(right):display(block):@@
|
||||
For this to work, we need each of the //participating object types// to provide the implementation of a generic interface {{{TypeHandler}}}, which allows to access actual C/C++ implementations for the predicates usable on objects of this type within the Prolog rules. The implementation has to make sure that, alongside with each config query, there are additional //type constraints// to be regarded. For example, if the client code runs a {{{Query<Pipe>}}}, an additional //type guard// (implemented by a predicate {{{type(pipe)}}} has to be inserted, so only rules and facts in accordance with this type will be used for resolution.
|
||||
|
|
@ -6419,7 +6419,7 @@ Just an ''registration scheme'' should be implemented right now, working complet
|
|||
see [[implementation planning|TypedLookup]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="TypedLookup" modifier="Ichthyostega" modified="201006250025" created="201004031607" tags="Rules spec impl draft" changecount="18">
|
||||
<div title="TypedLookup" modifier="Ichthyostega" modified="201010140129" created="201004031607" tags="Rules spec impl draft" changecount="19">
|
||||
<pre>TypedID is a registration service to associate object identities, symbolic identifiers and types. It acts as frontend to the TypedLookup service within Proc-Layer, at the implementation level. While TypedID works within a strictly typed context, this type information is translated into an internal index on passing over to the implementation, which manages a set of tables containing base entries with an combined symbolic+hash ID, plus an opaque buffer. Thus, the strictly typed context is required to re-access the stored data. But the type information wasn't erased entirely, so this typed context can be re-gained with the help of an internal type index. All of this is considered implementation detail and may be subject to change without further notice; any access is assumed to happen through the TypedID frontend. Besides, there are two more specialised frontends.
|
||||
|
||||
!Front-ends
|
||||
|
|
@ -6440,7 +6440,7 @@ In most cases, the //actually usable instance// of an entity isn't identical to
|
|||
!basic usage patterns
|
||||
* ''Assets'' are maintained by the AssetManager, which always holds a smart-ptr to the managed asset. Assets include explicit links to dependent assets. Thus, there is no point in interfering with lifecylce management, so we store just a ''weak reference'' here, which the access functor turns back into a smart-ptr, sharing ownership.
|
||||
* Plain ''~MObjects'' are somewhat similar, but there is no active lifecycle management &mdash; they are always tied either to a placement of linked from within the assets or render processes. When done, they just go out of scope. Thus we too use a ''weak reference'' here, thereby expecting the respective entity to mix in {{{TypedID::Link}}}
|
||||
* Active ''Placements'' of an MObject behave like //object instances// within the model/session. They live within the PlacementIndex and cary an unique {{{LUID}}}-ID. Thus, it's sufficient to store this ''Placement-ID'', which can be used by the access functor to fetch the corresponding Placement from the session.
|
||||
* Active ''Placements'' of an MObject behave like //object instances// within the model/session. They live within the PlacementIndex and cary an unique {{{LUID}}}-ID. Thus, it's sufficient to store this ''~Placement-ID'', which can be used by the access functor to fetch the corresponding Placement from the session.
|
||||
Obviously, the ~TypedLookup system is open for addition of completely separate and different types.
|
||||
[>img[TypedLookup implementation sketch|uml/fig140293.png]]
|
||||
|>| !Entity |!pattern |
|
||||
|
|
|
|||
Loading…
Reference in a new issue