diff --git a/src/proc/control/command-impl-clone-builder.hpp b/src/proc/control/command-impl-clone-builder.hpp index 6d185db22..b00e59df4 100644 --- a/src/proc/control/command-impl-clone-builder.hpp +++ b/src/proc/control/command-impl-clone-builder.hpp @@ -78,13 +78,11 @@ namespace control { // : public lib::BoolCheckable + : public boost::noncopyable { - Mutation do_; - UndoMutation undo_; + TypedAllocationManager& allocator_; + shared_ptr newClo_; - shared_ptr pClo_; - - HandlingPattern::ID defaultPatt_; template @@ -101,115 +99,54 @@ namespace control { #define _TY(_ID_) typename _Type::_ID_ public: - /** build a new implementation frame, and do the initial wiring. - * On the interface the specific type is discarded afterwards. - * This information is still kept though, as encoded into the vtable - * of the embedded FunErasure objects holding the command operation - * and undo functors, and the vtable of the embedded CmdClosure */ - template - CommandImpl (shared_ptr pArgHolder - ,_TY (Func_op) const& operFunctor - ,_TY (Func_cap) const& captFunctor - ,_TY (Func_undo) const& undoFunctor - ) - : do_(operFunctor) - , undo_(pArgHolder->tie (undoFunctor, captFunctor)) - , pClo_(pArgHolder) - , defaultPatt_(HandlingPattern::defaultID()) + CommandImplCloneBuilder (TypedAllocationManager allo) + : allocator_(allo) + , newClo_() { } + + /** visit the CommandImpl given as reference + * to re-gain the contained Closure type context + */ + void + visit (CommandImpl const& sourceImpl) + { + UNIMPLEMENTED ("get access to source context"); + } + + + /** to be executed from within the specifically typed context + * of a concrete command ArgumentHolder; prepare the objects + * necessary to re-build a "clone" of the UNDO-Functor. + */ + template + void + buildCloneContext (shared_ptr pArgHolder) + { + UNIMPLEMENTED ("how to reflect context back"); + newClo_ = pArgHolder; + } + #undef _TY - ~CommandImpl(); - - - /** cloning service for the CommandRegistry: - * effectively this is a copy ctor, but as we rely - * on a argument holder (without knowing the exact type), - * we need to delegate the cloning of the arguments down - * while providing a means of allocating storage for the clone */ - CommandImpl (CommandImpl const& orig, TypedAllocationManager& storageManager) - : do_(orig.do_) - , undo_(orig.undo_) - , pClo_(orig.pClo_->createClone(storageManager)) - , defaultPatt_(orig.defaultPatt_) - { } - - - void - setArguments (Arguments& args) + /** after visitation: use pre-built bits to provide a cloned UndoFunctor */ + UndoMutation const& + clonedUndoMutation () { - pClo_->bindArguments(args); - } - - void invokeOperation() { do_(*pClo_); } - void invokeCapture() { undo_.captureState(*pClo_); } - void invokeUndo() { undo_(*pClo_); } - - - - typedef HandlingPattern::ID PattID; - - PattID - getDefaultHandlingPattern() const - { - return defaultPatt_; - } - - /** define a handling pattern to be used by default - * @return ID of the currently defined default pattern */ - PattID - setHandlingPattern (PattID newID) - { - PattID currID = defaultPatt_; - defaultPatt_ = newID; - return currID; + UNIMPLEMENTED (" getNewUndoMutation ()" ); } - - /* === diagnostics === */ - - bool - isValid() const ///< validity self-check: is basically usable. + /** after visitation: provide cloned ArgumentHolder, + * but already stripped down to the generic usage type */ + shared_ptr const& + clonedClosuere () { - return bool(pClo_) - && HandlingPattern::get(defaultPatt_).isValid(); + REQUIRE (newClo_); + return newClo_; } - bool - canExec() const ///< state check: sufficiently defined to be invoked - { - return isValid() - && pClo_->isValid(); - } - - bool - canUndo() const ///< state check: has undo state been captured? - { - return isValid() && pClo_->isCaptured(); - } - - - - friend bool - operator== (CommandImpl const& ci1, CommandImpl const& ci2) - { - return (ci1.do_ == ci2.do_) -// && (ci1.undo_ == ci2.undo_) // causes failure regularly, due to the missing equality on boost::function. See Ticket #294 - && (ci1.defaultPatt_ == ci2.defaultPatt_) - && (ci1.canExec() == ci2.canExec()) - && (ci1.canUndo() == ci2.canUndo()) - && (ci1.pClo_->equals(*ci2.pClo_)) - ; - } - - friend bool - operator!= (CommandImpl const& ci1, CommandImpl const& ci2) - { - return !(ci1==ci2); - } }; diff --git a/src/proc/control/command-impl.hpp b/src/proc/control/command-impl.hpp index 456cc4c28..dd148037e 100644 --- a/src/proc/control/command-impl.hpp +++ b/src/proc/control/command-impl.hpp @@ -120,15 +120,24 @@ namespace control { ~CommandImpl(); + /** TODO: kill kill kill */ + CommandImpl (CommandImpl const& orig, TypedAllocationManager& storageManager) + : do_(orig.do_) + , undo_(orig.undo_) + , pClo_(orig.pClo_->createClone(storageManager)) + , defaultPatt_(orig.defaultPatt_) + { } + + /** cloning service for the CommandRegistry: * effectively this is a copy ctor, but as we rely * on a argument holder (without knowing the exact type), * we need to delegate the cloning of the arguments down * while providing a means of allocating storage for the clone */ - CommandImpl (CommandImpl const& orig, TypedAllocationManager& storageManager) + CommandImpl (CommandImpl const& orig, UndoMutation const& newUndo, shared_ptr& newClosure) : do_(orig.do_) - , undo_(orig.undo_) - , pClo_(orig.pClo_->createClone(storageManager)) + , undo_(newUndo) + , pClo_(newClosure) , defaultPatt_(orig.defaultPatt_) { } diff --git a/tests/components/proc/control/command-clone-builder-test.cpp b/tests/components/proc/control/command-clone-builder-test.cpp index 15beceb0c..a2c9c2f6b 100644 --- a/tests/components/proc/control/command-clone-builder-test.cpp +++ b/tests/components/proc/control/command-clone-builder-test.cpp @@ -22,11 +22,11 @@ #include "lib/test/run.hpp" -#include "lib/test/test-helper.hpp" +//#include "lib/test/test-helper.hpp" //#include "proc/control/command-def.hpp" #include "proc/control/command-registry.hpp" #include "proc/control/command-impl.hpp" -//#include "proc/control/command-impl-clone-builder.hpp" +#include "proc/control/command-impl-clone-builder.hpp" #include "proc/control/argument-erasure.hpp" #include "proc/control/handling-pattern.hpp" #include "lib/meta/tuple.hpp" @@ -79,16 +79,24 @@ namespace test { run (Arg) { CommandRegistry& registry = CommandRegistry::instance(); + TypedAllocationManager allo; /////////////////////////////////////////////TODO ASSERT (®istry); uint cnt_inst = registry.instance_count(); { PCmdImpl source = buildTestImplFrame (registry); - PCmdImpl clone = registry.createCloneImpl (*source); +////////////////////////////////////////////////////////////////////////////////////TODO +// PCmdImpl clone = registry.createCloneImpl (*source); + CommandImplCloneBuilder cloneBuilder(allo); + cloneBuilder.visit (*source); + PCmdImpl clone = allo.create (*source, cloneBuilder.clonedUndoMutation() + , cloneBuilder.clonedClosuere()); +////////////////////////////////////////////////////////////////////////////////////TODO verifySeparation (source, clone); } + ASSERT ( 0 == allo.numSlots()); /////////////////////////////TODO ASSERT (cnt_inst == registry.instance_count()); } @@ -158,16 +166,16 @@ namespace test { ASSERT (!copy->canUndo()); testExec.invoke (*copy, "Execute clone"); // EXEC 2 ASSERT (command1::check_ != state_after_exec1); - ASSERT (copy->canUndo()); +// ASSERT (copy->canUndo()); ASSERT (copy != orig); // invoke UNDO on the clone - testUndo.invoke (*copy, "Undo clone"); // UNDO 2 - ASSERT (command1::check_ == state_after_exec1); +// testUndo.invoke (*copy, "Undo clone"); // UNDO 2 +// ASSERT (command1::check_ == state_after_exec1); // invoke UNDO on original testUndo.invoke (*orig, "Undo original"); // UNDO 1 - ASSERT (command1::check_ ==0); +// ASSERT (command1::check_ ==0); ASSERT (copy != orig); }