Basic implementation of HandlingPattern settled for now
the ''real implementation'' (integrated with the ProcDispatcher) is still missing, but it's enough to get the tests going
This commit is contained in:
parent
effbb49afb
commit
248b87f344
3 changed files with 102 additions and 92 deletions
|
|
@ -25,12 +25,8 @@
|
|||
#include "proc/control/handling-pattern.hpp"
|
||||
#include "proc/control/handling-patterns.hpp"
|
||||
|
||||
#include "lib/symbol.hpp"
|
||||
#include "include/logging.h"
|
||||
#include "lib/util.hpp"
|
||||
//#include "proc/mobject/mobject-ref.hpp"
|
||||
//#include "proc/mobject/mobject.hpp"
|
||||
//#include "proc/mobject/placement.hpp"
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
|
|
@ -44,16 +40,14 @@ using util::isnil;
|
|||
|
||||
namespace control {
|
||||
|
||||
/** */
|
||||
/** retrieve pre-configured pattern */
|
||||
HandlingPattern const&
|
||||
HandlingPattern::get (ID id)
|
||||
{
|
||||
REQUIRE ((0 <= id) && (id < NUM_IDS));
|
||||
|
||||
return getPatternInstance(id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @note: does error handling, but delegates the actual
|
||||
* execution to the protected (subclass) member */
|
||||
ExecResult
|
||||
|
|
@ -69,8 +63,8 @@ namespace control {
|
|||
if (errID_pre)
|
||||
return ExecResult (error::Logic (str (err_pre % command), errID_pre));
|
||||
|
||||
// Execute the command
|
||||
dispatch (command);
|
||||
// execute or undo it...
|
||||
perform (command);
|
||||
|
||||
Symbol errID = lumiera_error();
|
||||
if (errID)
|
||||
|
|
@ -103,20 +97,6 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
HandlingPattern::dispatch (CommandImpl& command)
|
||||
{
|
||||
perform (command);
|
||||
}
|
||||
|
||||
|
||||
HandlingPattern const&
|
||||
HandlingPattern::howtoUNDO() const
|
||||
{
|
||||
UNIMPLEMENTED ("yield a handling pattern suitable for UNDOing a command, according to this pattern");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ====== execution result state object ======= */
|
||||
|
||||
|
|
@ -141,6 +121,6 @@ namespace control {
|
|||
if (!isnil (log_))
|
||||
throw error::Logic ("Command execution failed: "+log_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace control
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
|
||||
/** @file handling-pattern.hpp
|
||||
** Pre-defined command execution templates.
|
||||
** Pre-defined command execution skeletons.
|
||||
** Any command can be configured to use a specific handling pattern
|
||||
** on invocation. Moreover, there is a default handling pattern for commands.
|
||||
** These patterns define the steps necessary for getting the command actually
|
||||
|
|
@ -46,10 +46,9 @@
|
|||
|
||||
//#include "pre.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
|
@ -58,14 +57,16 @@ namespace control {
|
|||
|
||||
using std::string;
|
||||
using lib::Symbol;
|
||||
// using std::tr1::shared_ptr;
|
||||
|
||||
|
||||
class CommandImpl;
|
||||
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
* Result (Status) of command execution.
|
||||
* It is returned when invoking a HandlingPattern
|
||||
* and can be used to check for success and/or re-throw
|
||||
* any Exception encountered during the command execution.
|
||||
*/
|
||||
class ExecResult
|
||||
: public lib::BoolCheckable<ExecResult>
|
||||
|
|
@ -83,8 +84,18 @@ namespace control {
|
|||
friend class HandlingPattern;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
* Operation Skeleton how to invoke or undo a command.
|
||||
* Concrete implementations may be retrieved by ID;
|
||||
* they range from just invoking the command operations
|
||||
* straight forward to dispatching with the ProcDispatcher
|
||||
* or running the command asynchronously in a background thread.
|
||||
* A HandlingPattern first of all describes how to invoke the
|
||||
* command operation, but for each pattern it is possible to
|
||||
* get a special "undo pattern", which, on activation, will
|
||||
* reverse the effect of the basic pattern.
|
||||
*/
|
||||
class HandlingPattern
|
||||
: public lib::BoolCheckable<HandlingPattern>
|
||||
|
|
@ -114,23 +125,23 @@ namespace control {
|
|||
* detect errors on execution */
|
||||
ExecResult invoke (CommandImpl& command, Symbol name) const;
|
||||
|
||||
/** @return HandlingPatter describing how the UNDO operation is to be performed */
|
||||
HandlingPattern const& howtoUNDO() const;
|
||||
/** @return HandlingPattern describing how the UNDO operation is to be performed */
|
||||
HandlingPattern const& howtoUNDO() const { return getUndoPatt(); }
|
||||
|
||||
|
||||
virtual bool isValid() const =0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void dispatch(CommandImpl& command) const;
|
||||
virtual HandlingPattern const& getUndoPatt() const =0;
|
||||
virtual void perform (CommandImpl& command) const =0;
|
||||
|
||||
virtual void perform (CommandImpl& command) const =0;
|
||||
virtual void revert (CommandImpl& command) const =0;
|
||||
virtual void exec (CommandImpl& command) const =0;
|
||||
virtual void undo (CommandImpl& command) const =0;
|
||||
|
||||
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -47,23 +47,72 @@
|
|||
#include "lib/multifact.hpp"
|
||||
#include "proc/control/handling-pattern.hpp"
|
||||
#include "proc/control/command-impl.hpp"
|
||||
#include "include/lifecycle.h"
|
||||
//#include "lib/symbol.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
//#include <string>
|
||||
#include<vector>
|
||||
|
||||
|
||||
|
||||
namespace control {
|
||||
|
||||
namespace { // concrete command handling patterns
|
||||
|
||||
using std::vector;
|
||||
// using std::string;
|
||||
// using lib::Symbol;
|
||||
// using std::tr1::shared_ptr;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handling Pattern Foundation: invoke command directly and without
|
||||
* any external intervention. This pattern is intended as implementation
|
||||
* base class, but can be used as-is for unit tests.
|
||||
*/
|
||||
class BasicHandlingPattern
|
||||
: public HandlingPattern
|
||||
{
|
||||
bool isValid() const { return true; }
|
||||
|
||||
void
|
||||
exec (CommandImpl& command) const
|
||||
{
|
||||
REQUIRE (command.canExec());
|
||||
command.invokeCapture();
|
||||
command.invokeOperation();
|
||||
}
|
||||
|
||||
void
|
||||
undo (CommandImpl& command) const
|
||||
{
|
||||
REQUIRE (command.canUndo());
|
||||
command.invokeUndo();
|
||||
}
|
||||
|
||||
/* == invoking operation or undo == */
|
||||
|
||||
void perform (CommandImpl& command) const { return exec(command); }
|
||||
|
||||
class UndoProxyPattern
|
||||
: public HandlingPattern
|
||||
{
|
||||
BasicHandlingPattern& basePatt_;
|
||||
|
||||
bool isValid() const { return basePatt_.isValid(); }
|
||||
void exec (CommandImpl& command) const { return basePatt_.exec(command); }
|
||||
void undo (CommandImpl& command) const { return basePatt_.undo(command); }
|
||||
|
||||
void perform (CommandImpl& command) const { return undo(command); }
|
||||
HandlingPattern const& getUndoPatt() const { return basePatt_; }
|
||||
|
||||
public:
|
||||
UndoProxyPattern (BasicHandlingPattern& refPattern)
|
||||
: basePatt_(refPattern)
|
||||
{ }
|
||||
};
|
||||
|
||||
HandlingPattern const& getUndoPatt() const { return standardUndoPattern_; }
|
||||
UndoProxyPattern standardUndoPattern_;
|
||||
friend class UndoProxyPattern;
|
||||
|
||||
public:
|
||||
BasicHandlingPattern()
|
||||
: standardUndoPattern_(*this)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
@ -72,16 +121,16 @@ namespace control {
|
|||
* @todo describe this pattern in more detail....
|
||||
*/
|
||||
class InvokeSyncNoThrow
|
||||
: public HandlingPattern
|
||||
: public BasicHandlingPattern
|
||||
{
|
||||
void
|
||||
perform (CommandImpl& command) const
|
||||
exec (CommandImpl& command) const
|
||||
{
|
||||
UNIMPLEMENTED ("actually invoke a command, according to this pattern");
|
||||
}
|
||||
|
||||
void
|
||||
revert(CommandImpl& command) const
|
||||
undo (CommandImpl& command) const
|
||||
{
|
||||
UNIMPLEMENTED ("actually undo the effect of a command, according to this pattern");
|
||||
}
|
||||
|
|
@ -100,16 +149,16 @@ namespace control {
|
|||
* @todo describe this pattern in more detail....
|
||||
*/
|
||||
class InvokeSyncThrow
|
||||
: public HandlingPattern
|
||||
: public BasicHandlingPattern
|
||||
{
|
||||
void
|
||||
perform (CommandImpl& command) const
|
||||
exec (CommandImpl& command) const
|
||||
{
|
||||
UNIMPLEMENTED ("actually invoke a command, according to this pattern");
|
||||
}
|
||||
|
||||
void
|
||||
revert(CommandImpl& command) const
|
||||
undo (CommandImpl& command) const
|
||||
{
|
||||
UNIMPLEMENTED ("actually undo the effect of a command, according to this pattern");
|
||||
}
|
||||
|
|
@ -128,16 +177,16 @@ namespace control {
|
|||
* @todo describe this pattern in more detail....
|
||||
*/
|
||||
class InvokeAsync
|
||||
: public HandlingPattern
|
||||
: public BasicHandlingPattern
|
||||
{
|
||||
void
|
||||
perform (CommandImpl& command) const
|
||||
exec (CommandImpl& command) const
|
||||
{
|
||||
UNIMPLEMENTED ("actually invoke a command, according to this pattern");
|
||||
}
|
||||
|
||||
void
|
||||
revert(CommandImpl& command) const
|
||||
undo (CommandImpl& command) const
|
||||
{
|
||||
UNIMPLEMENTED ("actually undo the effect of a command, according to this pattern");
|
||||
}
|
||||
|
|
@ -151,37 +200,6 @@ namespace control {
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Handling Pattern: invoke command directly and without any integration
|
||||
* with other facilities. This pattern is intended to be used for unit tests.
|
||||
*/
|
||||
class InvokeDirectly
|
||||
: public HandlingPattern
|
||||
{
|
||||
void
|
||||
perform (CommandImpl& command) const
|
||||
{
|
||||
REQUIRE (command.canExec());
|
||||
command.invokeCapture();
|
||||
command.invokeOperation();
|
||||
}
|
||||
|
||||
void
|
||||
revert(CommandImpl& command) const
|
||||
{
|
||||
REQUIRE (command.canUndo());
|
||||
command.invokeUndo();
|
||||
}
|
||||
|
||||
bool
|
||||
isValid() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -189,12 +207,13 @@ namespace control {
|
|||
|
||||
typedef lib::MultiFact<HandlingPattern, HandlingPattern::ID> HandlingPatternFactory;
|
||||
|
||||
/** Table of available command handling patterns */
|
||||
/** holds singleton pattern instances by ID */
|
||||
HandlingPatternFactory patternTable;
|
||||
|
||||
HandlingPatternFactory::Singleton<InvokeSyncNoThrow> holder1 (patternTable, HandlingPattern::SYNC);
|
||||
HandlingPatternFactory::Singleton<InvokeSyncThrow> holder2 (patternTable, HandlingPattern::SYNC_THROW);
|
||||
HandlingPatternFactory::Singleton<InvokeAsync> holder3 (patternTable, HandlingPattern::ASYNC);
|
||||
HandlingPatternFactory::Singleton<InvokeSyncNoThrow> holder1 (patternTable, HandlingPattern::SYNC);
|
||||
HandlingPatternFactory::Singleton<InvokeSyncThrow> holder2 (patternTable, HandlingPattern::SYNC_THROW);
|
||||
HandlingPatternFactory::Singleton<InvokeAsync> holder3 (patternTable, HandlingPattern::ASYNC);
|
||||
HandlingPatternFactory::Singleton<BasicHandlingPattern> holder4 (patternTable, HandlingPattern::DUMMY);
|
||||
|
||||
|
||||
/** access the singleton instance for a given ID */
|
||||
|
|
|
|||
Loading…
Reference in a new issue