build new cmd impl object within registry
This commit is contained in:
parent
59f42c28ef
commit
155254dd9b
8 changed files with 126 additions and 36 deletions
|
|
@ -85,6 +85,7 @@ NOBUG_CPP_DEFINE_FLAG_PARENT ( mmapings_dbg, backend_dbg);
|
|||
NOBUG_CPP_DEFINE_FLAG_PARENT ( threads_dbg, backend_dbg);
|
||||
/** base of debug logging for the proc layer */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( proc_dbg, debugging);
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( command_dbg, proc_dbg);
|
||||
/** base of debug logging for the gui */
|
||||
NOBUG_CPP_DEFINE_FLAG_PARENT ( gui_dbg, debugging);
|
||||
/** base if debug logging for the support library */
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
typedef typename CommandSignature<SIG,MEM>::OperateSig SIG_op;
|
||||
typedef typename CommandSignature<SIG,MEM>::CaptureSig SIG_cap;
|
||||
typedef typename CommandSignature<SIG,MEM>::UndoOp_Sig SIG_undo;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "include/symbol.hpp"
|
||||
#include "proc/control/command.hpp"
|
||||
#include "proc/control/command-impl.hpp" /////TODO: any chance to get rid of this import here??
|
||||
#include "proc/control/command-registry.hpp"
|
||||
#include "proc/control/command-signature.hpp"
|
||||
#include "proc/control/command-mutation.hpp"
|
||||
|
|
@ -128,9 +129,9 @@ namespace control {
|
|||
REQUIRE (captFunctor_);
|
||||
|
||||
CommandRegistry& registry = CommandRegistry::instance();
|
||||
CommandImpl& completedDef = registry.newCommandImpl(operFunctor_
|
||||
,undoFunctor_
|
||||
,captFunctor_);
|
||||
CommandImpl* completedDef = registry.newCommandImpl(operFunctor_
|
||||
,captFunctor_
|
||||
,undoFunctor_);
|
||||
prototype_.activate(completedDef);
|
||||
ENSURE (prototype_);
|
||||
return *this;
|
||||
|
|
|
|||
|
|
@ -47,14 +47,6 @@ namespace control {
|
|||
|
||||
|
||||
/** */
|
||||
template<typename TYPES>
|
||||
void
|
||||
CommandImpl::bindArg (Tuple<TYPES> const&)
|
||||
{
|
||||
UNIMPLEMENTED ("actually bind arguments, maybe create ArgumentHolder");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CommandImpl::exec (HandlingPattern const& execPattern)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,17 +44,20 @@
|
|||
|
||||
#include "proc/control/command.hpp"
|
||||
#include "proc/control/command-mutation.hpp"
|
||||
#include "proc/control/command-argument-holder.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
//#include <tr1/memory>
|
||||
|
||||
#include <tr1/memory>
|
||||
#include <tr1/functional>
|
||||
|
||||
|
||||
namespace control {
|
||||
|
||||
using std::tr1::function;
|
||||
using std::tr1::shared_ptr;
|
||||
|
||||
|
||||
|
||||
|
|
@ -69,8 +72,40 @@ namespace control {
|
|||
Mutation do_;
|
||||
UndoMutation undo_;
|
||||
|
||||
shared_ptr<CmdClosure> pClo_;
|
||||
|
||||
|
||||
template<typename ARG>
|
||||
struct _Type
|
||||
{
|
||||
typedef typename ARG::SIG_op SIG_op;
|
||||
typedef typename ARG::SIG_cap SIG_cap;
|
||||
typedef typename ARG::SIG_undo SIG_undo;
|
||||
|
||||
typedef function<SIG_op> Func_op;
|
||||
typedef function<SIG_cap> Func_cap;
|
||||
typedef function<SIG_undo> Func_undo;
|
||||
};
|
||||
#define _TY(_ID_) typename _Type<ARG>::_ID_
|
||||
|
||||
public:
|
||||
/* === command registry === */
|
||||
/** build a new implementation frame, and do the initial wiring.
|
||||
* On the interface the specific type is discarded afterwards.
|
||||
* This information is still kept though, as encoded into the vtable
|
||||
* of the embedded FunErasure objects holding the command operation
|
||||
* and undo functors, and the vtable of the embedded CmdClosure */
|
||||
template<typename ARG>
|
||||
CommandImpl (shared_ptr<ARG> pArgHolder
|
||||
,_TY (Func_op) const& operFunctor
|
||||
,_TY (Func_cap) const& captFunctor
|
||||
,_TY (Func_undo) const& undoFunctor
|
||||
)
|
||||
: do_(operFunctor)
|
||||
, undo_(pArgHolder->tie (undoFunctor, captFunctor))
|
||||
, pClo_(pArgHolder)
|
||||
{ }
|
||||
|
||||
#undef _TY
|
||||
|
||||
|
||||
~CommandImpl();
|
||||
|
|
@ -84,7 +119,11 @@ namespace control {
|
|||
|
||||
|
||||
template<typename TYPES>
|
||||
void bindArg (Tuple<TYPES> const&);
|
||||
void bindArg (Tuple<TYPES> const&)
|
||||
{
|
||||
UNIMPLEMENTED ("actually bind arguments, maybe create ArgumentHolder");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* === diagnostics === */
|
||||
|
|
|
|||
|
|
@ -41,20 +41,26 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "lib/singleton.hpp"
|
||||
#include "lib/sync.hpp"
|
||||
#include "lib/format.hpp"
|
||||
#include "include/logging.h"
|
||||
//#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include "proc/control/command.hpp"
|
||||
#include "proc/control/command-signature.hpp"
|
||||
#include "proc/control/command-argument-holder.hpp"
|
||||
//#include "proc/control/memento-tie.hpp"
|
||||
|
||||
#include <tr1/memory>
|
||||
//#include <iostream>
|
||||
//#include <string>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
namespace control {
|
||||
|
||||
using std::tr1::shared_ptr;
|
||||
// using std::ostream;
|
||||
// using std::string;
|
||||
using std::string;
|
||||
|
||||
|
||||
|
||||
|
|
@ -121,41 +127,90 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
/** set up a new command implementation frame */
|
||||
/** set up a new command implementation frame
|
||||
* @return pointer to a newly created CommandImpl, allocated
|
||||
* through the registry. The caller is responsible for
|
||||
* deallocating this frame by calling #killCommandImpl
|
||||
*/
|
||||
template< typename SIG_OPER ///< signature of the command operation
|
||||
, typename SIG_UNDO ///< signature to undo the command
|
||||
, typename SIG_CAPT ///< signature for capturing undo state
|
||||
, typename SIG_UNDO ///< signature to undo the command
|
||||
>
|
||||
CommandImpl&
|
||||
newCommandImpl (function<SIG_OPER>& operFunctor_
|
||||
,function<SIG_UNDO>& undoFunctor_
|
||||
,function<SIG_CAPT>& captFunctor_)
|
||||
CommandImpl*
|
||||
newCommandImpl (function<SIG_OPER>& operFunctor
|
||||
,function<SIG_CAPT>& captFunctor
|
||||
,function<SIG_UNDO>& undoFunctor)
|
||||
{
|
||||
Lock sync(this);
|
||||
UNIMPLEMENTED ("set up a new impl instance located within the instance table");
|
||||
}
|
||||
|
||||
// derive the storage type necessary
|
||||
// to hold the command arguments and UNDO memento
|
||||
typedef typename UndoSignature<SIG_CAPT>::Memento Mem;
|
||||
typedef ArgumentHolder<SIG_OPER,Mem> Arguments;
|
||||
|
||||
shared_ptr<Arguments> pArg ( new (allocateSlot<Arguments>()) Arguments()
|
||||
, &kill<Arguments>
|
||||
);
|
||||
void* implStorage = 0;
|
||||
try
|
||||
{
|
||||
implStorage = allocateSlot<CommandImpl>();
|
||||
ASSERT (implStorage);
|
||||
|
||||
return new(implStorage) CommandImpl (pArg, operFunctor,captFunctor,undoFunctor);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
if (implStorage)
|
||||
releaseSlot<CommandImpl> (implStorage);
|
||||
throw;
|
||||
} }
|
||||
|
||||
|
||||
/** discard an command implementation frame */
|
||||
/** delete the command implementation and free the corresponding allocation */
|
||||
static void killCommandImpl (CommandImpl* entry) { kill(entry); }
|
||||
|
||||
|
||||
template<class IMP>
|
||||
static void
|
||||
killCommandImpl (CommandImpl* entry)
|
||||
kill (IMP* entry)
|
||||
{
|
||||
///////////////////////////////////////////////TODO: clean behaviour while in App shutdown (Ticket #196)
|
||||
instance().removeImpl(entry);
|
||||
instance().destroyImpl(entry);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
CommandImpl*
|
||||
createImpl ()
|
||||
template<class IMP>
|
||||
void*
|
||||
allocateSlot ()
|
||||
{
|
||||
///////////////////////////////TODO: still necessary?
|
||||
TODO ("redirect to the corresponding pool allocator");
|
||||
}
|
||||
|
||||
template<class IMP>
|
||||
void
|
||||
removeImpl (CommandImpl* entry)
|
||||
releaseSlot (void* entry)
|
||||
{
|
||||
UNIMPLEMENTED ("remove entry from instance table");
|
||||
TODO ("redirect to the corresponding pool allocator");
|
||||
}
|
||||
|
||||
|
||||
template<class IMP>
|
||||
void
|
||||
destroyImpl (IMP* entry)
|
||||
{
|
||||
if (!entry) return;
|
||||
try
|
||||
{
|
||||
entry->~IMP();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
WARN (command_dbg, "dtor of %s failed: %s", util::tyStr(entry).c_str()
|
||||
, lumiera_error() );
|
||||
}
|
||||
releaseSlot<IMP> (entry);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -118,14 +118,15 @@ namespace control {
|
|||
* @throw std::bad_alloc, in which case
|
||||
* CommandRegistry::killCommandImpl is invoked */
|
||||
Command&
|
||||
Command::activate (CommandImpl& implFrame)
|
||||
Command::activate (CommandImpl* implFrame)
|
||||
{
|
||||
static format fmt("Command \"%s\" already defined");
|
||||
REQUIRE (implFrame);
|
||||
|
||||
if (this->isValid())
|
||||
throw error::Logic (str (fmt % *this), LUMIERA_ERROR_DUPLICATE_COMMAND);
|
||||
|
||||
_Handle::activate (&implFrame, CommandRegistry::killCommandImpl);
|
||||
_Handle::activate (implFrame, CommandRegistry::killCommandImpl);
|
||||
|
||||
INFO (command, "Command \"%s\" defined OK", cStr(*this));
|
||||
return *this;
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ namespace control {
|
|||
|
||||
/* === command lifecycle === */
|
||||
|
||||
Command& activate (CommandImpl&);
|
||||
Command& activate (CommandImpl*);
|
||||
|
||||
template<typename TYPES>
|
||||
Command& bindArg (Tuple<TYPES> const&);
|
||||
|
|
|
|||
Loading…
Reference in a new issue