From edcf503da13ca512b234b1fd612966be438783ff Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 13 Jan 2017 01:10:05 +0100 Subject: [PATCH] Command-Framework: enable the use of immutable types as state memento --- src/lib/replaceable-item.hpp | 6 +++--- src/proc/control/memento-tie.hpp | 8 +++++--- tests/core/proc/control/command-argument-test.cpp | 14 ++++++++++++++ tests/core/proc/control/command-basic-test.cpp | 7 ++++--- .../proc/control/command-message-binding-test.cpp | 6 ++++-- .../proc/control/session-command-function-test.cpp | 4 ++-- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/lib/replaceable-item.hpp b/src/lib/replaceable-item.hpp index 683b92043..aab736266 100644 --- a/src/lib/replaceable-item.hpp +++ b/src/lib/replaceable-item.hpp @@ -55,8 +55,8 @@ */ -#ifndef LIB_REPLACABLE_ITEM_H -#define LIB_REPLACABLE_ITEM_H +#ifndef LIB_REPLACEABLE_ITEM_H +#define LIB_REPLACEABLE_ITEM_H #include "lib/error.hpp" #include "lib/null-value.hpp" @@ -237,4 +237,4 @@ namespace wrapper { }} // namespace lib::wrap -#endif /*LIB_REPLACABLE_ITEM_H*/ +#endif /*LIB_REPLACEABLE_ITEM_H*/ diff --git a/src/proc/control/memento-tie.hpp b/src/proc/control/memento-tie.hpp index 19ebe5aa5..d5ac10350 100644 --- a/src/proc/control/memento-tie.hpp +++ b/src/proc/control/memento-tie.hpp @@ -44,6 +44,7 @@ #include "lib/meta/maybe-compare.hpp" #include "lib/meta/function-closure.hpp" #include "proc/control/command-signature.hpp" +#include "lib/replaceable-item.hpp" #include "lib/functor-util.hpp" #include "lib/format-obj.hpp" #include "lib/util.hpp" @@ -60,6 +61,7 @@ namespace control { using lib::meta::func::bindLast; using lib::meta::func::chained; using lib::meta::equals_safeInvoke; + using lib::wrapper::ReplaceableItem; LUMIERA_ERROR_DECLARE (MISSING_MEMENTO); ///< Undo functor not yet usable, because no undo state has been captured @@ -80,7 +82,7 @@ namespace control { * to be provided with a reference to this stored memento value through an additional * parameter (which by convention is always the last argument of the undo function). * @warning take care of the MementoTie storage location, as the bound functions - * returned by #tieCaptureFunc and #tieUndoFunc refer to \c this internally. + * returned by #tieCaptureFunc and #tieUndoFunc refer to `this` implicitly. * * @param SIG signature of the command operation * @param MEM type of the memento state to capture. Needs to be default constructible and copyable @@ -94,7 +96,7 @@ namespace control { typedef typename CommandSignature::CaptureSig SIG_cap; typedef typename CommandSignature::UndoOp_Sig SIG_undo; - MEM memento_; ///< storage holding the captured state for undo + ReplaceableItem memento_; ///< storage holding the captured state for undo bool isCaptured_; @@ -214,7 +216,7 @@ namespace control { return ""; return ""; } diff --git a/tests/core/proc/control/command-argument-test.cpp b/tests/core/proc/control/command-argument-test.cpp index 91031f296..2421067ef 100644 --- a/tests/core/proc/control/command-argument-test.cpp +++ b/tests/core/proc/control/command-argument-test.cpp @@ -98,6 +98,19 @@ namespace test { template int Tracker::instanceCnt (0); + /** prepare a (singleton) _empty value_ for the memento. + * @remarks This is done prior to observing the Tracker instanceCnt, + * because this empty value obviously remains allocated forever. + * The memento is stored within a [special holder](\ref lib::ReplaceableItem) + * to allow capturing memento state even from immutable values, which only can + * be copy constructed. This mechanism uses lib::NullValue to retrieve an + * empty placeholder value when the memento has not yet been captured. + */ + void + prepareEmptyMemento() + { + lib::NullValue>::get(); + } /** Dummy custom memento datatype * @note memento needs to be equality comparable @@ -191,6 +204,7 @@ namespace test { run (Arg) { ArgTuples testTuples; + prepareEmptyMemento(); Tracker::instanceCnt = 0; Tracker::instanceCnt = 0; diff --git a/tests/core/proc/control/command-basic-test.cpp b/tests/core/proc/control/command-basic-test.cpp index 32426694b..49054e798 100644 --- a/tests/core/proc/control/command-basic-test.cpp +++ b/tests/core/proc/control/command-basic-test.cpp @@ -40,6 +40,7 @@ namespace test { using lib::time::Time; using lib::time::TimeVar; using lib::time::TimeValue; + using lib::time::Offset; @@ -53,14 +54,14 @@ namespace test { *dummyObj += TimeValue(randVal); } - TimeVar + Offset capture (P dummyObj, int) { - return *dummyObj; + return Offset{*dummyObj}; } void - undoIt (P dummyObj, int, TimeVar oldVal) + undoIt (P dummyObj, int, Offset oldVal) { *dummyObj = oldVal; } diff --git a/tests/core/proc/control/command-message-binding-test.cpp b/tests/core/proc/control/command-message-binding-test.cpp index e763d5c90..a694fe424 100644 --- a/tests/core/proc/control/command-message-binding-test.cpp +++ b/tests/core/proc/control/command-message-binding-test.cpp @@ -54,14 +54,14 @@ namespace test { implicitTestState += dur; } - TimeVar + Time capture (Duration) { return implicitTestState; } void - undoIt (Duration, TimeVar oldVal) + undoIt (Duration, Time oldVal) { implicitTestState = oldVal; } @@ -81,6 +81,8 @@ namespace test { * - we support immutable argument types, which means the command binding * machinery works without (re)assignment, only copy construction of * argument holders into an inline buffer. + * - likewise we support to use an immutable type as captured state + * memento, which is demonstrated by capturing a Time value * * @see BusTerm_test * @see TupleRecordInit_test diff --git a/tests/core/proc/control/session-command-function-test.cpp b/tests/core/proc/control/session-command-function-test.cpp index ce6a94cc4..e7f56f8ef 100644 --- a/tests/core/proc/control/session-command-function-test.cpp +++ b/tests/core/proc/control/session-command-function-test.cpp @@ -77,14 +77,14 @@ namespace test { testCommandState += Offset(dur) + offset*factor; } - string + Time capture (Duration, Offset, int) { return testCommandState; } void - undoIt (Duration, Offset, int, string oldState) + undoIt (Duration, Offset, int, Time oldState) { // dummyState = oldState; }