WIP more stubbing...

This commit is contained in:
Fischlurch 2009-07-25 19:21:50 +02:00
parent 299c316ad4
commit 1db718c2b3
10 changed files with 280 additions and 27 deletions

View file

@ -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);
}

View file

@ -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>
{
};

View file

@ -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
>

View 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

View file

@ -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");
}

View file

@ -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();

View file

@ -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

View file

@ -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

View file

@ -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"));

View file

@ -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_));
}
};