WIP more implementation drafting...
This commit is contained in:
parent
19dd606f54
commit
eaa4adddde
7 changed files with 631 additions and 271 deletions
File diff suppressed because it is too large
Load diff
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 122 KiB |
|
|
@ -44,7 +44,7 @@
|
|||
#define LIB_HANDLE_H
|
||||
|
||||
#include "lib/nobug-init.hpp"
|
||||
#include "lib/sync.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include <tr1/memory>
|
||||
|
||||
|
|
@ -61,13 +61,14 @@ namespace lib {
|
|||
* and managing its lifecycle. Usually such a handle is created by
|
||||
* an service interface and \link #activate activated \endlink by
|
||||
* setting up the link to some internal implementation object.
|
||||
* This setup can only be done by a friend or derived class,
|
||||
* This setup can only be done by a friend or derived class, //////////////////////////TODO: that was the intention. Why didn't this work out as expected?
|
||||
* while client code is free to copy and store handle objects.
|
||||
* Finally, any handle can be closed, thereby decrementing
|
||||
* the use count.
|
||||
*/
|
||||
template<class IMP>
|
||||
class Handle
|
||||
: public lib::BoolCheckable<Handle<IMP> >
|
||||
{
|
||||
protected:
|
||||
typedef std::tr1::shared_ptr<IMP> SmPtr;
|
||||
|
|
@ -115,11 +116,8 @@ namespace lib {
|
|||
void close () { smPtr_.reset(); }
|
||||
|
||||
|
||||
typedef SmPtr Handle::*__unspecified_bool_type;
|
||||
|
||||
/** implicit conversion to "bool" */
|
||||
operator __unspecified_bool_type() const { return smPtr_? &Handle::smPtr_ : 0; } // never throws
|
||||
bool operator! () const { return !bool(smPtr_); } // ditto
|
||||
/** implicit conversion to bool (BoolCheckable) */
|
||||
bool isValid() const { return bool(smPtr_);}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ namespace control {
|
|||
: public lib::BoolCheckable<CommandDef>
|
||||
{
|
||||
Symbol id_;
|
||||
Command& prototype_;
|
||||
Command prototype_;
|
||||
|
||||
public:
|
||||
CommandDef (Symbol cmdID)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,20 @@ namespace control {
|
|||
|
||||
|
||||
/** */
|
||||
template<typename TYPES>
|
||||
void
|
||||
CommandImpl::bindArg (Tuple<TYPES> const&)
|
||||
{
|
||||
UNIMPLEMENTED ("actually bind arguments, maybe create ArgumentHolder");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CommandImpl::exec (HandlingPattern const& execPattern)
|
||||
{
|
||||
UNIMPLEMENTED ("actually invoke the command");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
|
||||
//#include "pre.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/singleton.hpp"
|
||||
#include "lib/sync.hpp"
|
||||
//#include "lib/bool-checkable.hpp"
|
||||
//#include "proc/control/command-closure.hpp"
|
||||
//#include "proc/control/memento-tie.hpp"
|
||||
|
|
@ -60,14 +62,67 @@ namespace control {
|
|||
* TODO type comment
|
||||
*/
|
||||
class CommandRegistry
|
||||
: lib::Sync<>
|
||||
{
|
||||
|
||||
public:
|
||||
static lumiera::Singleton<CommandRegistry> instance;
|
||||
|
||||
|
||||
/** register a command (Frontend) under the given ID
|
||||
* @return either the new command, or an already existing
|
||||
* command registerd under the given ID*/
|
||||
static Command&
|
||||
track (Symbol cmdID, Command& commandHandle)
|
||||
{
|
||||
return instance().putIndex (cmdID, commandHandle);
|
||||
}
|
||||
|
||||
|
||||
/** set up a new command implementation frame */
|
||||
static CommandImpl*
|
||||
newCommandImpl ()
|
||||
{
|
||||
return instance().createImpl();
|
||||
}
|
||||
|
||||
|
||||
/** discard an command implementation frame */
|
||||
static void
|
||||
killCommandImpl (CommandImpl* entry)
|
||||
{
|
||||
///////////////////////////////////////////////TODO: clean behaviour while in App shutdown (Ticket #196)
|
||||
instance().removeImpl(entry);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
CommandImpl*
|
||||
createImpl ()
|
||||
{
|
||||
Lock sync(this);
|
||||
UNIMPLEMENTED ("set up a new impl instance located within the instance table");
|
||||
}
|
||||
|
||||
void
|
||||
removeImpl (CommandImpl* entry)
|
||||
{
|
||||
UNIMPLEMENTED ("remove entry from instance table");
|
||||
}
|
||||
|
||||
Command&
|
||||
putIndex (Symbol cmdID, Command& commandHandle)
|
||||
{
|
||||
Lock sync(this);
|
||||
UNIMPLEMENTED ("place a commandHandle into the command index, or return the command already registered there");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// inline ostream& operator<< (ostream& os, Mutation const& muta) { return os << string(muta); }
|
||||
|
||||
/** storage for the singleton factory used to access CommandRegistry */
|
||||
lumiera::Singleton<CommandRegistry> CommandRegistry::instance;
|
||||
|
||||
|
||||
} // namespace control
|
||||
|
|
|
|||
|
|
@ -48,10 +48,17 @@ namespace control {
|
|||
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");
|
||||
|
||||
|
||||
|
||||
|
||||
Command::~Command() { }
|
||||
|
||||
|
||||
/** @internal to be invoked by #fetchDef */
|
||||
Command::Command (CommandImpl* pImpl)
|
||||
{
|
||||
Handle::activate (pImpl, CommandRegistry::killCommandImpl);
|
||||
}
|
||||
|
||||
|
||||
/** */
|
||||
Command&
|
||||
|
|
@ -64,7 +71,14 @@ namespace control {
|
|||
Command&
|
||||
Command::fetchDef (Symbol cmdID)
|
||||
{
|
||||
UNIMPLEMENTED ("fetch an command prototype from the registry, create if necessary");
|
||||
Command* cmd = CommandRegistry::queryIndex (cmdID);
|
||||
if (cmd)
|
||||
////////////////////////////////////////////////////////////////////////TODO: race
|
||||
return *cmd;
|
||||
|
||||
Command newDefinition (CommandRegistry::newCommandImpl());
|
||||
|
||||
return CommandRegistry::track (cmdID, newDefinition);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -67,9 +67,10 @@ namespace control {
|
|||
* @todo Type-comment
|
||||
*/
|
||||
class Command
|
||||
: public com::ArgumentBinder<Command
|
||||
, lib::BoolCheckable<Command> >
|
||||
////////////////////////////////////////////////////////////////TODO: inherit from lib/handle
|
||||
: public com::ArgumentBinder<Command // accepts arbitrary bind(..) calls (with runtime check)
|
||||
, lib::BoolCheckable<Command // implicit conversion to bool for status check
|
||||
, lib::Handle<CommandImpl> // actually implemented as ref counting Handle
|
||||
> >
|
||||
{
|
||||
|
||||
public:
|
||||
|
|
@ -112,10 +113,21 @@ namespace control {
|
|||
bool canUndo() 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);
|
||||
|
||||
friend class CommandDef;
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue