Command-Framework: enable the use of immutable types as state memento

This commit is contained in:
Fischlurch 2017-01-13 01:10:05 +01:00
parent c799c7644c
commit edcf503da1
6 changed files with 32 additions and 13 deletions

View file

@ -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*/

View file

@ -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<SIG,MEM>::CaptureSig SIG_cap;
typedef typename CommandSignature<SIG,MEM>::UndoOp_Sig SIG_undo;
MEM memento_; ///< storage holding the captured state for undo
ReplaceableItem<MEM> memento_; ///< storage holding the captured state for undo
bool isCaptured_;
@ -214,7 +216,7 @@ namespace control {
return "<mem:missing>";
return "<mem: "
+ util::toString (memento_)
+ util::toString (memento_.get())
+ ">";
}

View file

@ -98,6 +98,19 @@ namespace test {
template<typename TY>
int Tracker<TY>::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<Tracker<string>>::get();
}
/** Dummy custom memento datatype
* @note memento needs to be equality comparable
@ -191,6 +204,7 @@ namespace test {
run (Arg)
{
ArgTuples testTuples;
prepareEmptyMemento();
Tracker<TimeVar>::instanceCnt = 0;
Tracker<string>::instanceCnt = 0;

View file

@ -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<TimeVar> dummyObj, int)
{
return *dummyObj;
return Offset{*dummyObj};
}
void
undoIt (P<TimeVar> dummyObj, int, TimeVar oldVal)
undoIt (P<TimeVar> dummyObj, int, Offset oldVal)
{
*dummyObj = oldVal;
}

View file

@ -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

View file

@ -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;
}