61 using CmdDefEntry = std::tuple<Symbol, DefinitionClosure>;
63 std::deque<CmdDefEntry>&
64 pendingCmdDefinitions()
66 static std::deque<CmdDefEntry> definitionQueue;
67 return definitionQueue;
77 CommandSetup::~CommandSetup() { }
114 if (not definitionBlock)
115 throw error::Invalid (
"unbound function/closure provided for CommandSetup" 116 , LERR_(BOTTOM_VALUE));
118 pendingCmdDefinitions().emplace_front (cmdID_, move(definitionBlock));
126 return pendingCmdDefinitions().size();
132 while (not pendingCmdDefinitions().empty())
134 CmdDefEntry&
entry = pendingCmdDefinitions().back();
136 DefinitionClosure& buildDefinition{get<DefinitionClosure> (
entry)};
138 TRACE (command,
"defining Command(%s)...", cmdID.c());
140 buildDefinition(def);
141 pendingCmdDefinitions().pop_back();
155 CommandInstanceManager::~CommandInstanceManager() { }
162 : dispatcher_{dispatcher}
175 Symbol instanceID{prototypeID, invocationID};
176 Command& instance = table_[instanceID];
178 throw new error::Logic (
_Fmt{
"Attempt to create a new Command instance '%s', " 179 "while an instance for this invocationID %s " 180 "is currently open for parametrisation and " 181 "not yet dispatched for execution."}
182 % instanceID % invocationID
183 , LERR_(DUPLICATE_COMMAND)
187 ENSURE (instance,
"cloning of command prototype failed");
207 auto entry = table_.find(instanceID);
208 if (
entry == table_.end())
210 if (not
entry->second)
211 throw error::Logic (
_Fmt{
"Command instance '%s' is not (yet/anymore) active"}
214 return entry->second;
229 auto entry = table_.find(instanceID);
230 if (
entry == table_.end())
232 "globally registered command definition, " 233 "nor to an previously opened command instance")
235 , LERR_(INVALID_COMMAND));
236 if (not
entry->second.isValid())
237 throw error::Logic (
_Fmt{
"Command instance '%s' is not (yet/anymore) active"}
240 if (not must_be_bound or
entry->second.canExec())
241 instance = move(
entry->second);
243 if (must_be_bound and not instance.canExec())
245 "without binding all arguments properly beforehand"}
247 , LERR_(UNBOUND_ARGUMENTS));
249 ENSURE (instance.isValid() and
250 (instance.canExec() or not must_be_bound));
259 REQUIRE (toDispatch and toDispatch.canExec());
260 dispatcher_.enqueue(move (toDispatch));
261 ENSURE (not toDispatch);
297 instance.bindArg (argSeq);
298 ENSURE (instance.canExec());
304 CommandInstanceManager::contains (
Symbol instanceID)
const 306 return util::contains (table_, instanceID)
307 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.