LUMIERA.clone/src/include/session-command-facade.h
Ichthyostega a64dc9c05f Clip-Drag: draft a solution for handling gestures
...even while keeping the focus to the actual problem at hand,
this solution must be built with the larger goal in mind, which
is the ability to support various editing gestures, transmitted
possibly through several control-systems (mouse, keybindings, pen...)

It is obvious that we'll need a dedicated controller for each kind of gesture;
what turns out as tricky is to maintain and bind a stateful context
and find the correct participants while a specific gesture is under way.
2021-02-28 23:04:06 +01:00

141 lines
5.6 KiB
C++

/*
SESSION-COMMAND-FACADE.h - access point for invoking commands on the session
Copyright (C) Lumiera.org
2016, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file session-command-facade.h
** Major public Interface to the Session subsystem of Lumiera GUI.
** This interface describes the ability of the Session to trigger the execution
** of pre-defined commands, outfitted with suitable arguments and parameters.
** Triggering of these commands typically happens in response to some messages
** being sent over the UI-Bus. Likewise, external entities (e.g. plug-ins) may
** invoke commands over this interface to alter the session.
**
** For this reason, the operations exposed here are defined in terms matching
** the structure of binding and invocation messages. This goes so far as to
** accept the command arguments for binding packaged as `Record<GenNode>`.
** For each command, there needs to be a registration record within the
** Steam-Layer implementation. The service implementation backing this
** facade indeed retrieves the corresponding steam::control::Command
** handles to perform the binding operation and hands them over
** to the SteamDispatcher for invocation.
**
** @see command.hpp
** @see session-command-service.hpp implementation
** @see steam::control::SteamDispatcher
** @see stage::ctrl::CoreService
*/
#ifndef STEAM_CONTROL_SESSION_COMMAND_H
#define STEAM_CONTROL_SESSION_COMMAND_H
#ifdef __cplusplus /* ============== C++ Interface ================= */
#include "lib/depend.hpp"
#include "lib/diff/gen-node.hpp"
#include "lib/symbol.hpp"
#include <string>
namespace steam {
namespace control {
using lib::Symbol;
using std::string;
/**********************************************************************//**
* Global access point to invoke commands and cause edit operations within
* the Session. Any changes to the session are effected by prepared functors
* bound into a steam::control::Command registration. A command instance will
* first be outfitted with suitable parameters to define the target and to
* qualify and elaborate the action, before it can be actually triggered.
* Commands then go through a queue to be invoked one by one.
*
* The service exposed through this facade offers dedicated support for
* the _standard command cycle_, as is typically performed from the UI.
* Such a usage cycle starts with ["opening"](\ref #cycle) a local anonymous
* clone copy from the global command definition, which is then used
* in further calls to be outfitted with actual arguments and finally
* to be handed over to the dispatcher for execution.
* @warning this standard command cycle is intended for single-threaded
* use from the UI. It is not threadsafe. To the contrary, all
* operations with globally registered commands are threadsafe.
*
* @remark This is a layer separation facade interface. Clients should
* use the embedded #facade factory, which yields a proxy to route any
* calls through the lumieraorg_SessionCommand interface
* @throws lumiera::error::State when interface is not opened
* @todo as of 2/2021 only the #trigger operation is used; if no case for
* an elaborated command cycle with binding step and deferred invocation
* shows up, we may consider dropping the other operations
* @see [Command system](\ref command.hpp)
* @see SessionCommandFunction_test
*/
class SessionCommand
{
public:
static lib::Depend<SessionCommand> facade;
/** start next command cycle and "open" a new anonymous command instance */
virtual Symbol cycle (Symbol cmdID, string const& invocationID) =0;
/** bind the command's arguments and trigger command invocation immediately */
virtual void trigger (Symbol cmdID, lib::diff::Rec const& args) =0;
/** prepare command invocation: bind the command's arguments */
virtual void bindArg (Symbol cmdID, lib::diff::Rec const& args) =0;
/** trigger invocation of a prepared command */
virtual void invoke (Symbol cmdID) =0;
protected:
virtual ~SessionCommand() {} ///< this is an interface
friend class lib::DependencyFactory<SessionCommand>;
};
}} // namespace steam::control
extern "C" {
#endif /* =========================== CL Interface ===================== */
#include "common/interface.h"
LUMIERA_INTERFACE_DECLARE (lumieraorg_SessionCommand, 0,
LUMIERA_INTERFACE_SLOT (const char*, cycle, (const char*, const char*)),
LUMIERA_INTERFACE_SLOT (void, trigger, (const char*, const void*)),
LUMIERA_INTERFACE_SLOT (void, bindArg, (const char*, const void*)),
LUMIERA_INTERFACE_SLOT (void, invoke, (const char*)),
);
#ifdef __cplusplus
}// extern "C"
#endif
#endif /*STEAM_CONTROL_SESSION_COMMAND_H*/