70 using CmdDefEntry = std::tuple<Symbol, DefinitionClosure>;
72 std::deque<CmdDefEntry>&
73 pendingCmdDefinitions()
75 static std::deque<CmdDefEntry> definitionQueue;
76 return definitionQueue;
86 CommandSetup::~CommandSetup() { }
123 if (not definitionBlock)
124 throw error::Invalid (
"unbound function/closure provided for CommandSetup" 125 , LERR_(BOTTOM_VALUE));
127 pendingCmdDefinitions().emplace_front (cmdID_, move(definitionBlock));
135 return pendingCmdDefinitions().size();
141 while (not pendingCmdDefinitions().empty())
143 CmdDefEntry&
entry = pendingCmdDefinitions().back();
145 DefinitionClosure& buildDefinition{get<DefinitionClosure> (
entry)};
147 TRACE (command,
"defining Command(%s)...", cmdID.c());
149 buildDefinition(def);
150 pendingCmdDefinitions().pop_back();
164 CommandInstanceManager::~CommandInstanceManager() { }
171 : dispatcher_{dispatcher}
184 Symbol instanceID{prototypeID, invocationID};
185 Command& instance = table_[instanceID];
187 throw new error::Logic (
_Fmt{
"Attempt to create a new Command instance '%s', " 188 "while an instance for this invocationID %s " 189 "is currently open for parametrisation and " 190 "not yet dispatched for execution."}
191 % instanceID % invocationID
192 , LERR_(DUPLICATE_COMMAND)
196 ENSURE (instance,
"cloning of command prototype failed");
216 auto entry = table_.find(instanceID);
217 if (
entry == table_.end())
219 if (not
entry->second)
220 throw error::Logic (
_Fmt{
"Command instance '%s' is not (yet/anymore) active"}
223 return entry->second;
238 auto entry = table_.find(instanceID);
239 if (
entry == table_.end())
241 "globally registered command definition, " 242 "nor to an previously opened command instance")
244 , LERR_(INVALID_COMMAND));
245 if (not
entry->second.isValid())
246 throw error::Logic (
_Fmt{
"Command instance '%s' is not (yet/anymore) active"}
249 if (not must_be_bound or
entry->second.canExec())
250 instance = move(
entry->second);
252 if (must_be_bound and not instance.canExec())
254 "without binding all arguments properly beforehand"}
256 , LERR_(UNBOUND_ARGUMENTS));
258 ENSURE (instance.isValid() and
259 (instance.canExec() or not must_be_bound));
268 REQUIRE (toDispatch and toDispatch.canExec());
269 dispatcher_.enqueue(move (toDispatch));
270 ENSURE (not toDispatch);
306 instance.bindArg (argSeq);
307 ENSURE (instance.canExec());
313 CommandInstanceManager::contains (
Symbol instanceID)
const 315 return util::contains (table_, instanceID)
316 and unConst(
this)->table_[instanceID].isValid();
Helper class used solely for defining a Command-Object.
Installing and invoking of application lifecycle event callbacks.
static size_t definition_count()
Symbol newInstance(Symbol prototypeID, string const &invocationID)
Create and thus "open" a new anonymous command instance.
AnyPair entry(Query< TY > const &query, typename WrapReturn< TY >::Wrapper &obj)
helper to simplify creating mock table entries, wrapped correctly
Service to support forming and invocation of command instances for use by the UI. ...
static Command get(Symbol cmdID)
Access existing command for use.
This header is for including and configuring NoBug.
Steam-Layer implementation namespace root.
A front-end for using printf-style formatting.
Command getInstance(Symbol instanceID)
access the currently "opened" instance with the given instanceID
CommandSetup & operator=(DefinitionClosure)
core functionality: provide a command definition block.
Marker and Helper for writing Steam-Layer Command definitions.
static size_t pendingCnt()
diagnostics / test
static Command maybeGetNewInstance(Symbol cmdID)
try to access an existing command definition and immediately create a new clone copy by calling newIn...
Derived specific exceptions within Lumiera's exception hierarchy.
Token or Atom with distinct identity.
Marker types to indicate a literal string and a Symbol.
Interface of a service to perform Commands on the session.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
Command getCloneOrInstance(Symbol, bool)
Provision for setup of concrete commands for use by the UI.
Steam-Layer command frontend.
const char * ON_GLOBAL_INIT
to be triggered in main()
static void invokeDefinitionClosures()
define and register a callback for a specific lifecycle event.
Lumiera error handling (C++ interface).
CommandSetup(Symbol cmdID)
Start a command setup for defining a Steam-Layer command with the given cmdID.
Handle object representing a single Command instance to be used by client code.
void handOver(Command &&)
void bindAndDispatch(Symbol instanceID, Rec const &argSeq)
fire and forget anonymous command instance.
void dispatch(Symbol instanceID)
hand over the designated command instance to the dispatcher installed on construction.
Actually defining a command and binding it to execution parameters.
CommandInstanceManager(CommandDispatch &)
create a CommandInstanceManager and wire it with the given CommandDispatch implementation.