finish and tidy up control::Mutation, unit test pass
This commit is contained in:
parent
e892a0087a
commit
9aa5ba560c
9 changed files with 119 additions and 88 deletions
|
|
@ -88,8 +88,8 @@ namespace lib {
|
|||
* \c isValid() function, the conversion operator returns either a
|
||||
* bound or unbound member pointer.
|
||||
*
|
||||
* @todo list some usage examples here
|
||||
* @see bool-checkable-test.cpp
|
||||
* @see bool-checkable-test.cpp
|
||||
* @see control::Mutation usage example
|
||||
*/
|
||||
template< class T ///< the target type implementing \c isValid()
|
||||
, class PAR = imp::Dummy ///< optional parent for inheritance chain
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ namespace lib {
|
|||
|
||||
template<class SUB>
|
||||
InPlaceAnyHolder(SUB const& obj)
|
||||
{
|
||||
{
|
||||
place_inBuff (obj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@
|
|||
|
||||
#include <tr1/memory>
|
||||
#include <tr1/functional>
|
||||
#include <iostream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
|
@ -119,14 +120,12 @@ namespace control {
|
|||
|
||||
ParamAccessor(TUP const& tuple)
|
||||
: BASE(tuple)
|
||||
{
|
||||
cout << showSizeof(element()) << endl; //////////TODO remove this test code
|
||||
}
|
||||
{ }
|
||||
|
||||
string
|
||||
dump (string const& prefix = "(") const
|
||||
ostream&
|
||||
dump (ostream& output) const
|
||||
{
|
||||
return BASE::dump (prefix+element()+",");
|
||||
return BASE::dump (output << element() << ',');
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -144,14 +143,10 @@ namespace control {
|
|||
|
||||
////////////////////TODO the recursion-end of the access operations goes here
|
||||
|
||||
string
|
||||
dump (string const& prefix ="(") const
|
||||
ostream&
|
||||
dump (ostream& output) const
|
||||
{
|
||||
if (1 < prefix.length())
|
||||
// remove trailing comma...
|
||||
return prefix.substr (0, prefix.length()-1) +")";
|
||||
else
|
||||
return prefix+")";
|
||||
return output;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -212,7 +207,15 @@ namespace control {
|
|||
|
||||
operator string() const
|
||||
{
|
||||
UNIMPLEMENTED ("how to do a string conversion on the variable argument tuple??");
|
||||
std::ostringstream buff;
|
||||
params_.dump (buff << "Closure(" );
|
||||
|
||||
string dumped (buff.str());
|
||||
if (1 < dumped.length())
|
||||
// remove trailing comma...
|
||||
return dumped.substr (0, dumped.length()-1) +")";
|
||||
else
|
||||
return dumped+")";
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,11 +22,32 @@
|
|||
|
||||
|
||||
/** @file command-mutation.hpp
|
||||
** The core of a Proc-Layer command: functor containing the actual operation to be executed.
|
||||
** //TODO
|
||||
**
|
||||
** Core of a Proc-Layer command: functor containing the actual operation to be executed.
|
||||
** Each command holds two of these functors: one representing the actual operation
|
||||
** and one to undo the effect of this operation. The latter involves the capturing
|
||||
** and storing of a "memento" value behind the scenes. But towards Command, the
|
||||
** Mutation acts as interface to conceal these details, as well as the actual
|
||||
** type and parameters of the functions to be invoked. Thus, Mutation's
|
||||
** public interface just consists of a function call operator \c void() .
|
||||
**
|
||||
** \par Lifecycle
|
||||
** Mutation objects are to be created based on a concrete function object, which then
|
||||
** gets embedded into a type erasure container, thus disposing the specific type information.
|
||||
** Moreover, building on this lib::OpaqueHolder yields a fixed size storage for Mutation objects,
|
||||
** allowing them to be embedded immediately within the Command instance.
|
||||
**
|
||||
** Later on, any command needs to be made ready for execution by binding it to a specific
|
||||
** execution environment, which especially includes the target objects to be mutated by the
|
||||
** command. This procedure includes "closing" the Mutation (and UNDO) functor(s) with the
|
||||
** actual function arguments. These arguments are stored embedded within an ArgumentHolder,
|
||||
** which thereby acts as closure. Besides, the ArgumentHolder also has to accommodate for
|
||||
** storage holding the captured UNDO state (memento). Thus, internally the ArgumentHolder
|
||||
** has to keep track of the actual types, thus allowing to re-construct the concrete
|
||||
** function signature when closing the Mutation.
|
||||
**
|
||||
** @see Command
|
||||
** @see ProcDispatcher
|
||||
** @see MementoTie binding memento state
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
@ -41,9 +62,6 @@
|
|||
#include "proc/control/command-closure.hpp"
|
||||
#include "proc/control/memento-tie.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <tr1/functional>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
|
|
@ -51,10 +69,6 @@
|
|||
|
||||
namespace control {
|
||||
|
||||
// using lumiera::Symbol;
|
||||
// using std::tr1::shared_ptr;
|
||||
using boost::scoped_ptr;
|
||||
using std::tr1::function;
|
||||
using std::ostream;
|
||||
using std::string;
|
||||
|
||||
|
|
@ -63,7 +77,13 @@ namespace control {
|
|||
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
* Unspecific command functor for implementing Proc-Layer Command.
|
||||
* To be created from an tr1::function object, which later on
|
||||
* can be \link #close closed \endlink with a set of actual
|
||||
* function arguments. The concrete type of the function
|
||||
* and the arguments is concealed (erased) on the interface,
|
||||
* while the unclosed/closed - state of the functor can be
|
||||
* checked by bool() conversion.
|
||||
*/
|
||||
class Mutation
|
||||
: public lib::BoolCheckable<Mutation>
|
||||
|
|
@ -105,7 +125,8 @@ namespace control {
|
|||
/** diagnostics */
|
||||
operator string() const
|
||||
{
|
||||
return isValid()? string (*clo_) : "Mutation(state missing)";
|
||||
return isValid()? "Mutation("+string (*clo_)+")"
|
||||
: "Mutation(untied)";
|
||||
}
|
||||
|
||||
virtual bool
|
||||
|
|
@ -114,7 +135,8 @@ namespace control {
|
|||
return func_ && clo_;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
void
|
||||
invoke (CmdFunctor & closedFunction)
|
||||
{
|
||||
|
|
@ -128,8 +150,21 @@ namespace control {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
* Specialised version of the command Mutation functor,
|
||||
* used to implement the UNDO functionality. The operation
|
||||
* executed when invoking this functor is the UNDO operation
|
||||
* of the respective command; additionally we need another
|
||||
* functor to capture the state to be restored on UNDO.
|
||||
* Both functors are wired up internally to cooperate
|
||||
* and store the state (memento), which is implemented
|
||||
* by the specifically typed MementoTie object passed
|
||||
* in on construction. All these specific details
|
||||
* are concealed on the interface
|
||||
*/
|
||||
class UndoMutation
|
||||
: public Mutation
|
||||
|
|
@ -143,11 +178,6 @@ namespace control {
|
|||
, captureMemento_(mementoHolder.tieCaptureFunc())
|
||||
{ }
|
||||
|
||||
// UndoMutation (UndoMutation const& o)
|
||||
// : Mutation(o)
|
||||
// , captureMemento_(o.captureMemento_)
|
||||
// { }
|
||||
|
||||
|
||||
virtual Mutation&
|
||||
close (CmdClosure& cmdClosure)
|
||||
|
|
@ -172,16 +202,13 @@ namespace control {
|
|||
|
||||
private:
|
||||
virtual bool
|
||||
isValid () const
|
||||
isValid () const
|
||||
{
|
||||
return Mutation::isValid() && captureMemento_;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace control
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@
|
|||
|
||||
namespace control {
|
||||
|
||||
using std::tr1::ref;
|
||||
using lumiera::typelist::func::bindLast;
|
||||
using lumiera::typelist::func::chained;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,14 @@ PLANNED "CommandArgument_test" CommandArgument_test <<END
|
|||
END
|
||||
|
||||
|
||||
PLANNED "CommandMutation_test" CommandMutation_test <<END
|
||||
TEST "Command functor" CommandMutation_test <<END
|
||||
out: Mutation\(untied\)
|
||||
out: param values: Closure\(23\)
|
||||
out: Mutation\(Closure\(23\)\)
|
||||
out: saved state: 11
|
||||
END
|
||||
|
||||
|
||||
Test "MementoTie_test" MementoTie_test <<END
|
||||
TEST "Memento binding" MementoTie_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ test_components_SOURCES = \
|
|||
$(testcomponents_srcdir)/proc/control/command-basic-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-argument-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/command-mutation-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/memento-tie-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/control/memento-tie-test.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/bufftabletest.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/sourcenodetest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/builder/buildertooltest.cpp \
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ namespace test {
|
|||
using lumiera::P;
|
||||
|
||||
|
||||
using lumiera::typelist::BuildTupleAccessor;
|
||||
//using lumiera::typelist::BuildTupleAccessor;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,36 +22,17 @@
|
|||
|
||||
|
||||
#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-mutation.hpp"
|
||||
#include "proc/control/memento-tie.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
//#include "lib/lumitime.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
#include <tr1/functional>
|
||||
//#include <boost/format.hpp>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#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::rand;
|
||||
using std::cout;
|
||||
|
|
@ -60,25 +41,15 @@ using std::endl;
|
|||
|
||||
namespace control {
|
||||
namespace test {
|
||||
|
||||
using lib::test::showSizeof;
|
||||
|
||||
// using session::test::TestClip;
|
||||
// using lumiera::P;
|
||||
using namespace lumiera::typelist;
|
||||
using lumiera::typelist::Tuple;
|
||||
|
||||
using namespace lumiera::typelist;
|
||||
using control::CmdClosure;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
namespace { /* ======= test functions to bind ========= */
|
||||
|
||||
int testVal=0; ///< used to verify the effect of testFunc
|
||||
|
||||
|
||||
void
|
||||
testFunc (int val)
|
||||
{
|
||||
|
|
@ -114,6 +85,7 @@ namespace test {
|
|||
{
|
||||
checkMutation();
|
||||
checkUndoMutation();
|
||||
checkStateCapturingMechanism();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -125,11 +97,12 @@ namespace test {
|
|||
void
|
||||
checkMutation ()
|
||||
{
|
||||
function<void(int)> funky = bind (testFunc, _1);
|
||||
function<void(int)> funky = testFunc;
|
||||
|
||||
Mutation functor (funky);
|
||||
ASSERT (!functor);
|
||||
VERIFY_ERROR (UNBOUND_ARGUMENTS, functor() );
|
||||
cout << functor << endl;
|
||||
|
||||
Tuple<Types<int> > param = tuple::make(23);
|
||||
Closure<void(int)> close_over (param);
|
||||
|
|
@ -139,6 +112,7 @@ namespace test {
|
|||
ASSERT (functor);
|
||||
|
||||
cout << "param values: " << clo << endl;
|
||||
cout << functor << endl;
|
||||
|
||||
testVal = 0;
|
||||
functor();
|
||||
|
|
@ -154,8 +128,8 @@ namespace test {
|
|||
* captured state value. Consequently this time the \em operation
|
||||
* which is to be undone would have the signature \c void(void) .
|
||||
* Obviously this is a rather silly "undo" function, but it is
|
||||
* easy to check in a unit test. To carry out this test, we first
|
||||
* have to trigger the state capturing mechanism; after that,
|
||||
* easy to check for unit testing. To carry out this 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, but they refer
|
||||
|
|
@ -166,27 +140,29 @@ namespace test {
|
|||
void
|
||||
checkUndoMutation ()
|
||||
{
|
||||
function<void(int)> undo_func = bind (&testFunc,_1);
|
||||
function<int(void)> cap_func = bind (&capture );
|
||||
function<void(int)> undo_func = testFunc;
|
||||
function<int(void)> cap_func = capture;
|
||||
|
||||
typedef MementoTie<void(),int> MemHolder;
|
||||
|
||||
MemHolder mementoHolder (undo_func,cap_func);
|
||||
UndoMutation undoFunctor (mementoHolder);
|
||||
ASSERT (!undoFunctor);
|
||||
ASSERT (!mementoHolder);
|
||||
VERIFY_ERROR (UNBOUND_ARGUMENTS, undoFunctor() );
|
||||
|
||||
Tuple<Types<> > param;
|
||||
Closure<void()> clo (param);
|
||||
|
||||
undoFunctor.close(clo);
|
||||
ASSERT (!undoFunctor);
|
||||
ASSERT ( undoFunctor);
|
||||
ASSERT (!mementoHolder);
|
||||
VERIFY_ERROR (MISSING_MEMENTO, undoFunctor() );
|
||||
VERIFY_ERROR (MISSING_MEMENTO, mementoHolder.getState() );
|
||||
|
||||
testVal = 11;
|
||||
undoFunctor.captureState();
|
||||
ASSERT (undoFunctor);
|
||||
ASSERT (mementoHolder);
|
||||
ASSERT (testVal == 11);
|
||||
|
||||
int mem = mementoHolder.getState();
|
||||
|
|
@ -217,11 +193,33 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
/** @test check the undo memento capturing mechanism in isolation
|
||||
* @see memento-tie-test.cpp more in-depth coverage */
|
||||
void
|
||||
checkStateCapturingMechanism ()
|
||||
{
|
||||
typedef MementoTie<void(),int> MemHolder;
|
||||
|
||||
MemHolder mementoHolder (testFunc, capture);
|
||||
|
||||
function<void()> bound_undo_func = mementoHolder.tieUndoFunc();
|
||||
function<void()> bound_cap_func = mementoHolder.tieCaptureFunc();
|
||||
|
||||
|
||||
int rr (rand() % 100);
|
||||
testVal = rr;
|
||||
bound_cap_func(); // invoke state capturing
|
||||
ASSERT (rr == mementoHolder.getState());
|
||||
|
||||
testVal = 10; // meanwhile "somehow" mutate the state
|
||||
bound_undo_func(); // invoking the undo() feeds back the memento
|
||||
ASSERT (testVal == 10+rr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (CommandMutation_test, "unit controller");
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace control::test
|
||||
|
|
|
|||
Loading…
Reference in a new issue