WIP more implementation drafting...

This commit is contained in:
Fischlurch 2009-07-29 16:55:15 +02:00
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

View file

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

View file

@ -191,7 +191,7 @@ namespace control {
: public lib::BoolCheckable<CommandDef>
{
Symbol id_;
Command& prototype_;
Command prototype_;
public:
CommandDef (Symbol cmdID)

View file

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

View file

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

View file

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

View file

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