68 using lib::append_all;
106 using CommandHandler = test::Nexus::CommandHandler;
107 using StateMarkHandler = test::Nexus::StateMarkHandler;
109 CommandHandler commandHandler_;
110 StateMarkHandler stateMarkHandler_;
117 log_.call (
this,
"act", command);
118 commandHandler_(command);
119 log_.event(
"TestNexus",
_Fmt(
"bind and trigger command \"%s\"%s")
120 % command.idi.getSym()
121 % command.data.get<Rec>());
127 log_.call (
this,
"note", subject, mark);
128 stateMarkHandler_(subject, mark);
129 log_.event(
"TestNexus",
_Fmt(
"processed note from %s |%s") % subject % mark);
135 log_.call(
this,
"mark", subject, mark);
136 if (BusHub::mark (subject, mark))
138 log_.event (
"TestNexus",
_Fmt(
"delivered mark to %s |%s") % subject % mark);
143 log_.warn (
_Fmt(
"discarding mark to unknown %s |%s") % subject % mark);
151 log_.call(
this,
"markAll", mark);
152 log_.event(
"Broadcast",
_Fmt(
"Broadcast mark(\"%s\"): %s") % mark.idi.getSym() % mark.data);
153 size_t cnt = BusHub::markAll (mark);
154 log_.event(
"TestNexus",
_Fmt(
"successfully broadcasted mark to %d terminals") % cnt);
161 string diffSeqLog = diff.updateDiagnostics();
162 log_.call (
this,
"change", subject, diffSeqLog);
163 if (BusHub::change (subject, move(diff)))
165 log_.event (
"TestNexus",
_Fmt(
"applied diff to %s |%s") % subject % diffSeqLog);
170 log_.warn (
_Fmt(
"disregarding change/diff to unknown %s |%s") % subject % diffSeqLog);
179 BusHub::routeAdd (identity, newNode);
180 log_.event(
"TestNexus",
_Fmt(
"added route to %s |%s| table-size=%2d")
190 log_.call (
this,
"routeDetach", node);
191 BusHub::routeDetach (node);
192 log_.event(
"TestNexus",
_Fmt(
"removed route to %s | table-size=%2d") % node % BusHub::size());
195 virtual operator string()
const 205 installCommandHandler();
206 installStateMarkHandler();
219 installCommandHandler (CommandHandler newHandler =CommandHandler())
222 commandHandler_ = newHandler;
227 log_.
warn(
_Fmt(
"NOT handling command-message %s in test-mode") %
cmd);
232 installStateMarkHandler (StateMarkHandler newHandler =StateMarkHandler())
235 stateMarkHandler_ = newHandler;
238 [=](ID subject,
GenNode const& mark)
240 log_.
warn(
_Fmt(
"NOT handling state-mark %s passed from %s in test-mode")
276 log().call(
this,
"act", command);
277 log().error (
"sent command invocation to ZombieNexus");
278 cerr <<
"Command " << command <<
" -> ZombieNexus" <<endl;
284 log().call(
this,
"note", subject, mark);
285 log().error (
"sent note message to ZombieNexus");
286 cerr <<
"note message "<< mark
287 <<
" FROM:" << subject
288 <<
" -> ZombieNexus" <<endl;
294 log().call(
this,
"mark", subject, mark);
295 log().error (
"request to deliver mark message via ZombieNexus");
296 cerr <<
"mark message -> ZombieNexus" <<endl;
303 log().call(
this,
"markAll", mark);
304 log().error (
"request to broadcast to all Zombies");
305 cerr <<
"broadcast message -> ZombieNexus" <<endl;
312 log().call(
this,
"change", subject, diff);
313 log().error (
"request to apply a diff message via ZombieNexus");
314 cerr <<
"change diff -> ZombieNexus" <<endl;
321 log().call(
this,
"routeAdd", identity, newNode);
322 log().error (
"attempt to connect against ZombieNexus");
323 cerr <<
"connect("<< identity <<
" -> ZombieNexus" <<endl;
330 log().call(
this,
"routeDetach", node);
331 log().error (
"disconnect from ZombieNexus");
332 cerr <<
"disconnect("<< node <<
" -> ZombieNexus" <<endl;
335 virtual operator string()
const 357 cerr << this->getID().getSym() <<
": Zombies never die" << endl;
419 testNexus().installCommandHandler (newHandler);
430 testNexus().installStateMarkHandler (newHandler);
456 log_.
call (
"MockHandlingPattern",
"exec", command);
457 command.invokeCapture();
458 command.invokeOperation();
464 log_.
call (
"MockHandlingPattern",
"undo", command);
465 command.invokeUndo();
469 isValid()
const override 477 : log_(Nexus::getLog())
478 , command_(retrieveCommand(cmdMsg))
480 log_.
event(
"TestNexus",
"HANDLING Command-Message for "+
string(command_));
482 Rec
const& argData{cmdMsg.data.get<Rec>()};
483 log_.
call (
"TestNexus",
"bind-command", enumerate(argData));
484 command_.bindArg (argData);
486 log_.
call (
"TestNexus",
"exec-command", command_);
487 if (command_.exec (*
this))
488 log_.
event(
"TestNexus",
"SUCCESS handling "+command_.getID());
490 log_.
warn(
_Fmt(
"FAILED to handle command-message %s in test-mode") % cmdMsg);
495 enumerate (Rec
const& argData)
497 EventLog::ArgSeq strings;
498 strings.reserve (argData.childSize());
500 , util::toString<DataCap>)
506 retrieveCommand (
GenNode const& cmdMsg)
508 Symbol cmdID {cmdMsg.idi.getSym().c_str()};
509 return Command::get (cmdID);
516 Nexus::prepareDiagnosticCommandHandler()
544 using StateManager::clearState;
566 stateManager().clearState();
571 stateManager().recordState (elementID, stateMark);
574 return getMockStateManager();
578 Nexus::getMockStateManager()
580 return stateManager();
595 string lateName = doomed.getID().getSym();
599 static_assert (
sizeof(
BusTerm) >=
sizeof(ZombieNexus),
"Zombie overflow");
600 new(&doomed) ZombieNexus{lateName, zombieNexus()};
601 testNexus().getLog().event(lateName +
" successfully zombificated.");
virtual bool change(ID subject, MutationMessage &&diff) override
direct a mutation message towards the indicated Tangible.
type erased baseclass for building a combined hash and symbolic ID.
Simple map based implementation of the PresentationStateManager interface.
Generic Message with an embedded diff, to describe changes to model elements.
EventLog & event(string text)
log some text as event
connection point at the UI-Bus.
EventLog & warn(string text)
Log a warning entry.
Support for verifying the occurrence of events from unit tests.
static void setCommandHandler(CommandHandler=CommandHandler())
install a closure (custom handler function) to deal with any command invocations encountered in the t...
virtual BusTerm & routeAdd(ID identity, Tangible &newNode) override
A fake UI backbone for investigations and unit testing.
Helper to log and verify the occurrence of events.
typed symbolic and hash ID for asset-like position accounting.
virtual void note(ID subject, GenNode const &mark) override
capture and record a "state mark" for later replay for restoring UI state.
virtual ~BusTerm()
this is an interface
ZombieNexus(string formerID, BusTerm &homeland)
fabricate a "dead terminal", marked as deceased, viciously connected to itself.
Opaque message to effect a structural change on a target, which is likewise only known in an abstract...
virtual void routeDetach(ID node) noexcept override
deactivate and remove a down-link route.
A front-end for using printf-style formatting.
Access point to singletons and other kinds of dependencies designated by type.
Implementation namespace for support and library code.
Generic functions to build identification schemes.
Compact diagnostic dummy command handler.
virtual bool change(ID subject, MutationMessage &&diff) override
alter and reshape the designated subject by applying the given diff message.
Token or Atom with distinct identity.
lib::Depend< TestNexus > testNexus
singleton instance of the [TestNexus] used for rigging unit tests
static ctrl::StateManager & useMockStateManager()
install a standard handler for state mark messages, which is actually backed by a mock implementation...
virtual size_t markAll(GenNode const &mark) override
broadcast a notification to all connected terminal nodes.
Marker types to indicate a literal string and a Symbol.
Lumiera GTK UI implementation root.
EventLog & call(string target, string function)
Log occurrence of a function call with no arguments.
Implementation of the PresentationStateManager interface through associative (key-value) store...
virtual void act(GenNode const &command)
prepare or trigger invocation of a command.
Generic building block for tree shaped (meta)data structures.
Steam-Layer command frontend.
static void setStateMarkHandler(StateMarkHandler=StateMarkHandler())
similar to the custom command handler this hook allows to install a closure to intercept any "state m...
Interface: handling of persistent interface state.
Central hub of the UI-Bus.
Singleton services and Dependency Injection.
static void zombificate(ctrl::BusTerm &)
kill the given [BusTerm] and implant a dead terminal in place
virtual bool mark(ID subject, GenNode const &mark) override
route mark messages down to the individual Tangible.
virtual void act(GenNode const &command)
prepare or trigger invocation of a command.
Lumiera error handling (C++ interface).
virtual void note(ID subject, GenNode const &mark) override
capture and record a "state mark" for later replay for restoring UI state.
string instanceTypeID(const TY *const obj)
designation of an distinct object instance
static ctrl::BusTerm & testUI()
get a connection point to a UI backbone faked for test
virtual void routeDetach(ID node) noexcept override
Handle object representing a single Command instance to be used by client code.
Bare symbolic and hash ID used for accounting of asset like entries.
Steam-Layer Command implementation.
Interface common to all UI elements of relevance for the Lumiera application.
auto transformIterator(IT const &src, FUN processingFunc)
Build a TransformIter: convenience free function shortcut, picking up the involved types automaticall...
object-like record of data.
virtual bool mark(ID subject, GenNode const &mark) override
route a state update or notification to the given subject.
virtual BusTerm & routeAdd(ID identity, Tangible &newNode) override
add a new down-link connection to the routing table
Interface: Operation Skeleton how to invoke or undo a command.
Core hub and routing table of the UI-Bus.
generic data element node within a tree
virtual size_t markAll(GenNode const &mark) override
broadcast a notification message to all currently connected bus terminals.