CmdAccess: replace existing usages of InvocationTrail
This commit is contained in:
parent
876c1dd1fd
commit
8c7ac997de
9 changed files with 72 additions and 69 deletions
|
|
@ -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)));
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)}});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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ü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ür Kontext-Zugriff"/>
|
||||
<node CREATED="1492281675557" ID="ID_1809773326" MODIFIED="1492281681224" TEXT="InvocationState mit Callbacks"/>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue