diff --git a/src/proc/control/command-impl.hpp b/src/proc/control/command-impl.hpp index 403c93317..f796c248a 100644 --- a/src/proc/control/command-impl.hpp +++ b/src/proc/control/command-impl.hpp @@ -120,20 +120,16 @@ 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: + /** @internal 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 */ + * to where the exact type info is still available; thus, + * a CommandImplCloneBuilder is first passed as a visitor + * down and then calls back to perform the copy, providing + * an new (clone) closure and UNDO functor already correctly + * wired to collaborate. + * @see #prepareClone */ CommandImpl (CommandImpl const& orig ,UndoMutation const& newUndo ,shared_ptr const& newClosure) @@ -161,6 +157,8 @@ namespace control { } + public: /* === implementation of command functionality === */ + void setArguments (Arguments& args) { diff --git a/src/proc/control/command-registry.hpp b/src/proc/control/command-registry.hpp index 6b0b55679..603aa5d9e 100644 --- a/src/proc/control/command-registry.hpp +++ b/src/proc/control/command-registry.hpp @@ -255,13 +255,15 @@ namespace control { * type information is vital for determining the exact allocation size for * the clone ArgumentHolder. The only solution is to delegate the cloning * of the arguments down into the ArgumentHolder, passing a reference - * to the memory manager for allocating the clone. + * to the memory manager for allocating the clone. Actually, we perform + * this operation through the help of a visitor, which re-gains the + * complete type context and prepares the necessary clone objects; + * in a final step, we allocate a new CommandImpl frame and + * initialise it with the prepared clone objects. + * @see command.cpp (implementation) */ shared_ptr - createCloneImpl (CommandImpl const& refObject) - { - return allocator_.create (refObject, allocator_); - } + createCloneImpl (CommandImpl const& refObject); }; diff --git a/src/proc/control/command.cpp b/src/proc/control/command.cpp index 4313ec0c6..a7f44c9b7 100644 --- a/src/proc/control/command.cpp +++ b/src/proc/control/command.cpp @@ -46,6 +46,7 @@ #include "proc/control/command-def.hpp" #include "proc/control/command-impl.hpp" #include "proc/control/command-registry.hpp" +#include "proc/control/command-impl-clone-builder.hpp" #include "proc/control/handling-pattern.hpp" #include @@ -170,6 +171,22 @@ namespace control { } + /** @note this bit of implementation from CommandRegistry rather + * heavily relies on implementation details from CommandImpl and + * the help of CommandImplCloneBuilder and ArgumentHolder. It's + * implemented within command.cpp to keep the includes of + * the handling patterns clean. */ + shared_ptr + CommandRegistry::createCloneImpl (CommandImpl const& refObject) + { + CommandImplCloneBuilder cloneBuilder(allocator_); + refObject.prepareClone(cloneBuilder); + return allocator_.create (refObject, cloneBuilder.clonedUndoMutation() + , cloneBuilder.clonedClosuere()); + } + + + void Command::duplicate_detected (Symbol newCmdID) const { diff --git a/tests/components/proc/control/command-clone-builder-test.cpp b/tests/components/proc/control/command-clone-builder-test.cpp index 79ef9f069..035af61ff 100644 --- a/tests/components/proc/control/command-clone-builder-test.cpp +++ b/tests/components/proc/control/command-clone-builder-test.cpp @@ -22,11 +22,8 @@ #include "lib/test/run.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-registry.hpp" #include "proc/control/argument-erasure.hpp" #include "proc/control/handling-pattern.hpp" #include "lib/meta/tuple.hpp" @@ -36,25 +33,22 @@ #include "proc/control/test-dummy-commands.hpp" -//#include - namespace control { namespace test { - -// using std::tr1::function; -// using util::isSameObject; -// using lib::Symbol; using namespace lumiera::typelist; + typedef lumiera::P PCmdImpl; - namespace { // test data and helpers... - + + namespace { // test config... HandlingPattern::ID TEST_HANDLING_PATTERN = HandlingPattern::DUMMY; } - typedef lumiera::P PCmdImpl; + + + /******************************************************************************** @@ -62,7 +56,7 @@ namespace test { * without disclosing specific type information about the involved closure. * This includes verifying sane allocation management. * @note this test covers a very specific low-level perspective, but on an - * integration level, including TypedAllocationManager, CommandRegistry, + * integration level, involving TypedAllocationManager, CommandRegistry, * CommandImpl, CmdClosure, ArgumentHolder, UndoMutation, MementoTie. * Closes: Ticket #298 * @@ -79,24 +73,16 @@ namespace test { run (Arg) { CommandRegistry& registry = CommandRegistry::instance(); - TypedAllocationManager allo; /////////////////////////////////////////////TODO ASSERT (®istry); uint cnt_inst = registry.instance_count(); { PCmdImpl source = buildTestImplFrame (registry); -////////////////////////////////////////////////////////////////////////////////////TODO -// PCmdImpl clone = registry.createCloneImpl (*source); - CommandImplCloneBuilder cloneBuilder(allo); - source->prepareClone(cloneBuilder); - PCmdImpl clone = allo.create (*source, cloneBuilder.clonedUndoMutation() - , cloneBuilder.clonedClosuere()); -////////////////////////////////////////////////////////////////////////////////////TODO + PCmdImpl clone = registry.createCloneImpl (*source); verifySeparation (source, clone); } - ASSERT ( 0 == allo.numSlots()); /////////////////////////////TODO ASSERT (cnt_inst == registry.instance_count()); }