ArgumentHolder finished, low-level integration test pass
This commit is contained in:
parent
63bad834c1
commit
c85d1d3cd8
7 changed files with 106 additions and 75 deletions
|
|
@ -128,7 +128,7 @@ namespace typelist{
|
|||
|
||||
template<typename SIG>
|
||||
function<SIG>&
|
||||
getFun ()
|
||||
getFun () const
|
||||
{
|
||||
return get<function<SIG> >();
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ namespace typelist{
|
|||
|
||||
template<typename SIG>
|
||||
SIG&
|
||||
getFun ()
|
||||
getFun () const
|
||||
{
|
||||
SIG *fun = get<SIG*>();
|
||||
REQUIRE (fun);
|
||||
|
|
|
|||
|
|
@ -22,18 +22,17 @@
|
|||
|
||||
|
||||
/** @file command-argument-holder.hpp
|
||||
** A simple container record holding the actual command arguments.
|
||||
** A passive container record holding the actual command arguments & UNDO state.
|
||||
** While all command objects themselves have a common type (type erasure),
|
||||
** the actual argument tuple and the state memento for undo can't. Especially,
|
||||
** the actual argument tuple and the state memento for UNDO can't. Especially,
|
||||
** the size of arguments and memento will depend on their respective types.
|
||||
** Thus, to manage somehow the storage of this data, we create a common holder,
|
||||
** to be managed by a custom allocator.
|
||||
** which can than be managed by a custom allocator / object pool.
|
||||
**
|
||||
** @todo doing just plain heap allocation for now :-P
|
||||
**
|
||||
** @see Command
|
||||
** @see UndoMutation
|
||||
** @see MementoTie
|
||||
** @see CmdClosure storage of command arguments
|
||||
** @see MementoTie wiring of UNDO functions & memento
|
||||
** @see UndoMutation execution of UNDO
|
||||
** @see command-argument-test.cpp
|
||||
**
|
||||
*/
|
||||
|
|
@ -43,20 +42,17 @@
|
|||
#ifndef CONTROL_COMMAND_ARGUMENT_HOLDER_H
|
||||
#define CONTROL_COMMAND_ARGUMENT_HOLDER_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
#include "proc/control/argument-tuple-accept.hpp"
|
||||
#include "proc/control/command-closure.hpp"
|
||||
#include "proc/control/memento-tie.hpp"
|
||||
#include "lib/opaque-holder.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
namespace control {
|
||||
|
||||
using boost::noncopyable;
|
||||
using lib::InPlaceBuffer;
|
||||
using std::string;
|
||||
|
||||
|
|
@ -96,14 +92,14 @@ namespace control {
|
|||
|
||||
|
||||
/**
|
||||
* Specifically typed CmdClosure, which serves for
|
||||
* Specifically typed CmdClosure, which serves for
|
||||
* actually allocating storage to hold the command arguments
|
||||
* and the undo state (memento) for Proc-Layer commands.
|
||||
* Both the contained components within ArgumentHolder
|
||||
* and the UNDO state (memento) for Proc-Layer commands.
|
||||
* Both the contained components within ArgumentHolder
|
||||
* can be in \em empty state; there are no distinct
|
||||
* lifecycle limitations. ArgumentHolder is part
|
||||
* of Proc-Layer command's implementation
|
||||
* and should not be used standalone.
|
||||
* and should not be used standalone.
|
||||
*/
|
||||
template<typename SIG, typename MEM>
|
||||
class ArgumentHolder
|
||||
|
|
@ -111,8 +107,10 @@ namespace control {
|
|||
, ArgumentHolder<SIG,MEM> // target class providing the implementation
|
||||
, CmdClosure // base class to inherit from
|
||||
>
|
||||
, private noncopyable
|
||||
{
|
||||
/** copy construction allowed(but no assignment)*/
|
||||
ArgumentHolder& operator= (ArgumentHolder const&);
|
||||
|
||||
|
||||
typedef Closure<SIG> ArgHolder;
|
||||
typedef MementoTie<SIG,MEM> MemHolder;
|
||||
|
|
@ -132,13 +130,14 @@ namespace control {
|
|||
|
||||
/* ==== proxied CmdClosure interface ==== */
|
||||
|
||||
public:
|
||||
virtual bool isValid () const
|
||||
{
|
||||
return arguments_->isValid();
|
||||
}
|
||||
|
||||
|
||||
virtual CmdFunctor bindArguments (CmdFunctor& func)
|
||||
virtual CmdFunctor bindArguments (CmdFunctor const& func)
|
||||
{
|
||||
if (!isValid())
|
||||
throw lumiera::error::State ("Lifecycle error: can't bind functor, "
|
||||
|
|
@ -158,7 +157,7 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/** per default, all data within ArgumentHolder
|
||||
* is set up in \em empty state. Later on, the
|
||||
* command arguments are to be provided by #bind ,
|
||||
|
|
@ -169,6 +168,16 @@ namespace control {
|
|||
, memento_()
|
||||
{ }
|
||||
|
||||
/** copy construction allowed(but no assignment) */
|
||||
ArgumentHolder (ArgumentHolder const& oAh)
|
||||
: arguments_()
|
||||
, memento_()
|
||||
{
|
||||
arguments_.template create<ArgHolder> (*oAh.arguments_);
|
||||
memento_.template create<MemHolder> (*oAh.memento_);
|
||||
}
|
||||
|
||||
|
||||
/** has undo state capturing been invoked? */
|
||||
bool canUndo () const { return memento_->isValid(); }
|
||||
bool empty () const { return !arguments_->isValid(); }
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ namespace control {
|
|||
|
||||
virtual bool isValid () const =0;
|
||||
|
||||
virtual CmdFunctor bindArguments (CmdFunctor&) =0;
|
||||
virtual CmdFunctor bindArguments (CmdFunctor const&) =0;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ namespace control {
|
|||
* can't be const.
|
||||
*/
|
||||
CmdFunctor
|
||||
bindArguments (CmdFunctor& unboundFunctor)
|
||||
bindArguments (CmdFunctor const& unboundFunctor)
|
||||
{
|
||||
return CmdFunctor (TupleApplicator<SIG> (params_)
|
||||
.bind ( unboundFunctor.getFun<SIG>()) );
|
||||
|
|
@ -221,7 +221,7 @@ namespace control {
|
|||
params_.dump (buff << "Closure(" );
|
||||
|
||||
string dumped (buff.str());
|
||||
if (1 < dumped.length())
|
||||
if (8 < dumped.length())
|
||||
// remove trailing comma...
|
||||
return dumped.substr (0, dumped.length()-1) +")";
|
||||
else
|
||||
|
|
|
|||
|
|
@ -7,11 +7,35 @@ PLANNED "CommandBasic_test" CommandBasic_test <<END
|
|||
END
|
||||
|
||||
|
||||
PLANNED "CommandArgument_test" CommandArgument_test <<END
|
||||
TEST "Argument & Memento handling" CommandArgument_test <<END
|
||||
out: Command-State. arguments=unbound, ·noUNDO·.
|
||||
out: capture state...
|
||||
out: Command-State. arguments=Closure\(\), ·noUNDO·.
|
||||
out: Command-State. arguments=Closure\(.\), ·noUNDO·.
|
||||
out: Command-State. arguments=Closure\(.,00:..:....00\), ·noUNDO·.
|
||||
out: Command-State. arguments=Closure\(00:..:....00,glorious,..\), <mem: destruction>.
|
||||
out: would be serialised.....Command-State. arguments=Closure\(\), ·noUNDO·.
|
||||
out: would be serialised.....Command-State. arguments=Closure\(.\), ·noUNDO·.
|
||||
out: would be serialised.....Command-State. arguments=Closure\(.,00:..:....00\), ·noUNDO·.
|
||||
out: would be serialised.....Command-State. arguments=Closure\(00:..:....00,glorious,..\), <mem: destruction>.
|
||||
out: sizeof\( .+control1.ArgumentHolder.+ \) = .+
|
||||
out: Command-State. arguments=Closure\(00:..:....00,Lumiera rocks,..\), ·noUNDO·.
|
||||
out: capture state...
|
||||
out: captured state: START...Lumiera rocks
|
||||
out: Command-State. arguments=Closure\(00:..:....00,Lumiera rocks,..\), <mem: START...Lumiera rocks>.
|
||||
out: invoke operation...
|
||||
out: START...doIt\( Time=00:..:....00 "Lumiera rocks" rand=.. \)
|
||||
out: undo... memento=START...Lumiera rocks
|
||||
out: START...doIt\( Time=00:..:....00 "Lumiera rocks" rand=.. \)undoIt\(time=00:..:....00\)----memento-:START...Lumiera rocks
|
||||
out: capture state...
|
||||
out: modified: Command-State. arguments=Closure\(00:00:00.123,unbelievable,..\), <mem: START...doIt\( Time=00:..:....00 "Lumiera rocks" rand=.. \)undoIt\(time=00:..:....00\)----memento-:START...Lumiera rocksLumiera rocks>.
|
||||
out: copied : Command-State. arguments=Closure\(00:..:....00,Lumiera rocks,..\), <mem: START...Lumiera rocks>.
|
||||
out: undo... memento=START...doIt\( Time=00:..:....00 "Lumiera rocks" rand=.. \)undoIt\(time=00:..:....00\)----memento-:START...Lumiera rocksLumiera rocks
|
||||
out: RESET...undoIt\(time=00:..:....00\)----memento-:START...doIt\( Time=00:..:....00 "Lumiera rocks" rand=.. \)undoIt\(time=00:..:....00\)----memento-:START...Lumiera rocksLumiera rocks
|
||||
END
|
||||
|
||||
|
||||
TEST "Command functor" CommandMutation_test <<END
|
||||
TEST "Command functor and UNDO functor" CommandMutation_test <<END
|
||||
out: Mutation\(untied\)
|
||||
out: param values: Closure\(23\)
|
||||
out: Mutation\(Closure\(23\)\)
|
||||
|
|
@ -27,6 +51,6 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
TEST "Memento binding" MementoTie_test <<END
|
||||
TEST "Memento wiring and storage" MementoTie_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
|
|
|||
|
|
@ -23,43 +23,25 @@
|
|||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
//#include "proc/asset/media.hpp"
|
||||
//#include "proc/mobject/session.hpp"
|
||||
//#include "proc/mobject/session/edl.hpp"
|
||||
//#include "proc/mobject/session/testclip.hpp"
|
||||
//#include "proc/mobject/test-dummy-mobject.hpp"
|
||||
//#include "lib/p.hpp"
|
||||
//#include "proc/mobject/placement.hpp"
|
||||
//#include "proc/mobject/placement-index.hpp"
|
||||
//#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/control/command-argument-holder.hpp"
|
||||
#include "lib/scoped-ptrvect.hpp"
|
||||
#include "lib/lumitime-fmt.hpp"
|
||||
//#include "lib/meta/typelist.hpp"
|
||||
//#include "lib/meta/tuple.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <tr1/functional>
|
||||
#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
//using std::tr1::bind;
|
||||
//using std::tr1::placeholders::_1;
|
||||
//using std::tr1::placeholders::_2;
|
||||
//using std::tr1::function;
|
||||
using util::isnil;
|
||||
//using util::and_all;
|
||||
using util::for_each;
|
||||
using boost::format;
|
||||
using lumiera::Time;
|
||||
//using util::contains;
|
||||
using boost::format;
|
||||
using std::string;
|
||||
using std::rand;
|
||||
using std::ostream;
|
||||
using std::ostringstream;
|
||||
using std::rand;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
|
@ -70,13 +52,6 @@ namespace test {
|
|||
using lib::test::showSizeof;
|
||||
using lib::test::randTime;
|
||||
|
||||
// using session::test::TestClip;
|
||||
// using lumiera::P;
|
||||
// using namespace lumiera::typelist;
|
||||
// using lumiera::typelist::Tuple;
|
||||
|
||||
// using control::CmdClosure;
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -87,6 +62,10 @@ namespace test {
|
|||
ostringstream protocol; ///< used to verify the test function calls
|
||||
|
||||
|
||||
/**
|
||||
* watching the instance creation
|
||||
* of some parameter values
|
||||
*/
|
||||
template<typename TY>
|
||||
struct Tracker
|
||||
{
|
||||
|
|
@ -116,26 +95,32 @@ namespace test {
|
|||
int Tracker<TY>::instanceCnt (0);
|
||||
|
||||
|
||||
/* === functions to implement test-"operation" & UNDO === */
|
||||
|
||||
void
|
||||
doIt (Tracker<Time> time, Tracker<string> str, int rand)
|
||||
{
|
||||
static format fmt ("doIt( Time=%s \"%s\" rand=%2d )");
|
||||
cout << "invoke operation..." << endl;
|
||||
protocol << fmt % *time % *str % rand;
|
||||
}
|
||||
|
||||
Tracker<string>
|
||||
captureState (Tracker<Time>, Tracker<string> xstr, int)
|
||||
{
|
||||
cout << "capture state..." << endl;
|
||||
return protocol.str() + *xstr;
|
||||
}
|
||||
|
||||
void
|
||||
undoIt (Tracker<Time> time, Tracker<string>, int, Tracker<string> memento)
|
||||
{
|
||||
protocol << "undoIt(time="<<time<<")---state-was-:"<< *memento;
|
||||
cout << "undo... memento=" << memento << endl;
|
||||
protocol << "undoIt(time="<<time<<")----memento-:"<< *memento;
|
||||
}
|
||||
|
||||
|
||||
/// another dummy-UNDO function
|
||||
void dummyU (int,int,int) { }
|
||||
int dummyC (int u,int o) { return u + rand() % (o-u+1); }
|
||||
|
||||
|
|
@ -163,11 +148,12 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
|
||||
typedef lib::ScopedPtrVect<CmdClosure> ArgTuples;
|
||||
|
||||
/***************************************************************************
|
||||
* @test Check storage handling of the command parameters and state memento.
|
||||
*
|
||||
*
|
||||
* @see control::CommandArgumentHolder
|
||||
* @see command-basic-test.hpp
|
||||
*/
|
||||
|
|
@ -186,16 +172,20 @@ namespace test {
|
|||
serialiseArgTuples (testTuples);
|
||||
testTuples.clear();
|
||||
|
||||
// simulateCmdLifecycle();
|
||||
simulateCmdLifecycle();
|
||||
|
||||
// verify all dtors properly called...
|
||||
ASSERT (0 == Tracker<Time>::instanceCnt);
|
||||
ASSERT (0 == Tracker<string>::instanceCnt);
|
||||
}
|
||||
|
||||
|
||||
typedef Tracker<Time> TTime;
|
||||
typedef Tracker<string> Tstr;
|
||||
typedef struct{ int i[5]; } Sint5;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/** @test create various argument tuples and re-access their contents */
|
||||
void
|
||||
|
|
@ -234,7 +224,7 @@ namespace test {
|
|||
|
||||
arg5->tie(undoIt, captureState)
|
||||
.tieCaptureFunc() // bind capturing function to memento storage,
|
||||
(TTime(), Tstr("destruction"), 11); // then invoke the bound capturing mechanism
|
||||
(TTime(), Tstr("destruction"), 11); // then invoke the bound capturing mechanism
|
||||
|
||||
ASSERT (arg5->canUndo());
|
||||
ASSERT (*arg5->memento() == "destruction");
|
||||
|
|
@ -245,6 +235,7 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/** @test serialise and de-serialise each tuple and check validity
|
||||
* @todo unimplemented, waiting on Serialiser
|
||||
*/
|
||||
|
|
@ -255,6 +246,7 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/** @test verify the comparison operators */
|
||||
void
|
||||
checkArgumentComparison ()
|
||||
|
|
@ -298,37 +290,43 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
#if false ////////////////////////////////////////////////////////////////////////////TODO.....
|
||||
/** @test simulate a complete command lifecycle with regards to
|
||||
* the storage handling of the command parameters and state memento.
|
||||
|
||||
/** @test simulate a complete command lifecycle with regards to the
|
||||
* storage handling of the command parameters and state memento.
|
||||
*/
|
||||
void
|
||||
simulateCmdLifecycle()
|
||||
{
|
||||
typedef void SIG_do(Tracker<Time>, Tracker<string>, int);
|
||||
typedef ArgumentHolder<SIG_do, Tracker<string> > Args;
|
||||
typedef MementoTie<SIG_do, Tracker<string> > MemHolder;
|
||||
typedef ArgumentHolder<SIG_do, Tracker<string> > Args;
|
||||
typedef MementoTie<SIG_do, Tracker<string> > MemHolder;
|
||||
|
||||
Args args;
|
||||
ASSERT (isnil (args));
|
||||
cout << showSizeof(args) << endl;
|
||||
|
||||
args.bind (randTime(), "Lumiera rocks". rand() % 100);
|
||||
// store a set of parameter values, later to be used on invocation
|
||||
args.bind (TTime(randTime()), Tstr("Lumiera rocks"), rand() % 100);
|
||||
ASSERT (!isnil (args));
|
||||
cout << args << endl;
|
||||
|
||||
ASSERT (!args.canUndo());
|
||||
ASSERT (isnil (args.memento()));
|
||||
VERIFY_ERROR(MISSING_MEMENTO, args.memento() );
|
||||
|
||||
MemHolder& memHolder = args.tie(undoIt,captureState);
|
||||
ASSERT (!memHolder); // no stored memento....
|
||||
ASSERT (!args.canUndo());
|
||||
|
||||
function<SIG_do> doItFun = doIt;
|
||||
function<SIG_do> undoFun = memHolder.tieUndoFunc();
|
||||
function<SIG_do> captFun = memHolder.tieCaptureFunc();
|
||||
|
||||
CmdFunctor bound_doItFun = args.bindArguments (CmdFunctor(doItFun));
|
||||
CmdFunctor bound_undoFun = args.bindArguments (CmdFunctor(undoFun));
|
||||
CmdFunctor bound_captFun = args.bindArguments (CmdFunctor(captFun));
|
||||
typedef function<void()> OpFun;
|
||||
|
||||
// now close all the functions with the stored parameter values...
|
||||
OpFun bound_doItFun = args.bindArguments (CmdFunctor(doItFun)).getFun<void()>();
|
||||
OpFun bound_undoFun = args.bindArguments (CmdFunctor(undoFun)).getFun<void()>();
|
||||
OpFun bound_captFun = args.bindArguments (CmdFunctor(captFun)).getFun<void()>();
|
||||
|
||||
protocol.seekp(0);
|
||||
protocol << "START...";
|
||||
|
|
@ -336,8 +334,9 @@ namespace test {
|
|||
bound_captFun();
|
||||
cout << "captured state: " << args.memento() << endl;
|
||||
ASSERT (memHolder);
|
||||
ASSERT (!isnil (args.memento()));
|
||||
ASSERT (!isnil (*args.memento()));
|
||||
ASSERT (args.canUndo());
|
||||
cout << args << endl;
|
||||
|
||||
bound_doItFun();
|
||||
cout << protocol.str() << endl;
|
||||
|
|
@ -350,14 +349,14 @@ namespace test {
|
|||
protocol.seekp(0);
|
||||
protocol << "RESET...";
|
||||
|
||||
args.bind (123456, "unbelievable", rand() %100);
|
||||
cout << "original: " << args << endl;
|
||||
cout << "copied : " << argsCopy << endl;
|
||||
args.bind (TTime(Time(123456)), Tstr("unbelievable"), rand() %100);
|
||||
cout << "modified: " << args << endl;
|
||||
cout << "copied : " << argsCopy << endl; // holds still the old params & memento
|
||||
|
||||
bound_undoFun();
|
||||
cout << protocol.str() << endl;
|
||||
}
|
||||
#endif ////////////////////////////////////////////////////////////////////////////TODO.....
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ test_lib_SOURCES = \
|
|||
$(testlib_srcdir)/factory-special-test.cpp \
|
||||
$(testlib_srcdir)/factorytest.cpp \
|
||||
$(testlib_srcdir)/format-helper-test.cpp \
|
||||
$(testlib_srcdir)/functor-util-test.cpp \
|
||||
$(testlib_srcdir)/hash-indexed-test.cpp \
|
||||
$(testlib_srcdir)/helloworldtest.cpp \
|
||||
$(testlib_srcdir)/lifecycletest.cpp \
|
||||
|
|
|
|||
|
|
@ -26,11 +26,9 @@
|
|||
//#include "lib/util.hpp"
|
||||
#include "lib/functor-util.hpp"
|
||||
|
||||
//#include <boost/lexical_cast.hpp>
|
||||
#include <tr1/functional>
|
||||
#include <iostream>
|
||||
|
||||
//using boost::lexical_cast;
|
||||
//using util::isnil;
|
||||
//using std::string;
|
||||
using std::cout;
|
||||
|
|
@ -91,7 +89,7 @@ namespace test {
|
|||
|
||||
f1 = f2;
|
||||
ASSERT ( rawComparison(f1, f2));
|
||||
|
||||
|
||||
ASSERT (!rawComparison(f0, Fvi())); // note: can't detect they are equivalent
|
||||
ASSERT (!rawComparison(f0, Fiv()));
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue