implement logging overrides in the Test-Nexus implementation
the actual functionality is forwareded to the base class, which is the regular Nexus Hub
This commit is contained in:
parent
3230660d86
commit
2e4d74747e
4 changed files with 99 additions and 14 deletions
|
|
@ -84,6 +84,7 @@ namespace ctrl{
|
|||
RoutingTable routingTable_;
|
||||
|
||||
|
||||
protected:
|
||||
/** route mark messages down to the individual Tangible.
|
||||
* @note only messages to elements currently registered
|
||||
* in the routing table are dispatched. All other
|
||||
|
|
@ -129,6 +130,12 @@ namespace ctrl{
|
|||
}
|
||||
|
||||
|
||||
size_t
|
||||
size() const
|
||||
{
|
||||
return routingTable_.size();
|
||||
}
|
||||
|
||||
public:
|
||||
explicit
|
||||
Nexus (BusTerm& uplink_to_CoreService, ID identity =lib::idi::EntryID<Nexus>())
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ namespace test {
|
|||
|
||||
MockElm mock(elmID);
|
||||
CHECK (nexusLog.verifyCall("routeAdd").on("TestNexus").arg(elmID,"MockElm")
|
||||
.beforeEvent("TestNexus", "add route to bID-zeitgeist"));
|
||||
.beforeEvent("TestNexus", "added route to bID-zeitgeist"));
|
||||
|
||||
EventLog elmLog = mock.getLog();
|
||||
CHECK (elmLog.verifyCall("ctor").on(&mock)
|
||||
|
|
@ -137,10 +137,10 @@ namespace test {
|
|||
CHECK (elmLog.verifyEvent("collapsed"));
|
||||
CHECK (nexusLog.verifyCall("note").on("TestNexus").arg("zeitgeist", "collapse"));
|
||||
|
||||
// send a note down to the mock element
|
||||
gui::test::Nexus::testUI().note (elmID, GenNode("Flash", 23));
|
||||
// send a state mark down to the mock element
|
||||
gui::test::Nexus::testUI().mark (elmID, GenNode("Flash", 23));
|
||||
CHECK (nexusLog.verifyCall("note").on("TestNexus").arg(elmID, "Flash")
|
||||
.beforeEvent("TestNexus", "note to bID-zeitgeist"));
|
||||
.beforeEvent("TestNexus", "mark to bID-zeitgeist"));
|
||||
CHECK (elmLog.verifyCall("doFlash").on("zeitgeist"));
|
||||
|
||||
|
||||
|
|
@ -148,7 +148,7 @@ namespace test {
|
|||
mock.kill();
|
||||
CHECK (elmLog.verifyEvent("destroy","zeitgeist"));
|
||||
CHECK (nexusLog.verifyCall("routeDetach").on("TestNexus").arg(elmID)
|
||||
.beforeEvent("TestNexus", "remove route to bID-zeitgeist"));
|
||||
.beforeEvent("TestNexus", "removed route to bID-zeitgeist"));
|
||||
|
||||
gui::test::Nexus::testUI().note (elmID, GenNode("Flash", 88));
|
||||
CHECK (nexusLog.verify("remove route to bID-zeitgeist")
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include "lib/idi/entry-id.hpp"
|
||||
#include "lib/idi/genfunc.hpp"
|
||||
#include "lib/depend.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
|
@ -57,6 +58,7 @@ using std::string;
|
|||
using lib::test::EventLog;
|
||||
using lib::diff::GenNode;
|
||||
using gui::ctrl::BusTerm;
|
||||
using util::_Fmt;
|
||||
//using util::contains;
|
||||
//using util::isnil;
|
||||
|
||||
|
|
@ -65,6 +67,48 @@ namespace test{
|
|||
|
||||
namespace { // internal details
|
||||
|
||||
using lib::Variant;
|
||||
using lib::diff::Rec;
|
||||
using lib::diff::DataValues;
|
||||
|
||||
using BusHub = gui::ctrl::Nexus;
|
||||
|
||||
|
||||
/** helper to figure out if a command message
|
||||
* is a binding or invocation message.
|
||||
* @remarks from a design standpoint, this is ugly,
|
||||
* since we're basically switching on type.
|
||||
* Well -- we do it just for diagnostics here,
|
||||
* so _look away please..._
|
||||
*/
|
||||
inline bool
|
||||
isCommandBinding (GenNode const& msg)
|
||||
{
|
||||
class CommandBindingDetector
|
||||
: public Variant<DataValues>::Predicate
|
||||
{
|
||||
bool handle (Rec const&) override { return true; }
|
||||
}
|
||||
detector;
|
||||
|
||||
return msg.data.accept (detector);
|
||||
}
|
||||
|
||||
inline string
|
||||
invocationStage (GenNode const& msg)
|
||||
{
|
||||
return isCommandBinding(msg)? string("binding for")
|
||||
: string("invoke");
|
||||
}
|
||||
|
||||
inline string
|
||||
renderBindingArgs (GenNode const& msg)
|
||||
{
|
||||
return isCommandBinding(msg)? "| " + string(msg.data.get<Rec>())
|
||||
: "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal fake interface backbone and unit test rig
|
||||
* for simulated command and presentation state handling.
|
||||
|
|
@ -75,7 +119,7 @@ namespace test{
|
|||
* state messages
|
||||
*/
|
||||
class TestNexus
|
||||
: public gui::ctrl::Nexus
|
||||
: public BusHub
|
||||
{
|
||||
EventLog log_{this};
|
||||
|
||||
|
|
@ -83,25 +127,59 @@ namespace test{
|
|||
virtual void
|
||||
act (GenNode const& command)
|
||||
{
|
||||
UNIMPLEMENTED("receive and handle command invocation");
|
||||
log_.call(this, "act", command);
|
||||
BusHub::act (command);
|
||||
log_.event("TestNexus", _Fmt("%s command \"%s\"%s")
|
||||
% invocationStage(command)
|
||||
% command.idi.getSym()
|
||||
% renderBindingArgs(command));
|
||||
}
|
||||
|
||||
|
||||
virtual void
|
||||
note (ID subject, GenNode const& mark) override
|
||||
{
|
||||
UNIMPLEMENTED ("receive and handle presentation state note messages.");
|
||||
log_.call(this, "note", subject, mark);
|
||||
BusHub::note (subject, mark);
|
||||
log_.event("TestNexus", _Fmt("processed note from %s |%s") % subject % mark);
|
||||
}
|
||||
|
||||
virtual void
|
||||
mark (ID subject, GenNode const& mark) override
|
||||
{
|
||||
log_.call(this, "mark", subject, mark);
|
||||
BusHub::mark (subject, mark);
|
||||
log_.event("TestNexus", _Fmt("delivered mark to %s |%s") % subject % mark);
|
||||
}
|
||||
|
||||
virtual operator string() const
|
||||
{
|
||||
return getID().getSym()+"."+lib::idi::instanceTypeID(this);
|
||||
}
|
||||
|
||||
virtual BusTerm&
|
||||
routeAdd (ID identity, Tangible& newNode) override
|
||||
{
|
||||
log_.call(this, "routeAdd", identity, newNode);
|
||||
BusHub::routeAdd (identity, newNode);
|
||||
log_.event("TestNexus", _Fmt("added route to %s |%s| table-size=%2d")
|
||||
% identity
|
||||
% lib::idi::instanceTypeID(&newNode)
|
||||
% BusHub::size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual void
|
||||
routeDetach (ID node) noexcept override
|
||||
{
|
||||
log_.call(this, "routeDetach", node);
|
||||
BusHub::routeDetach (node);
|
||||
log_.event("TestNexus", _Fmt("removed route to %s | table-size=%2d") % node % BusHub::size());
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
TestNexus()
|
||||
: Nexus(*this, lib::idi::EntryID<TestNexus>("mock-UI"))
|
||||
: BusHub(*this, lib::idi::EntryID<TestNexus>("mock-UI"))
|
||||
{ }
|
||||
|
||||
// standard copy operations
|
||||
|
|
|
|||
|
|
@ -2383,7 +2383,7 @@ On a second thought, the fact that the [[Bus-MObject|BusMO]] is rather void of a
|
|||
:sound mixing desks use list style arrangement, and this has proven to be quite viable, when combined with the ability to //send over// output from one mixer stripe to the input of another, allowing to build arbitrary complex filter matrices. On the other hand, organising a mix in //subgroups// can be considered best practice. This leads to arranging the pipes //as wood:// by default and on top level as list, optionally expanding into a subtree with automatic rooting, augmented by the ability to route any output to any input (cycles being detected and flagged as error).
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GuiCommandBinding" creator="Ichthyostega" modifier="Ichthyostega" created="201511272246" modified="201512190214" tags="design decision operational GuiPattern GuiIntegration draft discuss" changecount="18">
|
||||
<div title="GuiCommandBinding" creator="Ichthyostega" modifier="Ichthyostega" created="201511272246" modified="201601021718" tags="design decision operational GuiPattern GuiIntegration draft discuss" changecount="21">
|
||||
<pre>The question //how to connect the notion of an ''interface action'' to the notion of a ''command'' issued towards the [[session model|HighLevelModel]].//
|
||||
|
||||
!prerequisites for issuing a command
|
||||
|
|
@ -2399,7 +2399,7 @@ Within the Lumiera architecture, with the very distinct separation between [[Ses
|
|||
** the focus and current selection is relevant
|
||||
** the user interaction might supply context by pointing at something
|
||||
** the proximity of tangible interface elements might be sufficient to figure out missing parts
|
||||
** in fact it might be necessary to prepend the invocation of a detail parameter dialog to the command execution
|
||||
** in fact it might be necessary to intersperse the invocation of a detail parameter dialogue prior to command execution
|
||||
* and finally, after considering all these concerns, it is possible to wire a connection into the actual invocation point in UI
|
||||
This observation might be surprising; even while a given command is well defined, we can not just invoke it right away. The prevalence of all these intermediary complexities is what opens the necessity and the room for InteractionControl, which is a concern specific to human-computer interfaces. Faced with such a necessity, there are two fundamentally different approaches.
|
||||
!!!Binding close to the widget
|
||||
|
|
@ -2954,9 +2954,9 @@ From experiences with other middle scale projects, I prefer having the test code
|
|||
[img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="InvocationTrail" creator="Ichthyostega" modifier="Ichthyostega" created="201512190210" tags="def GuiIntegration draft" changecount="1">
|
||||
<div title="InvocationTrail" creator="Ichthyostega" modifier="Ichthyostega" created="201512190210" modified="201601021714" tags="def GuiIntegration draft" changecount="2">
|
||||
<pre>//A command in preparation of being issued from the UI.//
|
||||
The actual persistent operations on the session model are defined as DSL scripts acting on the session interface, and configured as a //command prototype.// Typically these need to be enriched with at least the actual subject to invoke this command on; many commands require additional parameters, e.g. some time or colour value. These actual invocation parameters need to be picked up from UI elements, and the process of preparing and outfitting a generic command with these actual values is tracked by an ''InvocationTrail handle''. When ready, finally this handle can be issued on any bus terminal, i.e. on any [[tangible interface element|UI-Element]].</pre>
|
||||
The actual persistent operations on the session model are defined through a DSL scripts acting on the session interface, and configured as a //command prototype.// Typically these need to be enriched with at least the actual subject to invoke this command on; many commands require additional parameters, e.g. some time or colour value. These actual invocation parameters need to be picked up from UI elements, and the process of preparing and outfitting a generic command with these actual values is tracked by an ''InvocationTrail handle''. When ready, finally this handle can be issued on any bus terminal, i.e. on any [[tangible interface element|UI-Element]].</pre>
|
||||
</div>
|
||||
<div title="JobTicket" modifier="Ichthyostega" created="201202120018" modified="201208311625" tags="spec Rendering draft">
|
||||
<pre>The actual media data is rendered by [[individually scheduled render jobs|RenderJob]]. All these calculations together implement a [[stream of calculations|CalcStream]], as demanded and directed by the PlayProcess. During the preparation of playback, a ''node planning phase'' is performed, to arrange for [[dispatching|FrameDispatcher]] the individual calculations per frame. The goal of these //preparations//&nbsp; is to find out
|
||||
|
|
|
|||
Loading…
Reference in a new issue