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"
|
2009-08-03 18:17:41 +02:00
|
|
|
#include "lib/format.hpp"
|
|
|
|
|
#include "include/logging.h"
|
2009-07-21 04:49:00 +02:00
|
|
|
//#include "lib/bool-checkable.hpp"
|
2009-07-30 03:57:19 +02:00
|
|
|
|
|
|
|
|
#include "proc/control/command.hpp"
|
2009-08-03 18:17:41 +02:00
|
|
|
#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"
|
|
|
|
|
|
2009-08-03 18:17:41 +02:00
|
|
|
#include <tr1/memory>
|
2009-07-21 04:49:00 +02:00
|
|
|
//#include <iostream>
|
2009-08-03 18:17:41 +02:00
|
|
|
#include <string>
|
2009-07-21 04:49:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace control {
|
|
|
|
|
|
2009-08-03 18:17:41 +02:00
|
|
|
using std::tr1::shared_ptr;
|
2009-07-21 04:49:00 +02:00
|
|
|
// using std::ostream;
|
2009-08-03 18:17:41 +02:00
|
|
|
using std::string;
|
2009-07-21 04:49:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* TODO type comment
|
|
|
|
|
*/
|
|
|
|
|
class CommandRegistry
|
2009-08-01 23:57:12 +02:00
|
|
|
: 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
|
2009-07-30 03:57:19 +02:00
|
|
|
* command registered under the given ID*/
|
2009-07-30 20:50:57 +02:00
|
|
|
Command
|
2009-07-30 03:57:19 +02:00
|
|
|
track (Symbol cmdID, Command const& commandHandle)
|
2009-07-29 16:55:15 +02:00
|
|
|
{
|
2009-07-30 20:50:57 +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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-07-30 03:57:19 +02:00
|
|
|
/** query the command index by ID
|
|
|
|
|
* @return the registered command,
|
|
|
|
|
* or an "invalid" token */
|
2009-07-30 20:50:57 +02:00
|
|
|
Command
|
2009-07-30 03:57:19 +02:00
|
|
|
queryIndex (Symbol cmdID)
|
|
|
|
|
{
|
2009-07-30 20:50:57 +02:00
|
|
|
Lock sync(this);
|
2009-08-01 02:18:01 +02:00
|
|
|
UNIMPLEMENTED ("retrieve the command registered under the given ID, maybe return an »empty« command");
|
2009-07-30 20:50:57 +02:00
|
|
|
// if index.contains(cmdID)
|
|
|
|
|
// return index[cmdID]
|
|
|
|
|
// else
|
|
|
|
|
return Command();
|
2009-07-30 03:57:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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 */
|
2009-08-01 23:57:12 +02:00
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-08-01 02:18:01 +02:00
|
|
|
size_t
|
|
|
|
|
index_size()
|
2009-08-01 17:14:27 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED ("number of defs in the index");
|
|
|
|
|
}
|
2009-08-01 02:18:01 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t
|
|
|
|
|
instance_count()
|
2009-08-01 17:14:27 +02:00
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED ("number of active command impl instances");
|
|
|
|
|
}
|
2009-08-01 02:18:01 +02:00
|
|
|
|
|
|
|
|
|
2009-08-03 18:17:41 +02:00
|
|
|
/** 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
|
|
|
|
|
*/
|
2009-08-01 23:57:12 +02:00
|
|
|
template< typename SIG_OPER ///< signature of the command operation
|
|
|
|
|
, typename SIG_CAPT ///< signature for capturing undo state
|
2009-08-03 18:17:41 +02:00
|
|
|
, typename SIG_UNDO ///< signature to undo the command
|
2009-08-01 23:57:12 +02:00
|
|
|
>
|
2009-08-03 18:17:41 +02:00
|
|
|
CommandImpl*
|
|
|
|
|
newCommandImpl (function<SIG_OPER>& operFunctor
|
|
|
|
|
,function<SIG_CAPT>& captFunctor
|
|
|
|
|
,function<SIG_UNDO>& undoFunctor)
|
2009-07-29 16:55:15 +02:00
|
|
|
{
|
2009-07-30 20:50:57 +02:00
|
|
|
Lock sync(this);
|
2009-08-03 18:17:41 +02:00
|
|
|
|
|
|
|
|
// 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
|
2009-08-03 18:17:41 +02:00
|
|
|
kill (IMP* entry)
|
2009-07-29 16:55:15 +02:00
|
|
|
{
|
|
|
|
|
///////////////////////////////////////////////TODO: clean behaviour while in App shutdown (Ticket #196)
|
2009-08-03 18:17:41 +02:00
|
|
|
instance().destroyImpl(entry);
|
2009-07-29 16:55:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
2009-08-03 18:17:41 +02:00
|
|
|
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
|
|
|
{
|
2009-08-03 18:17:41 +02:00
|
|
|
TODO ("redirect to the corresponding pool allocator");
|
2009-07-29 16:55:15 +02:00
|
|
|
}
|
|
|
|
|
|
2009-08-03 18:17:41 +02:00
|
|
|
|
|
|
|
|
template<class IMP>
|
2009-07-29 16:55:15 +02:00
|
|
|
void
|
2009-08-03 18:17:41 +02:00
|
|
|
destroyImpl (IMP* entry)
|
2009-07-29 16:55:15 +02:00
|
|
|
{
|
2009-08-03 18:17:41 +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
|