WIP: test-driven brainstorming... how to capture state and params.

This commit is contained in:
Fischlurch 2009-06-19 05:57:06 +02:00
parent 42fd494443
commit 0ab5a92629
6 changed files with 297 additions and 29 deletions

View file

@ -44,8 +44,8 @@
#ifndef CONTROL_COMMAND_H
#define CONTROL_COMMAND_H
#ifndef CONTROL_COMMAND_DEF_H
#define CONTROL_COMMAND_DEF_H
//#include "pre.hpp"
#include "include/symbol.hpp"

View file

@ -36,6 +36,7 @@
#define CONTROL_MUTATION_H
//#include "pre.hpp"
#include "lib/error.hpp"
//#include <tr1/memory>
@ -54,10 +55,53 @@ namespace control {
{
public:
template<typename SIG>
Mutation (function<SIG> const& func)
{
UNIMPLEMENTED ("build a Mutation functor object, thereby erasing the concrete function signature type");
}
virtual ~Mutation() {}
virtual Mutation&
close (CmdClosure const& closure)
{
UNIMPLEMENTED ("accept and store a parameter closure");
}
void
operator() ()
{
UNIMPLEMENTED ("invoke the Mutation functor");
}
/* == diagnostics == */
typedef pClo Mutation::*_unspecified_bool_type;
/** implicit conversion to "bool" */
operator _unspecified_bool_type() const { return isValid()? &Mutation::clo_ : 0; } // never throws
bool operator! () const { return !isValid(); } // ditto
operator string() const
{
return isValid()? string (*clo) : "Mutation(state missing)";
}
protected:
virtual bool
isValid ()
{
UNIMPLEMENTED ("mutation lifecycle");
}
};
inline ostream& operator<< (ostream& os, const Mutation& muta) { return os << string(muta); }
/**
* @todo Type-comment
*/
@ -66,6 +110,23 @@ namespace control {
{
public:
template<typename SIG>
UndoMutation (function<SIG> const& func)
{
UNIMPLEMENTED ("build a undo Mutation functor object");
}
Mutation&
captureState ()
{
UNIMPLEMENTED ("invoke the state capturing Functor");
}
CmdClosure&
getMemento()
{
UNIMPLEMENTED ("return the closure serving as memento");
}
};
////////////////TODO currently just fleshing out the API....

View file

@ -7,4 +7,5 @@ PLANNED "CommandBasic_test" CommandBasic_test <<END
END
#
PLANNED "CommandMutation_test" CommandMutation_test <<END
END

View file

@ -48,6 +48,7 @@ test_components_SOURCES = \
$(testcomponents_srcdir)/proc/asset/orderingofassetstest.cpp \
$(testcomponents_srcdir)/proc/asset/testasset.cpp \
$(testcomponents_srcdir)/proc/control/command-basic-test.cpp \
$(testcomponents_srcdir)/proc/control/command-mutation-test.cpp \
$(testcomponents_srcdir)/proc/engine/bufftabletest.cpp \
$(testcomponents_srcdir)/proc/engine/sourcenodetest.cpp \
$(testcomponents_srcdir)/proc/mobject/builder/buildertooltest.cpp \

View file

@ -80,6 +80,10 @@ namespace test {
using lumiera::typelist::BuildTupleAccessor;
////////////////////////////////////////////TODO braindump
/**
* Type analysis helper template.
* Used for dissecting a given type signature to derive
@ -313,17 +317,8 @@ namespace test {
//////////////////////////// start of the actual Test....
/*
bind: opFunc(a,b,c) -> op(void)
curry(opFunc) (a) (b) (c)
pAppl(func, x) -> func2 (b, c)
return bind( recursion(), param)
*/
namespace command1 {
void
operate (P<Time> dummyObj, int randVal)
@ -345,7 +340,6 @@ namespace test {
}
////////////////////////////////////////////TODO braindump
/***************************************************************************
@ -366,29 +360,28 @@ namespace test {
virtual void
run (Arg)
{
/////////////////////////////////TODO
defineCommands();
checkExecution();
}
void
defineCommands ()
{
P<Time> obj (new Time(5));
int randVal ((rand() % 10) - 5);
CommDef ("test.command1")
CommandDef ("test.command1")
.operation (command1::operate)
.captureUndo (command1::capture)
.undoOperation (command1::undoIt)
.bind (obj, randVal)
;
}
void
checkExecution ()
{
Command ourCmd = Command::get("test.command1");
// invoke the command
ASSERT (obj == Time(5));
ourCmd();
ASSERT (obj == Time(5) + Time(randVal));
// undo the effect of the command
ourCmd.undo();
ASSERT (obj == Time(5));
}
};

View file

@ -0,0 +1,212 @@
/*
CommandMutation(Test) - checking the functor and undo-functor used within Proc-commands
Copyright (C) Lumiera.org
2009, 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/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/mutation.hpp"
#include "lib/meta/tuple.hpp"
//#include "lib/lumitime.hpp"
//#include "lib/util.hpp"
//#include <tr1/functional>
//#include <boost/format.hpp>
#include <iostream>
#include <string>
//using std::tr1::bind;
//using std::tr1::placeholders::_1;
//using std::tr1::placeholders::_2;
//using std::tr1::function;
//using boost::format;
//using lumiera::Time;
//using util::contains;
using std::string;
using std::cout;
using std::endl;
namespace control {
namespace test {
using lib::test::showSizeof;
// using session::test::TestClip;
// using lumiera::P;
using lumiera::typelist::Tuple;
using control::CommandClosure;
namespace {
void
operate (P<Time> dummyObj, int randVal)
{
*dummyObj += Time(randVal);
}
Time
capture (P<Time> dummyObj, int)
{
return *dummyObj;
}
void
undoIt (P<Time> dummyObj, int, Time oldVal)
{
*dummyObj = oldVal;
}
}
/***************************************************************************
* Verify the behaviour of the type erased closure, which is used
* by Proc-Layer commands to implement the capturing and later
* re-invocation of a function.
*
* @see control::Command
* @see control::CommandDef
* @see control::Mutation
* @see control::UndoMutation
* @see command-basic-test.hpp
*/
class CommandMutation_test : public Test
{
virtual void
run (Arg)
{
checkMutation();
checkUndoMutation();
}
/** @test check the Mutation functor which is bound to our \c testFunc(int) .
* Then close this Mutation by providing a parameter tuple.
* Verify finally that by invoking the Mutation functor
* actually \c testFunc(param) is executed.
*/
void
checkMutation ()
{
function<void(int)> funky (bind (&testFunc));
Mutation functor (funky);
ASSERT (!functor);
VERIFY_ERROR (UNBOUND_ARGUMENTS, functor() );
Tuple<int> param = tuple::make(23);
Closure close_over (param);
CmdClosure& clo (close_over);
functor.close(clo);
ASSERT (functor);
testVal = 0;
functor();
ASSERT (testVal == 23);
functor();
ASSERT (testVal == 2*23);
}
/** @test check the special Mutation which is used to \em undo a command.
* This time, we use our \c testFunc(int) as implementation of the
* "undo" function; thus its parameter has now the meaning of an
* captured state value. Consequently this time the \em operation
* which is to be undone would have the signature \c void(void) .
* To carry out the test, we first have to trigger the state
* capturing mechanism; after that, invoking the UndoMutation
* will call the testFunc with the previously captured state.
* @note Mutation and UndoMutation are value objects.
*/
void
checkUndoMutation ()
{
function<void(int)> undo_func (bind (&testFunc));
function<int(void)> cap_func (bind (&capture));
UndoMutation undoFunctor (undo_func,cap_func);
ASSERT (!undoFunctor);
VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor() );
Tuple<> param;
Closure clo (param);
undoFunctor.close(clo);
ASSERT (!undoFunctor);
VERIFY_ERROR (MISSING_MEMENTO, undoFunctor() );
VERIFY_ERROR (MISSING_MEMENTO, undoFunctor.getMemento() );
testVal = 11;
undoFunctor.captureState();
ASSERT (undoFunctor);
ASSERT (testVal == 11);
CmdClosure& mem = undoFunctor.getMemento();
cout << showSizeof(mem) << endl;
cout << "saved state: " << mem << endl;
undoFunctor();
ASSERT (testVal == 11 + 11);
undoFunctor();
ASSERT (testVal == 11 + 11 + 11);
undoFunctor.captureState();
undoFunctor();
ASSERT (testVal == 33 + 33);
testVal = 9;
undoFunctor();
ASSERT (testVal == 42);
UndoMutation clonedFunc (undoFunctor);
ASSERT (&undoFunctor.getMemento() != &clonedFunc.getMemento());
clonedFunc.captureState();
testVal = 0;
undoFunctor();
ASSERT (testVal == 33);
testVal = 0;
clonedFunc();
ASSERT (testVal == 42);
}
};
/** Register this test class... */
LAUNCHER (CommandMutation_test, "unit controller");
}} // namespace control::test