diff --git a/src/proc/control/command-impl.hpp b/src/proc/control/command-impl.hpp index bb580693f..a3551dd90 100644 --- a/src/proc/control/command-impl.hpp +++ b/src/proc/control/command-impl.hpp @@ -132,13 +132,13 @@ namespace control { setArguments (Arguments& args) { pClo_->bindArguments(args); - - TODO ("this will break when re-binding to new arguments"); - - do_ .close(*pClo_); - undo_.close(*pClo_); } + void invokeOperation() { do_(*pClo_); } + void invokeCapture() { undo_.captureState(*pClo_); } + void invokeUndo() { undo_(*pClo_); } + + typedef HandlingPattern::ID PattID; diff --git a/src/proc/control/command.cpp b/src/proc/control/command.cpp index ec3303063..1c294131d 100644 --- a/src/proc/control/command.cpp +++ b/src/proc/control/command.cpp @@ -271,14 +271,15 @@ namespace control { ExecResult Command::exec (HandlingPattern const& execPattern) { - return execPattern (*this); + CommandImpl& thisCommand (_Handle::impl()); + return execPattern.invoke (thisCommand, cStr(*this)); } ExecResult Command::exec (HandlingPattern::ID pattID) { - return HandlingPattern::get(pattID) (*this); + return exec (HandlingPattern::get(pattID)); } diff --git a/src/proc/control/command.hpp b/src/proc/control/command.hpp index 18f4ca36e..ba45edf44 100644 --- a/src/proc/control/command.hpp +++ b/src/proc/control/command.hpp @@ -132,6 +132,7 @@ namespace control { ExecResult exec (HandlingPattern const& execPattern); ExecResult exec (HandlingPattern::ID); + /** invoke using a default "synchronous" execution pattern */ ExecResult execSync (); /** @return ID of the execution pattern used by operator() */ diff --git a/src/proc/control/handling-pattern.cpp b/src/proc/control/handling-pattern.cpp index 8d02128e7..d48f39d30 100644 --- a/src/proc/control/handling-pattern.cpp +++ b/src/proc/control/handling-pattern.cpp @@ -22,7 +22,6 @@ -#include "proc/control/command.hpp" #include "proc/control/handling-pattern.hpp" #include "proc/control/handling-patterns.hpp" @@ -58,9 +57,9 @@ namespace control { /** @note: does error handling, but delegates the actual * execution to the protected (subclass) member */ ExecResult - HandlingPattern::operator() (Command& command) const + HandlingPattern::invoke (CommandImpl& command, Symbol name) const { - TRACE (proc_dbg, "invoking %s...", cStr(command)); + TRACE (proc_dbg, "invoking %s...", name); 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."); @@ -84,21 +83,21 @@ namespace control { catch (lumiera::Error& problem) { Symbol errID = lumiera_error(); - WARN (command, "Invocation of %s failed: %s", cStr(command), problem.what()); + WARN (command, "Invocation of %s failed: %s", name, 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()); + WARN (command, "Invocation of %s failed: %s", name, 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); + ERROR (command, "Invocation of %s failed with unknown exception; error flag is: %s", name, errID); throw error::Fatal (str (err_fatal % command), errID); } } @@ -115,7 +114,7 @@ namespace control { /* ====== execution result state object ======= */ - /** @note we just grab an retain the error message. + /** @note we just grab and retain the error message. * @todo rather keep the exception object around. */ ExecResult::ExecResult (lumiera::Error const& problem) : log_(problem.what()) diff --git a/src/proc/control/handling-pattern.hpp b/src/proc/control/handling-pattern.hpp index 09fad5b65..c52b26075 100644 --- a/src/proc/control/handling-pattern.hpp +++ b/src/proc/control/handling-pattern.hpp @@ -22,7 +22,17 @@ /** @file handling-pattern.hpp - ** //TODO + ** Pre-defined command execution templates. + ** 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 + ** invoked (template method pattern). A pattern may cause the command to be + ** enqueued, registered for UNDO or dispatched into a background thread. + ** To carry out the work, HandlingPattern implementations are allowed to + ** invoke the CommandImpl API directly. + ** + ** @todo it is not clear what's the difference between "throw" and "no-throw" pattern + ** @todo any integration with the (yet undefined as of 9/09) ProcDispatcher is missing. ** ** @see ProcDispatcher ** @see Session @@ -37,7 +47,7 @@ //#include "pre.hpp" #include "lib/error.hpp" #include "lib/bool-checkable.hpp" -//#include "include/symbol.hpp" +#include "include/symbol.hpp" //#include #include @@ -47,11 +57,11 @@ namespace control { using std::string; -// using lumiera::Symbol; + using lumiera::Symbol; // using std::tr1::shared_ptr; - class Command; + class CommandImpl; /** @@ -101,7 +111,7 @@ namespace control { /** 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; + ExecResult invoke (CommandImpl& command, Symbol name) const; /** @return HandlingPatter describing how the UNDO operation is to be performed */ HandlingPattern const& howtoUNDO() const; @@ -111,7 +121,7 @@ namespace control { protected: - virtual void perform (Command& command) const =0; + virtual void perform (CommandImpl& command) const =0; virtual HandlingPattern const& defineUNDO() const =0; diff --git a/src/proc/control/handling-patterns.hpp b/src/proc/control/handling-patterns.hpp index 4892504af..b3e56f36c 100644 --- a/src/proc/control/handling-patterns.hpp +++ b/src/proc/control/handling-patterns.hpp @@ -1,5 +1,5 @@ /* - HANDLILNG-PATTERNS.hpp - Collection of predefinded command handling patterns + HANDLILNG-PATTERNS.hpp - Collection of predefined command handling patterns Copyright (C) Lumiera.org 2009, Hermann Vosseler @@ -26,7 +26,7 @@ ** There is a small number of different possibilities to handle execution ** and UNDO of proc-Layer commands. Each of these is defined as a subclass ** in this header and then hard wired into a small table. Handling patterns - ** are stateless singleton objects, thus we build use SingletonSubclass + ** are stateless singleton objects, thus we build using SingletonSubclass ** factory objects and configure them hard wired with the respective ** implementation classes. The index positions in this table match ** the sequence within the enum HandlingPattern::ID; all of this @@ -46,6 +46,7 @@ #include "lib/error.hpp" #include "lib/singleton-subclass.hpp" #include "proc/control/handling-pattern.hpp" +#include "proc/control/command-impl.hpp" #include "proc/mobject/session.hpp" #include "include/lifecycle.h" //#include "include/symbol.hpp" @@ -75,7 +76,7 @@ namespace control { : public HandlingPattern { void - perform (Command& command) const + perform (CommandImpl& command) const { UNIMPLEMENTED ("actually invoke a command, according to this pattern"); } @@ -103,7 +104,7 @@ namespace control { : public HandlingPattern { void - perform (Command& command) const + perform (CommandImpl& command) const { UNIMPLEMENTED ("actually invoke a command, according to this pattern"); } @@ -131,7 +132,7 @@ namespace control { : public HandlingPattern { void - perform (Command& command) const + perform (CommandImpl& command) const { UNIMPLEMENTED ("actually invoke a command, according to this pattern"); } @@ -180,9 +181,9 @@ namespace control { { using lumiera::singleton::UseSubclass; - patternTable[HandlingPattern::SYNC] = SingletonFac(UseSubclass()); + patternTable[HandlingPattern::SYNC ] = SingletonFac(UseSubclass()); patternTable[HandlingPattern::SYNC_THROW] = SingletonFac(UseSubclass()); - patternTable[HandlingPattern::ASYNC] = SingletonFac(UseSubclass()); + patternTable[HandlingPattern::ASYNC ] = SingletonFac(UseSubclass()); }