WIP: implement the basic operation of execution pattern
This commit is contained in:
parent
f2126c0764
commit
4236d0649a
10 changed files with 509 additions and 354 deletions
File diff suppressed because it is too large
Load diff
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 123 KiB |
|
|
@ -50,7 +50,7 @@ namespace lumiera {
|
|||
{
|
||||
public:
|
||||
Error (string description="", const char* id=LUMIERA_ERROR_EXCEPTION) throw();
|
||||
Error (std::exception& cause,
|
||||
Error (std::exception const& cause,
|
||||
string description="", const char* id=LUMIERA_ERROR_EXCEPTION) throw();
|
||||
|
||||
Error (const Error&) throw();
|
||||
|
|
@ -87,7 +87,7 @@ namespace lumiera {
|
|||
mutable string what_; ///< buffer for generating the detailed description on demand
|
||||
const string cause_; ///< description of first exception encountered in the chain
|
||||
|
||||
static const string extractCauseMsg (const std::exception&) throw();
|
||||
static const string extractCauseMsg (std::exception const&) throw();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ namespace lumiera {
|
|||
}
|
||||
|
||||
|
||||
Error::Error (std::exception& cause,
|
||||
Error::Error (std::exception const& cause,
|
||||
string description, const char* id) throw()
|
||||
: std::exception (),
|
||||
id_ (error::default_or_given (id)),
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "lib/meta/function-closure.hpp"
|
||||
#include "lib/meta/function-erasure.hpp"
|
||||
#include "lib/meta/tuple.hpp"
|
||||
#include "lib/format.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
|
|
@ -133,7 +134,7 @@ namespace control {
|
|||
ostream&
|
||||
dump (ostream& output) const
|
||||
{
|
||||
return BASE::dump (output << element() << ',');
|
||||
return BASE::dump (output << util::str (element()) << ',');
|
||||
}
|
||||
|
||||
friend bool
|
||||
|
|
|
|||
|
|
@ -224,14 +224,23 @@ namespace control {
|
|||
void
|
||||
Command::undo ()
|
||||
{
|
||||
exec (getDefaultHandlingPattern().howtoUNDO());
|
||||
HandlingPattern const& defaultPattern
|
||||
= HandlingPattern::get (getDefaultHandlingPattern());
|
||||
exec (defaultPattern.howtoUNDO());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Command::exec (HandlingPattern const& execPattern)
|
||||
{
|
||||
execPattern.invoke (*this);
|
||||
execPattern (*this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Command::exec (HandlingPattern::ID pattID)
|
||||
{
|
||||
HandlingPattern::get(pattID) (*this);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -242,13 +251,20 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
HandlingPattern const&
|
||||
HandlingPattern::ID
|
||||
Command::getDefaultHandlingPattern() const
|
||||
{
|
||||
UNIMPLEMENTED ("manage the default command handling pattern");
|
||||
}
|
||||
|
||||
|
||||
HandlingPattern::ID
|
||||
Command::setHandlingPattern (HandlingPattern::ID pattID)
|
||||
{
|
||||
UNIMPLEMENTED ("manage handling patterns in general");
|
||||
}
|
||||
|
||||
|
||||
template<typename TYPES>
|
||||
void
|
||||
Command::bindArg (Tuple<TYPES> const& args)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "proc/control/command-binding.hpp"
|
||||
#include "proc/control/command-mutation.hpp"
|
||||
#include "proc/control/command-closure.hpp"
|
||||
#include "proc/control/handling-pattern.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/handle.hpp"
|
||||
|
||||
|
|
@ -64,7 +65,6 @@ namespace control {
|
|||
|
||||
class CommandDef;
|
||||
class CommandImpl;
|
||||
class HandlingPattern;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -97,10 +97,16 @@ namespace control {
|
|||
* necessary to get this command invoked properly
|
||||
*/
|
||||
void exec (HandlingPattern const& execPattern);
|
||||
void exec (HandlingPattern::ID);
|
||||
|
||||
void execSync ();
|
||||
|
||||
HandlingPattern const& getDefaultHandlingPattern() const;
|
||||
/** @return ID of the execution pattern used by operator() */
|
||||
HandlingPattern::ID getDefaultHandlingPattern() const;
|
||||
|
||||
/** define a handling pattern to be used by default
|
||||
* @return ID of the currently defined default pattern */
|
||||
HandlingPattern::ID setHandlingPattern (HandlingPattern::ID);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,12 +23,24 @@
|
|||
|
||||
|
||||
#include "proc/control/handling-pattern.hpp"
|
||||
#include "proc/control/command.hpp"
|
||||
|
||||
#include "include/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>
|
||||
//using boost::str;
|
||||
#include <boost/format.hpp>
|
||||
|
||||
|
||||
using boost::str;
|
||||
using boost::format;
|
||||
using namespace lumiera;
|
||||
using util::cStr;
|
||||
using util::isnil;
|
||||
|
||||
|
||||
namespace control {
|
||||
|
||||
|
|
@ -39,8 +51,87 @@ namespace control {
|
|||
UNIMPLEMENTED ("Factory for handling patterns");
|
||||
}
|
||||
|
||||
|
||||
/** @note: does error handling, but delegates the actual
|
||||
* execution to the protected (subclass) member */
|
||||
ExecResult
|
||||
HandlingPattern::operator() (Command& command) const
|
||||
{
|
||||
TRACE (proc_dbg, "invoking %s...", cStr(command));
|
||||
static format err_pre ("Error state detected, %s *NOT* invoked.");
|
||||
static format err_post ("Error state after %s invocation.");
|
||||
static format err_fatal ("Execution of %s raised unknown error.");
|
||||
try
|
||||
{
|
||||
Symbol errID_pre = lumiera_error();
|
||||
if (errID_pre)
|
||||
return ExecResult (error::Logic (str (err_pre % command), errID_pre));
|
||||
|
||||
// Execute the command
|
||||
perform (command);
|
||||
|
||||
Symbol errID = lumiera_error();
|
||||
if (errID)
|
||||
return ExecResult (error::State (str (err_post % command),errID));
|
||||
else
|
||||
return ExecResult();
|
||||
}
|
||||
|
||||
|
||||
catch (lumiera::Error& problem)
|
||||
{
|
||||
Symbol errID = lumiera_error();
|
||||
WARN (command, "Invocation of %s failed: %s", cStr(command), problem.what());
|
||||
TRACE (proc_dbg, "Error flag was: %s", errID);
|
||||
return ExecResult (problem);
|
||||
}
|
||||
catch (std::exception& library_problem)
|
||||
{
|
||||
Symbol errID = lumiera_error();
|
||||
WARN (command, "Invocation of %s failed: %s", cStr(command), library_problem.what());
|
||||
TRACE (proc_dbg, "Error flag was: %s", errID);
|
||||
return ExecResult (error::External (library_problem));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
Symbol errID = lumiera_error();
|
||||
ERROR (command, "Invocation of %s failed with unknown exception; error flag is: %s", cStr(command), errID);
|
||||
throw error::Fatal (str (err_fatal % command), errID);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////TODO: is this implementation file actually required??
|
||||
|
||||
HandlingPattern const&
|
||||
HandlingPattern::howtoUNDO() const
|
||||
{
|
||||
return defineUNDO();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ====== execution result state object ======= */
|
||||
|
||||
|
||||
/** @note we just grab an retain the error message.
|
||||
* @todo rather keep the exception object around. */
|
||||
ExecResult::ExecResult (lumiera::Error const& problem)
|
||||
: log_(problem.what())
|
||||
{ }
|
||||
|
||||
|
||||
bool
|
||||
ExecResult::isValid() const
|
||||
{
|
||||
return isnil(log_);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ExecResult::maybeThrow() const
|
||||
{
|
||||
if (!isnil (log_))
|
||||
throw error::Logic ("Command execution failed: "+log_);
|
||||
}
|
||||
|
||||
|
||||
} // namespace control
|
||||
|
|
|
|||
|
|
@ -36,14 +36,17 @@
|
|||
|
||||
//#include "pre.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
//#include "include/symbol.hpp"
|
||||
|
||||
//#include <tr1/memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
namespace control {
|
||||
|
||||
using std::string;
|
||||
// using lumiera::Symbol;
|
||||
// using std::tr1::shared_ptr;
|
||||
|
||||
|
|
@ -51,6 +54,25 @@ namespace control {
|
|||
class Command;
|
||||
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
*/
|
||||
class ExecResult
|
||||
: public lib::BoolCheckable<ExecResult>
|
||||
{
|
||||
const string log_;
|
||||
|
||||
public:
|
||||
bool isValid() const;
|
||||
void maybeThrow() const;
|
||||
|
||||
protected:
|
||||
ExecResult () { } ///< default: command executed successfully
|
||||
ExecResult (lumiera::Error const&); ///< this result marks a failed execution
|
||||
|
||||
friend class HandlingPattern;
|
||||
};
|
||||
|
||||
/**
|
||||
* @todo Type-comment
|
||||
*/
|
||||
|
|
@ -70,9 +92,22 @@ namespace control {
|
|||
|
||||
virtual ~HandlingPattern() {}
|
||||
|
||||
virtual void invoke (Command& command) const =0;
|
||||
/** main functionality: invoke a command, detect errors.
|
||||
* @return ExecResult object, which might later be used to
|
||||
* detect errors on execution */
|
||||
ExecResult operator() (Command& command) const;
|
||||
|
||||
/** @return HandlingPatter describing how the UNDO operation is to be performed */
|
||||
HandlingPattern const& howtoUNDO() const;
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void perform (Command& command) const =0;
|
||||
|
||||
virtual HandlingPattern const& defineUNDO() const =0;
|
||||
|
||||
virtual HandlingPattern const& howtoUNDO() const =0;
|
||||
|
||||
};
|
||||
////////////////TODO currently just fleshing out the API....
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
|
||||
#include <nobug.h>
|
||||
#define LUMIERA_LOGGING_CXX
|
||||
#include "include/logging.h"
|
||||
//#include "include/nobugcfg.h"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
|
|
@ -23,6 +25,7 @@
|
|||
//#include <typeinfo>
|
||||
#include <boost/format.hpp>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
using std::rand;
|
||||
|
|
@ -73,6 +76,8 @@ main (int, char**) //(int argc, char* argv[])
|
|||
}
|
||||
cout << "size=" << sizeof(TestIt1) <<"\n";
|
||||
|
||||
char* horror = 0;
|
||||
ERROR (all, "note: %s is a horrible thing", horror);
|
||||
|
||||
cout << "\n.gulp.\n";
|
||||
|
||||
|
|
|
|||
|
|
@ -196,7 +196,9 @@ namespace test {
|
|||
|
||||
blowUp_ = true;
|
||||
string current = command2::check_.str();
|
||||
VERIFY_ERROR( EXTERNAL, com.exec(HandlingPattern::get(SYNC_THROW)) );
|
||||
HandlingPattern const& doThrow = HandlingPattern::get(HandlingPattern::SYNC_THROW);
|
||||
|
||||
VERIFY_ERROR( EXTERNAL, com.exec (doThrow) );
|
||||
ASSERT (command2::check_.str() == current);
|
||||
|
||||
// we can achieve the same effect,
|
||||
|
|
|
|||
Loading…
Reference in a new issue