WIP more implementation...
This commit is contained in:
parent
c2d9a02303
commit
8971d667cf
7 changed files with 161 additions and 49 deletions
|
|
@ -120,8 +120,8 @@ NOBUG_CPP_DEFINE_FLAG_PARENT ( mmap, backend);
|
|||
NOBUG_CPP_DEFINE_FLAG_PARENT ( thread, backend); //starting/stopping threads
|
||||
/** progress log for the proc layer */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( proc, progress);
|
||||
/** progress log for the render subsystem of proc */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( render, proc); //ichthyo: did you want this as global channel or as progress child?
|
||||
/** progress log for proc-layer command dispatch */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( command, proc);
|
||||
/** progress log for the gui */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( gui, progress);
|
||||
/** progress log for the support lib */
|
||||
|
|
@ -130,7 +130,7 @@ NOBUG_CPP_DEFINE_FLAG_PARENT ( resourcecollector, library);
|
|||
/** progress log for the common lib */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( common, progress);
|
||||
/** progress log, config subsystem */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( config, common);
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( config, common); //TODO: here seems to be a name clash with the global "config" channel
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( configfiles, config); //reading, writing, lookup configfiles
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( configtyped, config); //values queried, errors
|
||||
/** progress log, interfaces */
|
||||
|
|
@ -142,6 +142,8 @@ NOBUG_CPP_DEFINE_FLAG_PARENT ( subsystem, common);
|
|||
NOBUG_CPP_DEFINE_FLAG_PARENT ( pluginloader, common); //plugins loaded/unloaded/errors
|
||||
/** progress log, external plugins*/
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( plugins, progress);
|
||||
/** base channel flag to track overall working of the render engine */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( render, logging);
|
||||
/** base flag for software testing */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( test, logging);
|
||||
/** base flag for syncronization logging */
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ namespace lib {
|
|||
/** Activation of the handle by the managing service.
|
||||
* @param impl the implementation object this handle is tied to
|
||||
* @param whenDead functor to be invoked when reaching end-of-life
|
||||
* @throw std::bad_alloc, in which case \c whenDead(impl) is invoked
|
||||
*/
|
||||
template<typename DEL>
|
||||
Handle&
|
||||
|
|
|
|||
|
|
@ -48,8 +48,10 @@
|
|||
#define CONTROL_COMMAND_DEF_H
|
||||
|
||||
//#include "pre.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "include/symbol.hpp"
|
||||
#include "proc/control/command.hpp"
|
||||
#include "proc/control/command-registry.hpp"
|
||||
#include "proc/control/command-signature.hpp"
|
||||
#include "proc/control/command-mutation.hpp"
|
||||
#include "proc/control/command-closure.hpp"
|
||||
|
|
@ -89,27 +91,47 @@ namespace control {
|
|||
, UndoDefinition<SIG,MEM> // target type (this class) providing the implementation \c bindArg(Tuple<..>)
|
||||
>
|
||||
{
|
||||
typedef typename FunctionSignature< function<SIG> >::Args BasicArgs;
|
||||
typedef typename FunctionTypedef<MEM,BasicArgs>::Sig UndoCaptureSig;
|
||||
typedef CommandSignature<SIG,MEM> CmdType;
|
||||
typedef typename CmdType::OperateSig CommandOperationSig;
|
||||
typedef typename CmdType::UndoOp_Sig UndoOperationSig;
|
||||
typedef typename CmdType::CaptureSig UndoCaptureSig;
|
||||
|
||||
typedef function<CommandOperationSig> OperFunc;
|
||||
typedef function<UndoOperationSig> UndoFunc;
|
||||
typedef function<UndoCaptureSig> CaptFunc;
|
||||
|
||||
Command& prototype_;
|
||||
OperFunc operFunctor_;
|
||||
UndoFunc undoFunctor_;
|
||||
CaptFunc captFunctor_;
|
||||
|
||||
UndoDefinition (Command& underConstruction, function<UndoCaptureSig>& undoCapOperation)
|
||||
|
||||
UndoDefinition (Command& underConstruction,
|
||||
OperFunc& commandOperation,
|
||||
CaptFunc& undoCapOperation)
|
||||
: prototype_(underConstruction)
|
||||
, operFunctor_(commandOperation)
|
||||
, captFunctor_(undoCapOperation)
|
||||
, undoFunctor_()
|
||||
{
|
||||
cout << showSizeof(undoCapOperation) << endl;
|
||||
UNIMPLEMENTED ("re-fetch command definition and augment it with Functor for capturing Undo information");
|
||||
}
|
||||
|
||||
template<typename SIG2>
|
||||
|
||||
UndoDefinition&
|
||||
undoOperation (SIG2& how_to_Undo)
|
||||
undoOperation (UndoOperationSig& how_to_Undo)
|
||||
{
|
||||
typedef typename UndoSignature<SIG2>::UndoOp_Sig UndoSig;
|
||||
undoFunctor_ = UndoFunc (how_to_Undo);
|
||||
REQUIRE (operFunctor_);
|
||||
REQUIRE (undoFunctor_);
|
||||
REQUIRE (captFunctor_);
|
||||
|
||||
function<UndoSig> opera3 (how_to_Undo);
|
||||
|
||||
UNIMPLEMENTED ("store actual Undo-Functor into the command definition held by the enclosing UndoDefinition instance");
|
||||
CommandRegistry& registry = CommandRegistry::instance();
|
||||
CommandImpl& completedDef = registry.newCommandImpl(operFunctor_
|
||||
,undoFunctor_
|
||||
,captFunctor_);
|
||||
prototype_.activate(completedDef);
|
||||
ENSURE (prototype_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -146,13 +168,12 @@ namespace control {
|
|||
struct BasicDefinition
|
||||
{
|
||||
Command& prototype_;
|
||||
function<SIG>& operation_;
|
||||
|
||||
BasicDefinition(Command& underConstruction, function<SIG>& operation)
|
||||
: prototype_(underConstruction)
|
||||
{
|
||||
cout << showSizeof(operation) << endl;
|
||||
UNIMPLEMENTED ("create new command object and store the operation functor");
|
||||
}
|
||||
, operation_(operation)
|
||||
{ }
|
||||
|
||||
|
||||
template<typename SIG2>
|
||||
|
|
@ -162,8 +183,8 @@ namespace control {
|
|||
typedef typename UndoSignature<SIG2>::CaptureSig UndoCapSig;
|
||||
typedef typename BuildUndoDefType<UndoSignature<SIG2> >::Type SpecificUndoDefinition;
|
||||
|
||||
function<UndoCapSig> opera2 (how_to_capture_UndoState);
|
||||
return SpecificUndoDefinition (prototype_, opera2);
|
||||
function<UndoCapSig> captureOperation (how_to_capture_UndoState);
|
||||
return SpecificUndoDefinition (prototype_, operation_, captureOperation);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -96,18 +96,29 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
/** search the command index for a definition
|
||||
* @param cmdInstance using the definition to look up
|
||||
* @return the ID used to register this definition
|
||||
* or \c NULL in case of an "anonymous" command */
|
||||
Symbol
|
||||
findDefinition (Command const& cmdInstance)
|
||||
{
|
||||
UNIMPLEMENTED ("try to find a registration in the index for a given command instance");
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
index_size()
|
||||
{
|
||||
UNIMPLEMENTED ("number of defs in the index");
|
||||
}
|
||||
{
|
||||
UNIMPLEMENTED ("number of defs in the index");
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
instance_count()
|
||||
{
|
||||
UNIMPLEMENTED ("number of active command impl instances");
|
||||
}
|
||||
{
|
||||
UNIMPLEMENTED ("number of active command impl instances");
|
||||
}
|
||||
|
||||
|
||||
/** set up a new command implementation frame */
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "include/logging.h"
|
||||
#include "proc/control/command.hpp"
|
||||
#include "proc/control/command-def.hpp"
|
||||
#include "proc/control/command-registry.hpp"
|
||||
|
|
@ -39,16 +41,22 @@
|
|||
//#include "proc/mobject/mobject.hpp"
|
||||
//#include "proc/mobject/placement.hpp"
|
||||
|
||||
//#include <boost/format.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
using namespace lumiera;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
//using boost::str;
|
||||
using boost::format;
|
||||
using boost::str;
|
||||
using util::cStr;
|
||||
|
||||
|
||||
namespace control {
|
||||
|
||||
LUMIERA_ERROR_DEFINE (INVALID_COMMAND, "Unknown or insufficiently defined command");
|
||||
LUMIERA_ERROR_DEFINE (DUPLICATE_COMMAND, "Attempt to redefine an already existing command definition");
|
||||
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");
|
||||
|
|
@ -58,20 +66,15 @@ namespace control {
|
|||
Command::~Command() { }
|
||||
|
||||
|
||||
/** @internal to be invoked by #fetchDef */
|
||||
Command::Command (CommandImpl* pImpl)
|
||||
{
|
||||
Handle::activate (pImpl, CommandRegistry::killCommandImpl);
|
||||
}
|
||||
|
||||
|
||||
/** */
|
||||
Command
|
||||
Command::get (Symbol cmdID)
|
||||
{
|
||||
Command cmd = CommandRegistry::instance().queryIndex (cmdID);
|
||||
static format fmt("Command definition \"%s\" not found");
|
||||
if (!cmd)
|
||||
throw lumiera::error::Invalid("Command definition not found", LUMIERA_ERROR_INVALID_COMMAND);
|
||||
throw error::Invalid(str(fmt % cmdID), LUMIERA_ERROR_INVALID_COMMAND);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
|
@ -85,12 +88,32 @@ namespace control {
|
|||
if (cmd)
|
||||
return cmd;
|
||||
|
||||
Command newDefinition (registry.newCommandImpl());
|
||||
// create an empty definition, later to be activated
|
||||
Command newDefinition;
|
||||
|
||||
return registry.track (cmdID, newDefinition);
|
||||
} // return new or currently registered cmd...
|
||||
|
||||
|
||||
/** @internal to be invoked by CommandDef
|
||||
* @throw std::bad_alloc, in which case
|
||||
* CommandRegistry::killCommandImpl is invoked */
|
||||
Command&
|
||||
Command::activate (CommandImpl& implFrame)
|
||||
{
|
||||
static format fmt_err("Command \"%s\" already defined");
|
||||
static format fmt_ok("Command \"%s\" defined OK");
|
||||
|
||||
if (this->isValid())
|
||||
throw error::Logic (str(fmt_err % *this), LUMIERA_ERROR_DUPLICATE_COMMAND);
|
||||
|
||||
_Handle::activate (&implFrame, CommandRegistry::killCommandImpl);
|
||||
|
||||
INFO (command, cStr(fmt_ok % *this));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
CommandDef
|
||||
Command::storeDef (Symbol newCmdID)
|
||||
{
|
||||
|
|
@ -175,6 +198,34 @@ namespace control {
|
|||
return isValid()
|
||||
&& impl().canUndo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** diagnostics: shows the commandID, if any,
|
||||
* and the degree of definition of this command */
|
||||
Command::operator string() const
|
||||
{
|
||||
ostringstream repr;
|
||||
repr << "Command";
|
||||
////////////////////////////////////////////////////////////////////TODO do we need no-throw guarantee here?
|
||||
Symbol id = CommandRegistry::instance().findCommand (*this);
|
||||
if (id)
|
||||
repr << "(\""<<id<<"\") ";
|
||||
else
|
||||
repr << "(_xxx_) ";
|
||||
if (!isValid())
|
||||
repr << "NIL";
|
||||
else
|
||||
if (canUndo())
|
||||
repr << "{undo}";
|
||||
else
|
||||
if (canExec())
|
||||
repr << "{exec}";
|
||||
else
|
||||
repr << "{def}";
|
||||
|
||||
return repr.str();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "lib/handle.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
#include <string>
|
||||
|
||||
///////////////////////////////////////////TODO: define an C-API representation here, make the header multilingual!
|
||||
|
||||
|
|
@ -50,11 +51,13 @@
|
|||
|
||||
namespace control {
|
||||
|
||||
using std::string;
|
||||
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 (DUPLICATE_COMMAND); ///< Attempt to redefine an already existing command definition
|
||||
LUMIERA_ERROR_DECLARE (INVALID_ARGUMENTS); ///< Arguments provided for binding doesn't match stored command function parameters
|
||||
|
||||
|
||||
|
|
@ -76,9 +79,9 @@ namespace control {
|
|||
|
||||
public:
|
||||
/* === command registry === */
|
||||
static Command& get (Symbol cmdID);
|
||||
static bool remove (Symbol cmdID);
|
||||
static bool undef (Symbol cmdID);
|
||||
static Command get (Symbol cmdID);
|
||||
static bool remove (Symbol cmdID);
|
||||
static bool undef (Symbol cmdID);
|
||||
|
||||
CommandDef storeDef (Symbol newCmdID);
|
||||
|
||||
|
|
@ -100,6 +103,11 @@ namespace control {
|
|||
HandlingPattern const& getDefaultHandlingPattern() const;
|
||||
|
||||
|
||||
|
||||
/* === command lifecycle === */
|
||||
|
||||
Command& activate (CommandImpl&);
|
||||
|
||||
template<typename TYPES>
|
||||
void bindArg (Tuple<TYPES> const&);
|
||||
|
||||
|
|
@ -113,24 +121,17 @@ namespace control {
|
|||
bool canExec() const;
|
||||
bool canUndo() const;
|
||||
|
||||
operator string() const;
|
||||
friend bool operator== (Command const&, Command const&);
|
||||
|
||||
|
||||
protected:
|
||||
static Command& fetchDef (Symbol cmdID);
|
||||
static Command fetchDef (Symbol cmdID);
|
||||
|
||||
friend class CommandDef;
|
||||
|
||||
|
||||
private:
|
||||
/** Commands can only be created through the framework
|
||||
* (by setting up an CommandDef), thus ensuring there's
|
||||
* always a corresponding CommandImpl within the registry.
|
||||
* @note the copy operations are public though
|
||||
* @see Command#fetchDef
|
||||
* @see CommandDef
|
||||
*/
|
||||
Command (CommandImpl* pImpl);
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ namespace test {
|
|||
|
||||
// using lib::test::showSizeof;
|
||||
using util::isSameObject;
|
||||
using util::contains;
|
||||
|
||||
// using session::test::TestClip;
|
||||
// using lumiera::P;
|
||||
|
|
@ -97,6 +98,7 @@ namespace test {
|
|||
standardUse();
|
||||
definePrototype();
|
||||
usePrototype();
|
||||
preventDuplicates();
|
||||
undef();
|
||||
|
||||
ASSERT (0 == command1::check_);
|
||||
|
|
@ -138,7 +140,9 @@ namespace test {
|
|||
ASSERT (!Command::get("test.command1.2"));
|
||||
|
||||
Command com = Command::get("test.command1.2");
|
||||
ASSERT (!com);
|
||||
ASSERT (contains (str(com), "test.command1.2"));
|
||||
ASSERT (contains (str(com), "{def}"));
|
||||
ASSERT (!com); ////////////////////TODO: mismatch: shall bool() < canExec() ????
|
||||
ASSERT (!com.canUndo());
|
||||
VERIFY_ERROR (UNBOUND_ARGUMENTS, com() );
|
||||
|
||||
|
|
@ -248,6 +252,20 @@ namespace test {
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
preventDuplicates()
|
||||
{
|
||||
ASSERT (CommandDef ("test.command1.1"));
|
||||
VERIFY_ERROR (DUPLICATE_COMMAND, CommandDef ("test.command1.1").operation (command1::operate) );
|
||||
ASSERT (CommandDef ("test.command1.2"));
|
||||
VERIFY_ERROR (DUPLICATE_COMMAND, CommandDef ("test.command1.2").operation (command1::operate) );
|
||||
ASSERT (CommandDef ("test.command1.3"));
|
||||
VERIFY_ERROR (DUPLICATE_COMMAND, CommandDef ("test.command1.3").operation (command1::operate) );
|
||||
ASSERT (CommandDef ("test.command1.4"));
|
||||
VERIFY_ERROR (DUPLICATE_COMMAND, CommandDef ("test.command1.4").operation (command1::operate) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
undef()
|
||||
{
|
||||
|
|
@ -266,8 +284,15 @@ namespace test {
|
|||
CommandDef unbelievable ("miracle");
|
||||
ASSERT (!unbelievable);
|
||||
|
||||
Command miracle;
|
||||
// but because the miracle isn't yet defined, any use throws
|
||||
VERIFY_ERROR (INVALID_COMMAND, Command::get("miracle"));
|
||||
VERIFY_ERROR (INVALID_COMMAND, miracle.bind("abracadabra"));
|
||||
VERIFY_ERROR (INVALID_COMMAND, miracle.execSync());
|
||||
VERIFY_ERROR (INVALID_COMMAND, miracle.undo());
|
||||
VERIFY_ERROR (INVALID_COMMAND, miracle());
|
||||
ASSERT (!miracle.canExec());
|
||||
ASSERT (!miracle.canUndo());
|
||||
ASSERT (!miracle);
|
||||
|
||||
ASSERT (Command::remove("test.command1.1"));
|
||||
ASSERT (Command::remove("test.command1.2"));
|
||||
|
|
|
|||
Loading…
Reference in a new issue