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:
Fischlurch 2009-10-01 13:29:53 +02:00
parent effbb49afb
commit 248b87f344
3 changed files with 102 additions and 92 deletions

View file

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

View file

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

View file

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