build new cmd impl object within registry

This commit is contained in:
Fischlurch 2009-08-03 18:17:41 +02:00
parent 59f42c28ef
commit 155254dd9b
8 changed files with 126 additions and 36 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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 === */

View file

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

View file

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

View file

@ -115,7 +115,7 @@ namespace control {
/* === command lifecycle === */
Command& activate (CommandImpl&);
Command& activate (CommandImpl*);
template<typename TYPES>
Command& bindArg (Tuple<TYPES> const&);