CmdAccess: replace existing usages of InvocationTrail

This commit is contained in:
Fischlurch 2017-04-17 16:57:09 +02:00
parent 876c1dd1fd
commit 8c7ac997de
9 changed files with 72 additions and 69 deletions

View file

@ -189,12 +189,19 @@ namespace model {
/**
* Perform a command or action, once the execution context has been established.
* After binding (and recording) the command arguments, as supplied with the
* After binding (and recording) the command arguments, as supplied with the
* [record](\ref lib::diff::Rec), the command action is executed right away.
* @param instance handle to a command instantiation, to be readied for invocation
* @param cmdID indicates the global command definition to be invoked
* @param arguments suitable tuple of values, to be used to outfit the prototype
* @remark may use a previously "opened" instanceID, instead of a global commandID
*/
void
Tangible::invoke (Symbol cmdID, Rec&& arguments)
{
uiBus_.act (GenNode{string{cmdID}, std::forward<Rec>(arguments)});
}
/** @deprecated */
void
Tangible::invoke (Cmd const& instance, Rec&& arguments)
{
uiBus_.act (instance.triggerMsg (std::forward<Rec>(arguments)));

View file

@ -135,6 +135,7 @@
#include "gui/interact/invocation-trail.hpp"
#include "lib/diff/diff-mutable.hpp"
#include "lib/idi/entry-id.hpp"
#include "lib/symbol.hpp"
#include <boost/noncopyable.hpp>
#include <sigc++/trackable.h>
@ -146,6 +147,7 @@ namespace gui {
namespace model {
using std::string;
using lib::Symbol;
/**
@ -188,6 +190,9 @@ namespace model {
void clearMsg();
void clearErr();
template<typename...ARGS>
void invoke (Symbol cmdID, ARGS&&...);
void invoke (Symbol cmdID, Rec&& arguments);
template<typename...ARGS>
void invoke (Cmd const& prototype, ARGS&&...);
void invoke (Cmd const& prototype, Rec&& arguments);
@ -235,6 +240,18 @@ namespace model {
/** convenience shortcut to issue a command with several arguments */
template<typename...ARGS>
inline void
Tangible::invoke (Symbol cmdID, ARGS&&... args)
{
using GenNodeIL = std::initializer_list<GenNode>;
invoke (cmdID,
Rec(Rec::TYPE_NIL_SYM
,GenNodeIL{}
,GenNodeIL {std::forward<ARGS> (args)...}));
} // not typed, no attributes, all arguments as children
/** @deprecated */
template<typename...ARGS>
inline void
Tangible::invoke (Cmd const& prototype, ARGS&&... args)
{
using GenNodeIL = std::initializer_list<GenNode>;

View file

@ -133,8 +133,8 @@ namespace ctrl {
* @note no information regarding the _origin_ of this command invocation
* is captured. If a command needs a _subject_, this has to be
* bound as an command argument beforehand.
* @see gui::interact::InvocationTrail
* @see gui::model::Tangible::issueCommand()
* @see proc::control::SessionCommand
*/
void
BusTerm::act (GenNode const& command)

View file

@ -12,7 +12,7 @@ return: 0
END
PLANNED "building block of the UI-Bus" BusTerm_test <<END
TEST "building block of the UI-Bus" BusTerm_test <<END
return: 0
END

View file

@ -101,7 +101,6 @@ namespace test {
using boost::lexical_cast;
using lib::test::randTime;
using gui::interact::InvocationTrail;
using proc::control::SessionCommand;
using lib::diff::GenNode;
using lib::diff::Rec;
@ -285,19 +284,16 @@ namespace test {
/** @test invoke a command in the same way as CoreService does
* when handling command messages from the UI-Bus
* - use the help of an InvocationTrail, similar to what the
* - build a command message, similar to what the
* [generic UI element](\ref gui::model::Tangible) does
* - generate an argument binding message
* - generate a "bang!" message
* - use the contents of this message at the SessionCommand
* facade, similar to what CoreService does
*/
void
perform_messageInvocation()
{
// this happens "somewhere" in the UI interaction control framework
InvocationTrail invoTrail{Command(COMMAND_I2)};
// this happens within some tangible UI element (widget / controller)
GenNode commandMsg = invoTrail.triggerMsg (Rec {Duration(25,10), Time(500,0), -2});
GenNode commandMsg{string(COMMAND_I2), Rec{Duration(25,10), Time(500,0), -2}};
CHECK (commandMsg.idi.getSym() == string{COMMAND_I2});
CHECK (not Command::canExec(COMMAND_I2));
Time prevState = testCommandState;
@ -364,10 +360,9 @@ namespace test {
for (uint j=0; j<NUM_INVOC_PER_THRED; ++j)
{
auto cmd = Command(COMMAND_ID).storeDef(cmdID(j));
InvocationTrail invoTrail{cmd};
__randomDelay();
sendCommandMessage (invoTrail.triggerMsg (Rec {Duration(7*id_, 2), Time(500,0), -int(j)}));
sendCommandMessage (GenNode{string{cmd.getID()}, Rec{Duration(7*id_, 2), Time(500,0), -int(j)}});
}
}

View file

@ -77,7 +77,6 @@ using lib::diff::GenNode;
using lib::diff::DataCap;
using proc::control::Command;
using proc::control::CommandDef;
using gui::interact::InvocationTrail;
using gui::ctrl::MutationMessage;
@ -324,12 +323,7 @@ namespace test {
gui::test::Nexus::setCommandHandler (&processCommandInvocation);
// Usually it's the InvocationStateManager's job to
// prepare an "InvocationTrail", which is a prospective
// Command invocation about to happen soon.
InvocationTrail invoTrail (Command::get (DUMMY_CMD_ID));
// the UI element relevant for this command invocation
// the UI element to trigger this command invocation
MockElm mock("uiElm");
int prevState = dummyState;
@ -340,7 +334,7 @@ namespace test {
// message to bind parameter data and finally trigger the command
mock.invoke (invoTrail, lib::diff::Rec({concreteParam}));
mock.invoke (DUMMY_CMD_ID, lib::diff::Rec({concreteParam}));
CHECK (dummyState == concreteParam); // command was indeed invoked
CHECK (nexusLog.verifyCall("act").arg("«int»|" +toString(concreteParam))
.beforeEvent("bind and trigger command \""+DUMMY_CMD_ID));

View file

@ -29,6 +29,7 @@
#include "lib/test/test-helper.hpp"
#include "gui/ctrl/bus-term.hpp"
#include "gui/ctrl/state-manager.hpp"
#include "proc/control/command.hpp"
#include "test/test-nexus.hpp"
#include "test/mock-elm.hpp"
#include "lib/idi/entry-id.hpp"
@ -62,9 +63,7 @@ namespace test {
using proc::control::LUMIERA_ERROR_UNBOUND_ARGUMENTS;
using lumiera::error::LUMIERA_ERROR_WRONG_TYPE;
namespace { // test fixture...
}//(End) test fixture
using proc::control::Command;
@ -104,8 +103,7 @@ namespace test {
replayStateMark();
verifyNotifications();
clearStates();
pushDiff();
destroy();
// pushDiff(); ///////////////////////////////////////////////////////////////////////////TICKET #1066
}
@ -188,7 +186,7 @@ namespace test {
{
MARK_TEST_FUN
gui::test::Nexus::startNewLog();
auto cmd = gui::test::Nexus::prepareMockCmd<string, TimeSpan, LuidH>();
Symbol cmd = gui::test::Nexus::prepareMockCmd<string, TimeSpan, LuidH>();
MockElm mock("uiElm");
@ -197,19 +195,19 @@ namespace test {
TimeSpan clip (Time(1,2,3), lib::test::randTime());
LuidH luid;
// we cannot invoke commands without binding all arguments
VERIFY_ERROR (UNBOUND_ARGUMENTS, mock.invoke(cmd) );
// we cannot invoke commands without binding required arguments
VERIFY_ERROR (WRONG_TYPE, mock.invoke(cmd) );
// proper argument typing is ensured while dispatching the bind message.
VERIFY_ERROR (WRONG_TYPE, mock.invoke(cmd, Rec({"lalala"})) );
// command can't be issued, since it's still unbound
CHECK (not cmd.canExec());
CHECK (not Command::canExec(cmd));
mock.invoke (cmd, text, clip, luid);
CHECK (cmd.canExec());
CHECK (Command::canExec(cmd));
CHECK (gui::test::Nexus::wasBound(cmd, text, clip, luid));
CHECK (not gui::test::Nexus::wasBound(cmd, "lololo"));
CHECK (gui::test::Nexus::wasInvoked(cmd));
@ -220,8 +218,8 @@ namespace test {
// Mock commands are automatically unique
auto cmdX = gui::test::Nexus::prepareMockCmd<>();
auto cmdY = gui::test::Nexus::prepareMockCmd<>();
CHECK (cmd.getID() != cmdX.getID());
CHECK (cmd.getID() != cmdY.getID());
CHECK (cmd != cmdX);
CHECK (cmd != cmdY);
CHECK (not gui::test::Nexus::wasInvoked(cmdX));
CHECK (not gui::test::Nexus::wasInvoked(cmdY));
@ -508,13 +506,6 @@ namespace test {
{
UNIMPLEMENTED ("push a mutation diff towards an interface element");
}
void
destroy()
{
UNIMPLEMENTED ("detach and destroy the test BusTerm");
}
};

View file

@ -101,18 +101,16 @@ namespace test{
static ctrl::StateManager& getMockStateManager();
using Cmd = interact::InvocationTrail;
template<typename...ARGS>
static Symbol prepareMockCmd();
static bool wasInvoked (Symbol);
template<typename...ARGS>
static Cmd prepareMockCmd();
static bool wasInvoked (Cmd);
static bool wasBound (Symbol, ARGS const& ...args);
template<typename...ARGS>
static bool wasBound (Cmd, ARGS const& ...args);
template<typename...ARGS>
static bool wasInvoked (Cmd, ARGS const& ...args);
static bool wasInvoked (Symbol, ARGS const& ...args);
private:
static void prepareDiagnosticCommandHandler();
@ -125,19 +123,18 @@ namespace test{
* which accepts arguments with the denoted types.
* @note this call installs the command mock into the Proc-Layer
* command registry, where it remains in place until shutdown.
* The command uses a synthetic command ID, which is available
* through the returned InvocationTrail. Besides, this call
* also installs a command handler into the Test-Nexus,
* The can be accessed through the generated command ID. Besides,
* this call also installs a command handler into the Test-Nexus,
* causing "`act`" messages to be processed and logged.
* @return InvocationTrail, the UI-representation of a Proc-Layer command.
* This can be used to trigger command actions on any model::Tangible.
* @return the ID of the generated mock command.
*/
template<typename...ARGS>
inline interact::InvocationTrail
inline Symbol
Nexus::prepareMockCmd()
{
prepareDiagnosticCommandHandler();
return Cmd {PlaceholderCommand<ARGS...>::fabricateNewInstance(getLog())};
return PlaceholderCommand<ARGS...>::fabricateNewInstance(getLog())
.getID();
}
@ -157,12 +154,12 @@ namespace test{
*/
template<typename...ARGS>
inline bool
Nexus::wasBound (Cmd cmd, ARGS const& ...args)
Nexus::wasBound (Symbol cmd, ARGS const& ...args)
{
using lib::diff::DataCap;
return getLog()
.verifyMatch("TestNexus.+HANDLING Command-Message for .+" +cmd.getID())
.verifyMatch("TestNexus.+HANDLING Command-Message for .+" +cmd)
.beforeCall("bind-command").on("TestNexus")
.arg(string(DataCap(args))...);
}
@ -180,14 +177,14 @@ namespace test{
*/
template<typename...ARGS>
inline bool
Nexus::wasInvoked (Cmd cmd, ARGS const& ...args)
Nexus::wasInvoked (Symbol cmd, ARGS const& ...args)
{
return getLog()
.verifyMatch("TestNexus.+HANDLING Command-Message for .+" +cmd.getID())
.beforeCall("exec-command").on("TestNexus").arg(cmd.getID())
.verifyMatch("TestNexus.+HANDLING Command-Message for .+" +cmd)
.beforeCall("exec-command").on("TestNexus").arg(cmd)
.beforeCall("exec").on("MockHandlingPattern")
.beforeCall("operate").arg(util::toString(args)...)
.beforeEvent("TestNexus", "SUCCESS handling "+cmd.getID());
.beforeEvent("TestNexus", "SUCCESS handling "+cmd);
}
/**
@ -195,13 +192,13 @@ namespace test{
* without matching any concrete arguments
*/
inline bool
Nexus::wasInvoked (Cmd cmd)
Nexus::wasInvoked (Symbol cmd)
{
return getLog()
.verifyMatch("TestNexus.+HANDLING Command-Message for .+" +cmd.getID())
.beforeCall("exec-command").on("TestNexus").arg(cmd.getID())
.verifyMatch("TestNexus.+HANDLING Command-Message for .+" +cmd)
.beforeCall("exec-command").on("TestNexus").arg(cmd)
.beforeCall("operate")
.beforeEvent("TestNexus", "SUCCESS handling "+cmd.getID());
.beforeEvent("TestNexus", "SUCCESS handling "+cmd);
}

View file

@ -12384,8 +12384,8 @@
<node COLOR="#338800" CREATED="1492281610286" ID="ID_1217333147" MODIFIED="1492359761121" TEXT="automatische Instanz-Erzeugung">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1492281619901" ID="ID_887103826" MODIFIED="1492281874171" TEXT="direkter Aufruf mit CommandDef-ID">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1492281619901" ID="ID_887103826" MODIFIED="1492440987297" TEXT="direkter Aufruf mit CommandDef-ID">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1492281659520" ID="ID_488879231" MODIFIED="1492281875331" TEXT="Argument-Resolver f&#xfc;r Kontext-Zugriff">
<icon BUILTIN="flag-yellow"/>
@ -13084,7 +13084,9 @@
<node COLOR="#338800" CREATED="1492281610286" ID="ID_1542647024" MODIFIED="1492359767992" TEXT="automatische Instanz-Erzeugung">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1492281619901" ID="ID_423372741" MODIFIED="1492281631495" TEXT="direkter Aufruf mit CommandDef-ID"/>
<node COLOR="#338800" CREATED="1492281619901" ID="ID_423372741" MODIFIED="1492440997416" TEXT="direkter Aufruf mit CommandDef-ID">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1492281659520" ID="ID_1742758477" MODIFIED="1492281669306" TEXT="Argument-Resolver f&#xfc;r Kontext-Zugriff"/>
<node CREATED="1492281675557" ID="ID_1809773326" MODIFIED="1492281681224" TEXT="InvocationState mit Callbacks"/>
</node>