From 3922bb58e18373e97fa0ee90f7feecd4d6c1eea3 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 16 Apr 2017 20:12:01 +0200 Subject: [PATCH] Commands: fix and adapt instance management test --- src/proc/control/command-queue.hpp | 2 +- src/proc/control/command-setup.cpp | 12 +++++++----- .../control/command-instance-manager-test.cpp | 16 ++++++++++++++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/proc/control/command-queue.hpp b/src/proc/control/command-queue.hpp index ec29bfbe2..a74fbe266 100644 --- a/src/proc/control/command-queue.hpp +++ b/src/proc/control/command-queue.hpp @@ -79,7 +79,7 @@ namespace control { % cmd.getID() % cmd , LUMIERA_ERROR_UNBOUND_ARGUMENTS); - lib::IterQueue::feed(cmd); + lib::IterQueue::feed (move (cmd)); return *this; } diff --git a/src/proc/control/command-setup.cpp b/src/proc/control/command-setup.cpp index 520c23be3..62c7cfbce 100644 --- a/src/proc/control/command-setup.cpp +++ b/src/proc/control/command-setup.cpp @@ -237,6 +237,10 @@ namespace control { "nor to an previously opened command instance") % instanceID , LUMIERA_ERROR_INVALID_COMMAND); + if (not entry->second.isValid()) + throw error::Logic (_Fmt{"Command instance '%s' is not (yet/anymore) active"} + % instanceID + , error::LUMIERA_ERROR_LIFECYCLE); instance = move(entry->second); } ENSURE (instance); @@ -248,11 +252,6 @@ namespace control { void CommandInstanceManager::handOver (Command&& toDispatch, Symbol cmdID) { - if (not toDispatch) - throw error::Logic (_Fmt{"attempt to dispatch command instance '%s' " - "without creating a new instance from prototype beforehand"} - % cmdID - , error::LUMIERA_ERROR_LIFECYCLE); if (not toDispatch.canExec()) throw error::State (_Fmt{"attempt to dispatch command instance '%s' " "without binding all arguments properly beforehand"} @@ -272,6 +271,9 @@ namespace control { * instance manager). In this case, the instance will really be _moved_ over into * the dispatcher, which also means this instance is no longer "open" for * parametrisation. + * @throw error::Logic when the command's arguments aren't bound + * @warning invoking #dispatch() on an unbound local instance has the nasty + * side-effect of invalidating the instance. Just don't do that! */ void CommandInstanceManager::dispatch (Symbol instanceID) diff --git a/tests/core/proc/control/command-instance-manager-test.cpp b/tests/core/proc/control/command-instance-manager-test.cpp index 193c0c8d4..74db8497d 100644 --- a/tests/core/proc/control/command-instance-manager-test.cpp +++ b/tests/core/proc/control/command-instance-manager-test.cpp @@ -164,6 +164,9 @@ namespace test { CHECK (command1::check_ == 0); // nothing invoked yet fixture.invokeAll(); CHECK (command1::check_ == r1 + r2); // both instances were invoked with their specific arguments + + // clean-up: we have bound arguments on the global prototype + com.unbind(); } @@ -356,12 +359,18 @@ namespace test { CHECK (i2 == instanceID); CHECK (iManager.getInstance (instanceID)); + VERIFY_ERROR (DUPLICATE_COMMAND, iManager.newInstance (COMMAND_PROTOTYPE, INVOCATION_ID)); + Command cmd = iManager.getInstance (instanceID); CHECK (cmd); CHECK (not cmd.canExec()); VERIFY_ERROR (UNBOUND_ARGUMENTS, iManager.dispatch (instanceID)); - VERIFY_ERROR (DUPLICATE_COMMAND, iManager.newInstance (COMMAND_PROTOTYPE, INVOCATION_ID)); + // NOTE: this error has killed the instance.... + VERIFY_ERROR (LIFECYCLE, iManager.getInstance (instanceID)) + // ... we need to re-open it to repair the situation + iManager.newInstance (COMMAND_PROTOTYPE, INVOCATION_ID); + cmd = iManager.getInstance (instanceID); cmd.bind(23); CHECK (cmd.canExec()); @@ -395,11 +404,14 @@ namespace test { CHECK (not fixture.contains(cmd)); iManager.dispatch (COMMAND_PROTOTYPE); - CHECK (not fixture.contains(cmd)); // because a clone copy was dispatched + CHECK (fixture.contains(cmd)); // an equivalent clone was enqueued command1::check_ = 0; fixture.invokeAll(); CHECK (command1::check_ == -12); // the clone copy was executed + + // clean-up: we have bound arguments on the global prototype + cmd.unbind(); } };