WIP more stubbing...
This commit is contained in:
parent
299c316ad4
commit
1db718c2b3
10 changed files with 280 additions and 27 deletions
|
|
@ -390,7 +390,7 @@ namespace typelist{
|
|||
, T6 a6 =T6()
|
||||
)
|
||||
{
|
||||
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> > (a1,a2,a3,a4,a5,a6);
|
||||
return Tuple<Types<T1,T2,T3,T4,T5,T6> > (a1,a2,a3,a4,a5,a6);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -413,7 +413,7 @@ namespace typelist{
|
|||
, T7 a7 =T7()
|
||||
)
|
||||
{
|
||||
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> > (a1,a2,a3,a4,a5,a6,a7);
|
||||
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7> > (a1,a2,a3,a4,a5,a6,a7);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -438,7 +438,7 @@ namespace typelist{
|
|||
, T8 a8 =T8()
|
||||
)
|
||||
{
|
||||
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7,T8,T9> > (a1,a2,a3,a4,a5,a6,a7,a8);
|
||||
return Tuple<Types<T1,T2,T3,T4,T5,T6,T7,T8> > (a1,a2,a3,a4,a5,a6,a7,a8);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
|
||||
/** @file argument-tuple-accept.hpp
|
||||
** The ArgumentTupleAccept template allows to mix in a \c bind(...) function.
|
||||
** The AcceptArgumentTuple template allows to mix in a \c bind(...) function.
|
||||
** Thereby, the correct number and types of arguments is derived according to
|
||||
** the function signature given as template parameter. This helper template is
|
||||
** used for the ArgumentHolder and generally for binding the arguments when
|
||||
|
|
@ -257,7 +257,7 @@ namespace control {
|
|||
* @param BASE the base class for inheritance chaining
|
||||
*/
|
||||
template<typename SIG, class TAR, class BASE>
|
||||
class ArgumentTupleAccept
|
||||
class AcceptArgumentTuple
|
||||
: public bind_arg::AcceptArgs<TAR,BASE, typename bind_arg::_Type<SIG>::Args>
|
||||
{
|
||||
};
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ namespace control {
|
|||
*/
|
||||
template<typename SIG, typename MEM>
|
||||
class ArgumentHolder
|
||||
: public ArgumentTupleAccept< SIG // to derive the desired bind(..) signature
|
||||
: public AcceptArgumentTuple< SIG // to derive the desired bind(..) signature
|
||||
, ArgumentHolder<SIG,MEM> // target class providing the implementation
|
||||
, CmdClosure // base class to inherit from
|
||||
>
|
||||
|
|
|
|||
213
src/proc/control/command-binding.hpp
Normal file
213
src/proc/control/command-binding.hpp
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
COMMAND-BINDING.hpp - interface for various ways of binding command arguments
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file command-binding.hpp
|
||||
** Sub-include of command.hpp, providing an interface to various ways
|
||||
** of binding command arguments. While in some cases, a command will be
|
||||
** set up completely finished and closed over all it's arguments, usually
|
||||
** the CommandDef will just specify the command operation and undo function,
|
||||
** thus leaving the task of binding concrete arguments to the client code.
|
||||
** Thus, depending on the circumstances, there might be usage situations
|
||||
** where the exact number and type of arguments can be detected and checked
|
||||
** at compile time, while otherwise this check needs to be deferred to happen
|
||||
** at runtime, when the binding is actually invoked.
|
||||
**
|
||||
** @see Command
|
||||
** @see CommandDef
|
||||
** @see command-use1-test.cpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef CONTROL_COMMAND_BINDING_H
|
||||
#define CONTROL_COMMAND_BINDING_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
//#include "include/symbol.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace control {
|
||||
namespace com { ///< Proc-Layer command implementation details
|
||||
|
||||
// using lumiera::Symbol;
|
||||
// using std::tr1::shared_ptr;
|
||||
using namespace lumiera::typelist;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
*/
|
||||
template<class TAR, class BA>
|
||||
class ArgumentBinder
|
||||
: public BA
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/** Arm up a command by binding it with concrete arguments.
|
||||
* At this point, a run time type check is performed, to find out
|
||||
* if the number and type of arguments of the stored operation function
|
||||
* within the command matches the given argument pattern
|
||||
*/
|
||||
void
|
||||
bind ()
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::makeNullTuple());
|
||||
}
|
||||
|
||||
|
||||
template<typename T1>
|
||||
void //________________________________
|
||||
bind (T1 a1) ///< Accept binding with 1 Argument
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1));
|
||||
}
|
||||
|
||||
|
||||
template< typename T1
|
||||
, typename T2
|
||||
>
|
||||
void //________________________________
|
||||
bind (T1 a1, T2 a2) ///< Accept binding for 2 Arguments
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2));
|
||||
}
|
||||
|
||||
|
||||
template< typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
>
|
||||
void //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3) ///< Accept binding for 3 Arguments
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3));
|
||||
}
|
||||
|
||||
|
||||
template< typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
, typename T4
|
||||
>
|
||||
void //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4) ///< Accept binding for 4 Arguments
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4));
|
||||
}
|
||||
|
||||
|
||||
template< typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
, typename T4
|
||||
, typename T5
|
||||
>
|
||||
void //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) ///< Accept binding for 5 Arguments
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5));
|
||||
}
|
||||
|
||||
|
||||
template< typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
, typename T4
|
||||
, typename T5
|
||||
, typename T6
|
||||
>
|
||||
void //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) ///< Accept binding for 6 Arguments
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6));
|
||||
}
|
||||
|
||||
|
||||
template< typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
, typename T4
|
||||
, typename T5
|
||||
, typename T6
|
||||
, typename T7
|
||||
>
|
||||
void //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) ///< Accept binding for 7 Arguments
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7));
|
||||
}
|
||||
|
||||
|
||||
template< typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
, typename T4
|
||||
, typename T5
|
||||
, typename T6
|
||||
, typename T7
|
||||
, typename T8
|
||||
>
|
||||
void //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8) ///< Accept binding for 8 Arguments
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8));
|
||||
}
|
||||
|
||||
|
||||
template< typename T1
|
||||
, typename T2
|
||||
, typename T3
|
||||
, typename T4
|
||||
, typename T5
|
||||
, typename T6
|
||||
, typename T7
|
||||
, typename T8
|
||||
, typename T9
|
||||
>
|
||||
void //________________________________
|
||||
bind (T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9) ///< Accept binding for 9 Arguments
|
||||
{
|
||||
static_cast<TAR*> (this) -> bindArg (tuple::make (a1,a2,a3,a4,a5,a6,a7,a8,a9));
|
||||
}
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace control
|
||||
#endif
|
||||
|
|
@ -43,8 +43,10 @@
|
|||
|
||||
namespace control {
|
||||
|
||||
LUMIERA_ERROR_DEFINE (INVALID_COMMAND, "Unknown or insufficiently defined command");
|
||||
LUMIERA_ERROR_DEFINE (INVALID_ARGUMENTS, "Arguments provided for binding doesn't match stored command function parameters");
|
||||
LUMIERA_ERROR_DEFINE (UNBOUND_ARGUMENTS, "Command mutation functor not yet usable, because arguments aren't bound");
|
||||
LUMIERA_ERROR_DEFINE (MISSING_MEMENTO, "Undo functor not yet usable, because no undo state has been captured");
|
||||
LUMIERA_ERROR_DEFINE (MISSING_MEMENTO, "Undo functor not yet usable, because no undo state has been captured");
|
||||
|
||||
|
||||
|
||||
|
|
@ -142,6 +144,15 @@ namespace control {
|
|||
{
|
||||
UNIMPLEMENTED ("manage the default command handling pattern");
|
||||
}
|
||||
|
||||
|
||||
template<typename TYPES>
|
||||
void
|
||||
Command::bindArg (Tuple<TYPES> const& args)
|
||||
{
|
||||
UNIMPLEMENTED ("create an argument-binding, with runtime type check");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,8 +34,9 @@
|
|||
#ifndef CONTROL_COMMAND_H
|
||||
#define CONTROL_COMMAND_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
#include "pre.hpp"
|
||||
#include "include/symbol.hpp"
|
||||
#include "proc/control/command-binding.hpp"
|
||||
#include "proc/control/command-mutation.hpp"
|
||||
#include "proc/control/command-closure.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
|
@ -51,6 +52,11 @@ namespace control {
|
|||
using lumiera::Symbol;
|
||||
// using std::tr1::shared_ptr;
|
||||
|
||||
LUMIERA_ERROR_DECLARE (UNBOUND_ARGUMENTS); ///< Command functor not yet usable, because arguments aren't bound
|
||||
LUMIERA_ERROR_DECLARE (INVALID_COMMAND); ///< Unknown or insufficiently defined command
|
||||
LUMIERA_ERROR_DECLARE (INVALID_ARGUMENTS); ///< Arguments provided for binding doesn't match stored command function parameters
|
||||
|
||||
|
||||
|
||||
class HandlingPattern;
|
||||
|
||||
|
|
@ -59,7 +65,8 @@ namespace control {
|
|||
* @todo Type-comment
|
||||
*/
|
||||
class Command
|
||||
: public lib::BoolCheckable<Command>
|
||||
: public com::ArgumentBinder<Command
|
||||
, lib::BoolCheckable<Command> >
|
||||
{
|
||||
|
||||
public:
|
||||
|
|
@ -85,6 +92,10 @@ namespace control {
|
|||
HandlingPattern const& getDefaultHandlingPattern() const;
|
||||
|
||||
|
||||
template<typename TYPES>
|
||||
void bindArg (Tuple<TYPES> const&);
|
||||
|
||||
|
||||
/* === diagnostics === */
|
||||
|
||||
static size_t definition_count();
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ out: saved state: 11
|
|||
END
|
||||
|
||||
|
||||
TEST "build argument accepting function" ArgumentTupleAccept_test <<END
|
||||
TEST "build argument accepting function" AcceptArgumentTuple_test <<END
|
||||
out: sizeof\( .+control.+TestClass.+ \) = 1
|
||||
out: sizeof\( .+control.+TestClass.+lumiera.Time.+ \) = ( 8)|(16)
|
||||
out: 00:..:..\.000
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
ArgumentTupleAccept(Test) - verify synthesising a bind(...) function
|
||||
AcceptArgumentTuple(Test) - verify synthesising a bind(...) function
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
|
@ -63,7 +63,7 @@ namespace test {
|
|||
|
||||
template<typename SIG>
|
||||
class TestClass
|
||||
: public ArgumentTupleAccept< SIG // to derive the desired signature
|
||||
: public AcceptArgumentTuple< SIG // to derive the desired signature
|
||||
, TestClass<SIG> // the target class providing the implementation
|
||||
, typename Tup<SIG>::Ty // base class to inherit from
|
||||
>
|
||||
|
|
@ -93,7 +93,7 @@ namespace test {
|
|||
*
|
||||
* @see control::CommandArgumentHolder
|
||||
*/
|
||||
class ArgumentTupleAccept_test : public Test
|
||||
class AcceptArgumentTuple_test : public Test
|
||||
{
|
||||
|
||||
virtual void
|
||||
|
|
@ -117,7 +117,7 @@ namespace test {
|
|||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (ArgumentTupleAccept_test, "unit controller");
|
||||
LAUNCHER (AcceptArgumentTuple_test, "unit controller");
|
||||
|
||||
|
||||
}} // namespace control::test
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
//#include "proc/mobject/placement.hpp"
|
||||
//#include "proc/mobject/placement-index.hpp"
|
||||
//#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/control/command.hpp"
|
||||
#include "proc/control/command-def.hpp"
|
||||
//#include "lib/lumitime.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
|
@ -224,7 +225,7 @@ namespace test {
|
|||
// note we've overwritten the previous undo state
|
||||
// and get the sate captured on the second invocation
|
||||
|
||||
c2.undo()
|
||||
c2.undo();
|
||||
ASSERT (randVal == command1::check_);
|
||||
c1.undo();
|
||||
ASSERT (randVal + 23 == command1::check_);
|
||||
|
|
@ -267,7 +268,6 @@ namespace test {
|
|||
|
||||
// but because the miracle isn't yet defined, any use throws
|
||||
VERIFY_ERROR (INVALID_COMMAND, Command::get("miracle"));
|
||||
VERIFY_ERROR (UNBOUND_ARGUMENTS, unbelievable.execSync() );
|
||||
VERIFY_ERROR (INVALID_COMMAND, unbelievable.bind("abracadabra"));
|
||||
|
||||
ASSERT (Command::remove("test.command1.1"));
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@
|
|||
//#include "proc/mobject/placement.hpp"
|
||||
//#include "proc/mobject/placement-index.hpp"
|
||||
//#include "proc/mobject/explicitplacement.hpp"
|
||||
#include "proc/control/command.hpp"
|
||||
#include "proc/control/command-def.hpp"
|
||||
#include "proc/control/handling-pattern.hpp"
|
||||
//#include "lib/lumitime.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -41,6 +43,7 @@
|
|||
#include <tr1/functional>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
//#include <iostream>
|
||||
//#include <cstdlib>
|
||||
#include <string>
|
||||
|
|
@ -62,6 +65,7 @@ namespace test {
|
|||
//using std::endl;
|
||||
// using lib::test::showSizeof;
|
||||
// using util::isSameObject;
|
||||
using boost::lexical_cast;
|
||||
using util::contains;
|
||||
using boost::ref;
|
||||
|
||||
|
|
@ -73,6 +77,20 @@ namespace test {
|
|||
using lumiera::error::LUMIERA_ERROR_EXTERNAL;
|
||||
|
||||
|
||||
/** diagnostics: checks if the given value has been written
|
||||
* to the test protocol (string stream) of command2
|
||||
* Explanation: command2 accepts a function, invokes
|
||||
* it and writes the result to the protocol stream.
|
||||
*/
|
||||
template<typename TY>
|
||||
inline bool
|
||||
protocolled (TY val2check)
|
||||
{
|
||||
return contains ( command2::check_.str()
|
||||
, lexical_cast<string> (val2check)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -95,7 +113,7 @@ namespace test {
|
|||
return str (fmt % randVal_);
|
||||
}
|
||||
|
||||
bool blowUp_ = false;
|
||||
bool blowUp_;
|
||||
|
||||
|
||||
virtual void
|
||||
|
|
@ -114,8 +132,8 @@ namespace test {
|
|||
.undoOperation (command2::undoIt)
|
||||
.bind (randFun, ref(blowUp_));
|
||||
|
||||
// note: blowUp_ is bound via reference_wrapper,
|
||||
// so we can pull the trigger to provoke an exception
|
||||
//note : blowUp_ is bound via reference_wrapper,
|
||||
// thus we can provoke an exception at will.
|
||||
blowUp_ = false;
|
||||
|
||||
|
||||
|
|
@ -136,18 +154,18 @@ namespace test {
|
|||
{
|
||||
Command com = Command::get("test.command2");
|
||||
|
||||
ASSERT (!contains (command2::check_, "invoked"));
|
||||
ASSERT (!protocolled("invoked"));
|
||||
|
||||
bool res = com();
|
||||
|
||||
ASSERT (res);
|
||||
ASSERT (contains (command2::check_, "invoked"));
|
||||
ASSERT (contains (command2::check_, randVal_));
|
||||
ASSERT (protocolled("invoked"));
|
||||
ASSERT (protocolled(randVal_));
|
||||
|
||||
res = com.undo();
|
||||
ASSERT (res); // UNDO invoked successfully
|
||||
ASSERT (!contains (command2::check_, randVal_));
|
||||
ASSERT (contains (command2::check_, "UNDO"));
|
||||
ASSERT (!protocolled(randVal_));
|
||||
ASSERT (protocolled("UNDO"));
|
||||
|
||||
blowUp_ = true;
|
||||
string current = command2::check_.str();
|
||||
|
|
@ -174,7 +192,7 @@ namespace test {
|
|||
|
||||
blowUp_ = false;
|
||||
com.exec(HandlingPattern::THROW_SYNC);
|
||||
ASSERT (contains (command2::check_, randVal_));
|
||||
ASSERT (protocolled(randVal_));
|
||||
|
||||
blowUp_ = true;
|
||||
string current = command2::check_.str();
|
||||
|
|
@ -193,10 +211,10 @@ namespace test {
|
|||
blowUp_ = false;
|
||||
com2();
|
||||
ASSERT (command2::check_.str() > current);
|
||||
ASSERT (contains (command2::check_, randVal_));
|
||||
ASSERT (protocolled(randVal_));
|
||||
|
||||
com2.undo();
|
||||
ASSERT (!contains (command2::check_, randVal_));
|
||||
ASSERT (!protocolled(randVal_));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue