LUMIERA.clone/src/proc/control/command-registry.hpp

221 lines
6.2 KiB
C++
Raw Normal View History

2009-07-21 04:49:00 +02:00
/*
COMMAND-REGISTRY.hpp - proc-Command object registration and storage management
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-registry.hpp
** Managing command definitions and the storage of individual command objects.
** @todo WIP WIP.
**
** \par Lifecycle
**
** @see Command
** @see ProcDispatcher
**
*/
#ifndef CONTROL_COMMAND_REGISTRY_H
#define CONTROL_COMMAND_REGISTRY_H
//#include "pre.hpp"
#include "lib/error.hpp"
2009-07-29 16:55:15 +02:00
#include "lib/singleton.hpp"
#include "lib/sync.hpp"
#include "lib/format.hpp"
#include "include/logging.h"
2009-07-21 04:49:00 +02:00
//#include "lib/bool-checkable.hpp"
#include "proc/control/command.hpp"
#include "proc/control/command-signature.hpp"
#include "proc/control/command-argument-holder.hpp"
2009-07-21 04:49:00 +02:00
//#include "proc/control/memento-tie.hpp"
#include <tr1/memory>
2009-07-21 04:49:00 +02:00
//#include <iostream>
#include <string>
2009-07-21 04:49:00 +02:00
namespace control {
using std::tr1::shared_ptr;
2009-07-21 04:49:00 +02:00
// using std::ostream;
using std::string;
2009-07-21 04:49:00 +02:00
/**
* TODO type comment
*/
class CommandRegistry
: public lib::Sync<>
2009-07-21 04:49:00 +02:00
{
public:
2009-07-29 16:55:15 +02:00
static lumiera::Singleton<CommandRegistry> instance;
/** register a command (Frontend) under the given ID
* @return either the new command, or an already existing
* command registered under the given ID*/
Command
track (Symbol cmdID, Command const& commandHandle)
2009-07-29 16:55:15 +02:00
{
Lock sync(this);
UNIMPLEMENTED ("place a commandHandle into the command index, or return the command already registered there");
2009-07-29 16:55:15 +02:00
}
/** query the command index by ID
* @return the registered command,
* or an "invalid" token */
Command
queryIndex (Symbol cmdID)
{
Lock sync(this);
UNIMPLEMENTED ("retrieve the command registered under the given ID, maybe return an »empty« command");
// if index.contains(cmdID)
// return index[cmdID]
// else
return Command();
}
2009-08-01 17:14:27 +02:00
/** 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 */
const char*
2009-08-01 17:14:27 +02:00
findDefinition (Command const& cmdInstance)
{
UNIMPLEMENTED ("try to find a registration in the index for a given command instance");
}
size_t
index_size()
2009-08-01 17:14:27 +02:00
{
UNIMPLEMENTED ("number of defs in the index");
}
size_t
instance_count()
2009-08-01 17:14:27 +02:00
{
UNIMPLEMENTED ("number of active command impl instances");
}
/** 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_CAPT ///< signature for capturing undo state
, typename SIG_UNDO ///< signature to undo the command
>
CommandImpl*
newCommandImpl (function<SIG_OPER>& operFunctor
,function<SIG_CAPT>& captFunctor
,function<SIG_UNDO>& undoFunctor)
2009-07-29 16:55:15 +02:00
{
Lock sync(this);
// 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;
} }
/** delete the command implementation and free the corresponding allocation */
static void killCommandImpl (CommandImpl* entry) { kill(entry); }
template<class IMP>
2009-07-29 16:55:15 +02:00
static void
kill (IMP* entry)
2009-07-29 16:55:15 +02:00
{
///////////////////////////////////////////////TODO: clean behaviour while in App shutdown (Ticket #196)
instance().destroyImpl(entry);
2009-07-29 16:55:15 +02:00
}
private:
template<class IMP>
void*
allocateSlot ()
{
TODO ("redirect to the corresponding pool allocator");
}
template<class IMP>
void
releaseSlot (void* entry)
2009-07-29 16:55:15 +02:00
{
TODO ("redirect to the corresponding pool allocator");
2009-07-29 16:55:15 +02:00
}
template<class IMP>
2009-07-29 16:55:15 +02:00
void
destroyImpl (IMP* entry)
2009-07-29 16:55:15 +02:00
{
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);
2009-07-29 16:55:15 +02:00
}
2009-07-21 04:49:00 +02:00
};
} // namespace control
#endif