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
|
#define LIB_HANDLE_H
|
||||||
|
|
||||||
#include "lib/nobug-init.hpp"
|
#include "lib/nobug-init.hpp"
|
||||||
#include "lib/sync.hpp"
|
#include "lib/bool-checkable.hpp"
|
||||||
|
|
||||||
#include <tr1/memory>
|
#include <tr1/memory>
|
||||||
|
|
||||||
|
|
@ -61,13 +61,14 @@ namespace lib {
|
||||||
* and managing its lifecycle. Usually such a handle is created by
|
* and managing its lifecycle. Usually such a handle is created by
|
||||||
* an service interface and \link #activate activated \endlink by
|
* an service interface and \link #activate activated \endlink by
|
||||||
* setting up the link to some internal implementation object.
|
* 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.
|
* while client code is free to copy and store handle objects.
|
||||||
* Finally, any handle can be closed, thereby decrementing
|
* Finally, any handle can be closed, thereby decrementing
|
||||||
* the use count.
|
* the use count.
|
||||||
*/
|
*/
|
||||||
template<class IMP>
|
template<class IMP>
|
||||||
class Handle
|
class Handle
|
||||||
|
: public lib::BoolCheckable<Handle<IMP> >
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
typedef std::tr1::shared_ptr<IMP> SmPtr;
|
typedef std::tr1::shared_ptr<IMP> SmPtr;
|
||||||
|
|
@ -115,11 +116,8 @@ namespace lib {
|
||||||
void close () { smPtr_.reset(); }
|
void close () { smPtr_.reset(); }
|
||||||
|
|
||||||
|
|
||||||
typedef SmPtr Handle::*__unspecified_bool_type;
|
/** implicit conversion to bool (BoolCheckable) */
|
||||||
|
bool isValid() const { return bool(smPtr_);}
|
||||||
/** implicit conversion to "bool" */
|
|
||||||
operator __unspecified_bool_type() const { return smPtr_? &Handle::smPtr_ : 0; } // never throws
|
|
||||||
bool operator! () const { return !bool(smPtr_); } // ditto
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ namespace control {
|
||||||
: public lib::BoolCheckable<CommandDef>
|
: public lib::BoolCheckable<CommandDef>
|
||||||
{
|
{
|
||||||
Symbol id_;
|
Symbol id_;
|
||||||
Command& prototype_;
|
Command prototype_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CommandDef (Symbol cmdID)
|
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 "pre.hpp"
|
||||||
#include "lib/error.hpp"
|
#include "lib/error.hpp"
|
||||||
|
#include "lib/singleton.hpp"
|
||||||
|
#include "lib/sync.hpp"
|
||||||
//#include "lib/bool-checkable.hpp"
|
//#include "lib/bool-checkable.hpp"
|
||||||
//#include "proc/control/command-closure.hpp"
|
//#include "proc/control/command-closure.hpp"
|
||||||
//#include "proc/control/memento-tie.hpp"
|
//#include "proc/control/memento-tie.hpp"
|
||||||
|
|
@ -60,14 +62,67 @@ namespace control {
|
||||||
* TODO type comment
|
* TODO type comment
|
||||||
*/
|
*/
|
||||||
class CommandRegistry
|
class CommandRegistry
|
||||||
|
: lib::Sync<>
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
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); }
|
// 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
|
} // namespace control
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,13 @@ namespace control {
|
||||||
Command::~Command() { }
|
Command::~Command() { }
|
||||||
|
|
||||||
|
|
||||||
|
/** @internal to be invoked by #fetchDef */
|
||||||
|
Command::Command (CommandImpl* pImpl)
|
||||||
|
{
|
||||||
|
Handle::activate (pImpl, CommandRegistry::killCommandImpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
Command&
|
Command&
|
||||||
Command::get (Symbol cmdID)
|
Command::get (Symbol cmdID)
|
||||||
|
|
@ -64,7 +71,14 @@ namespace control {
|
||||||
Command&
|
Command&
|
||||||
Command::fetchDef (Symbol cmdID)
|
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
|
* @todo Type-comment
|
||||||
*/
|
*/
|
||||||
class Command
|
class Command
|
||||||
: public com::ArgumentBinder<Command
|
: public com::ArgumentBinder<Command // accepts arbitrary bind(..) calls (with runtime check)
|
||||||
, lib::BoolCheckable<Command> >
|
, lib::BoolCheckable<Command // implicit conversion to bool for status check
|
||||||
////////////////////////////////////////////////////////////////TODO: inherit from lib/handle
|
, lib::Handle<CommandImpl> // actually implemented as ref counting Handle
|
||||||
|
> >
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -112,9 +113,20 @@ namespace control {
|
||||||
bool canUndo() const;
|
bool canUndo() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static Command& fetchDef (Symbol cmdID);
|
static Command& fetchDef (Symbol cmdID);
|
||||||
|
|
||||||
friend class CommandDef;
|
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);
|
||||||
|
|
||||||
};
|
};
|
||||||
////////////////TODO currently just fleshing out the API....
|
////////////////TODO currently just fleshing out the API....
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue