2015-11-21 03:39:07 +01:00
|
|
|
/*
|
|
|
|
|
BUS-TERM.hpp - connection point for UI elements to the UI-Bus
|
|
|
|
|
|
|
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2015, 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 bus-term.hpp
|
2015-11-26 21:10:38 +01:00
|
|
|
** Attachment point to the UI-Bus.
|
2015-11-21 03:39:07 +01:00
|
|
|
** Every gui::model::Tangible holds a BusTerm, which is linked
|
|
|
|
|
** to the Tangible's identity, and serves to relay interface actions
|
2015-11-26 21:10:38 +01:00
|
|
|
** towards the Proc-Layer, to remember state changes and to broadcast
|
|
|
|
|
** notifications. Moreover, the BusTerm is the service point
|
2015-11-21 03:39:07 +01:00
|
|
|
** to receive structural change messages.
|
|
|
|
|
**
|
2015-11-26 21:10:38 +01:00
|
|
|
** \par Lifecycle and identity
|
|
|
|
|
** An BusTerm is always created starting from another BusTerm, to
|
|
|
|
|
** which it will be wired. Moreover, each BusTerm bears a distinct
|
2015-12-27 03:16:49 +01:00
|
|
|
** [identity](\ref ::endpointID_), which is used as _implicit subject_
|
2015-11-26 21:10:38 +01:00
|
|
|
** for emanating messages, or as explicit destination for routing.
|
2015-12-27 03:16:49 +01:00
|
|
|
** The whole [UI-Bus](\ref BusController) is built to perform within the
|
2015-11-26 21:10:38 +01:00
|
|
|
** UI event thread and thus is _not threadsafe_. For that reason,
|
|
|
|
|
** the automatic detachment built into each BusTerm's dtor is
|
|
|
|
|
** sufficient to ensure sane connectivity.
|
|
|
|
|
**
|
2015-11-21 03:39:07 +01:00
|
|
|
** @todo as of 11/2015 this is complete WIP-WIP-WIP
|
|
|
|
|
**
|
2015-12-27 01:58:15 +01:00
|
|
|
** @see [BusTerm_test]
|
2015-11-21 03:39:07 +01:00
|
|
|
**
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
2015-11-28 18:36:35 +01:00
|
|
|
#ifndef GUI_CTRL_BUS_TERM_H
|
|
|
|
|
#define GUI_CTRL_BUS_TERM_H
|
2015-11-21 03:39:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "lib/error.hpp"
|
|
|
|
|
//#include "lib/symbol.hpp"
|
|
|
|
|
//#include "lib/util.hpp"
|
2015-11-26 21:10:38 +01:00
|
|
|
#include "lib/idi/entry-id.hpp"
|
|
|
|
|
#include "lib/diff/gen-node.hpp"
|
2015-11-21 03:39:07 +01:00
|
|
|
|
|
|
|
|
#include <boost/noncopyable.hpp>
|
2015-11-28 20:55:28 +01:00
|
|
|
#include <utility>
|
2015-11-21 03:39:07 +01:00
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace gui {
|
2015-12-18 01:02:19 +01:00
|
|
|
namespace model {
|
|
|
|
|
class Tangible;
|
|
|
|
|
}
|
2015-11-21 03:39:07 +01:00
|
|
|
namespace ctrl{
|
|
|
|
|
|
2016-10-02 23:51:45 +02:00
|
|
|
class MutationMessage;
|
|
|
|
|
|
2015-11-21 03:39:07 +01:00
|
|
|
// using lib::HashVal;
|
|
|
|
|
// using util::isnil;
|
2015-11-26 21:10:38 +01:00
|
|
|
using lib::idi::EntryID;
|
|
|
|
|
using lib::diff::GenNode;
|
2015-11-21 03:39:07 +01:00
|
|
|
using std::string;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-11-26 21:10:38 +01:00
|
|
|
* connection point at the UI-Bus.
|
|
|
|
|
* The UI-Bus is a star shaped network of terminal points,
|
2015-12-27 03:16:49 +01:00
|
|
|
* where each \ref model::Tangible "tangible UI element"
|
2015-11-26 21:10:38 +01:00
|
|
|
* holds a BusTerm serving access point. The BusTerm interface
|
|
|
|
|
* exposes the basic "verbs" available for communication within
|
|
|
|
|
* the UI
|
|
|
|
|
* - to _act_ on an element means to issue a command
|
|
|
|
|
* - to _note_ some state or information for later replay
|
|
|
|
|
* - to _mark_ as erroneous, send an information message,
|
|
|
|
|
* replay remembered presentation state or effect structural change
|
|
|
|
|
* There are \em indirect variants of the message verbs, which are
|
|
|
|
|
* intended for routing, broadcasting or forwarding. Effectively,
|
|
|
|
|
* routing is determined from the context and meaning of a message,
|
|
|
|
|
* where the _act_ and _note_ messages have an implicit receiver
|
|
|
|
|
* (either the Proc-Layer or the UI state manager), while the
|
|
|
|
|
* _mark_ messages are always directed _downstream_ towards
|
|
|
|
|
* some element.
|
2015-11-21 03:39:07 +01:00
|
|
|
*/
|
|
|
|
|
class BusTerm
|
|
|
|
|
{
|
2015-12-18 19:47:25 +01:00
|
|
|
protected:
|
2015-12-18 01:02:19 +01:00
|
|
|
using EntryID = lib::idi::BareEntryID;
|
2015-12-24 22:27:37 +01:00
|
|
|
using Tangible = gui::model::Tangible;
|
2015-11-28 20:55:28 +01:00
|
|
|
|
2015-12-18 01:02:19 +01:00
|
|
|
EntryID endpointID_;
|
2015-11-26 21:10:38 +01:00
|
|
|
BusTerm& theBus_;
|
2015-11-21 03:39:07 +01:00
|
|
|
|
|
|
|
|
public:
|
2016-12-03 19:37:52 +01:00
|
|
|
using ID = EntryID const&;
|
|
|
|
|
|
2015-11-26 21:10:38 +01:00
|
|
|
virtual ~BusTerm(); ///< this is an interface
|
|
|
|
|
|
2015-12-19 03:40:19 +01:00
|
|
|
virtual void act (GenNode const& command);
|
2015-12-18 01:02:19 +01:00
|
|
|
virtual void note (ID subject, GenNode const& mark);
|
2016-01-03 03:37:52 +01:00
|
|
|
virtual bool mark (ID subject, GenNode const& mark);
|
2015-11-26 21:10:38 +01:00
|
|
|
|
2016-02-14 02:20:51 +01:00
|
|
|
virtual size_t markAll (GenNode const& mark);
|
2016-10-01 23:09:08 +02:00
|
|
|
virtual bool change (ID subject, MutationMessage& diff);
|
2016-02-14 02:20:51 +01:00
|
|
|
|
2015-12-25 00:41:14 +01:00
|
|
|
virtual operator string() const;
|
|
|
|
|
|
2015-12-19 03:40:19 +01:00
|
|
|
void note (GenNode const& mark);
|
|
|
|
|
|
2015-12-18 01:02:19 +01:00
|
|
|
ID getID() const { return endpointID_; }
|
2015-11-26 21:10:38 +01:00
|
|
|
|
2015-12-18 01:02:19 +01:00
|
|
|
|
2015-12-24 22:27:37 +01:00
|
|
|
BusTerm attach (ID, Tangible& newNode);
|
2015-11-28 23:50:56 +01:00
|
|
|
|
2015-11-28 20:55:28 +01:00
|
|
|
/** may be moved, but not copied,
|
|
|
|
|
* due to the embedded identity */
|
|
|
|
|
BusTerm(BusTerm&&) = default;
|
2015-11-21 03:39:07 +01:00
|
|
|
|
|
|
|
|
protected:
|
2016-12-10 04:01:06 +01:00
|
|
|
/**
|
|
|
|
|
* @param identity used for routing towards this BusTerm
|
|
|
|
|
* @param attached_to the "upstream" connection to the Bus
|
|
|
|
|
* @warning it is essential that this ctor just initialises
|
|
|
|
|
* the references, but never invokes any operation
|
|
|
|
|
* on the _upstream_ connection. Because this allows
|
|
|
|
|
* to build mutually interdependent connections.
|
|
|
|
|
*/
|
2015-11-28 20:55:28 +01:00
|
|
|
BusTerm(ID identity, BusTerm& attached_to)
|
2015-11-26 21:10:38 +01:00
|
|
|
: endpointID_(identity)
|
|
|
|
|
, theBus_(attached_to)
|
|
|
|
|
{ }
|
2015-12-18 01:02:19 +01:00
|
|
|
|
2015-12-24 22:43:41 +01:00
|
|
|
virtual BusTerm& routeAdd(ID,Tangible&);
|
2015-12-18 01:02:19 +01:00
|
|
|
virtual void routeDetach(ID) noexcept;
|
2016-10-04 03:50:44 +02:00
|
|
|
|
|
|
|
|
bool isConnected() const noexcept;
|
2015-11-21 03:39:07 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2015-12-19 03:40:19 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/** record state mark from this subject */
|
2015-12-19 04:05:21 +01:00
|
|
|
inline void
|
2015-12-19 03:40:19 +01:00
|
|
|
BusTerm::note (GenNode const& mark)
|
|
|
|
|
{
|
|
|
|
|
theBus_.note (this->endpointID_, mark);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-04 03:50:44 +02:00
|
|
|
/** @internal tie break */
|
|
|
|
|
inline bool
|
|
|
|
|
BusTerm::isConnected() const noexcept
|
|
|
|
|
{
|
|
|
|
|
return &theBus_ != this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2015-11-21 03:39:07 +01:00
|
|
|
|
|
|
|
|
}} // namespace gui::ctrl
|
2015-11-28 18:36:35 +01:00
|
|
|
#endif /*GUI_CTRL_BUS_TERM_H*/
|