From 27ba8d589653eea7db1dfba29a52bc758f963f96 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 30 Sep 2016 22:23:55 +0200 Subject: [PATCH] UI-Bus/mutation: draft idea for mutation message on UI-Bus --- src/gui/ctrl/bus-controller.cpp | 21 ++++++ src/gui/ctrl/bus-term.hpp | 2 + src/gui/ctrl/mutation-message.hpp | 104 ++++++++++++++++++++++++++++++ src/gui/ctrl/nexus.hpp | 9 +++ tests/gui/test/test-nexus.cpp | 17 +++++ wiki/thinkPad.ichthyo.mm | 27 ++++++++ 6 files changed, 180 insertions(+) create mode 100644 src/gui/ctrl/mutation-message.hpp diff --git a/src/gui/ctrl/bus-controller.cpp b/src/gui/ctrl/bus-controller.cpp index 8adf0764f..5d92337dc 100644 --- a/src/gui/ctrl/bus-controller.cpp +++ b/src/gui/ctrl/bus-controller.cpp @@ -73,6 +73,9 @@ namespace ctrl { } + MutationMessage::~MutationMessage() { } + + /** Builder function: establish and wire a new BusTerm. @@ -171,6 +174,24 @@ namespace ctrl { } + /** alter and reshape the designated subject by applying the given diff message. + * @param diff encapsulated representation of a concrete diff sequence for the target. + * @return if the target was known and the diff was applied without accident + * @throws lumiera::error::State when diff application fails due to the target's shape + * or state being different than implicitly assumed by the given diff. + * @remark each tangible offers to build a custom TreeMutator, which is appropriately + * wired to receive diff messages targeted towards this specific element. The + * standard implementation within the Nexus uses this ability to create a + * DiffApplicator, finally to feed the given diff to the target, + * which consequently will reshape and remould itself accordingly. + */ + void + BusTerm::change (ID subject, MutationMessage& diff) + { + theBus_.change(subject, diff); + } + + /** * @internal establish new down-link connection form UI-Bus * @param node reference to the [Tangible] to be connected. diff --git a/src/gui/ctrl/bus-term.hpp b/src/gui/ctrl/bus-term.hpp index c696f5a7a..d701b6709 100644 --- a/src/gui/ctrl/bus-term.hpp +++ b/src/gui/ctrl/bus-term.hpp @@ -55,6 +55,7 @@ //#include "lib/util.hpp" #include "lib/idi/entry-id.hpp" #include "lib/diff/gen-node.hpp" +#include "gui/ctrl/mutation-message.hpp" #include #include @@ -111,6 +112,7 @@ namespace ctrl{ virtual bool mark (ID subject, GenNode const& mark); virtual size_t markAll (GenNode const& mark); + virtual void change (ID subject, MutationMessage& diff); virtual operator string() const; diff --git a/src/gui/ctrl/mutation-message.hpp b/src/gui/ctrl/mutation-message.hpp new file mode 100644 index 000000000..60eed50bb --- /dev/null +++ b/src/gui/ctrl/mutation-message.hpp @@ -0,0 +1,104 @@ +/* + MUTATION-MESSAGE.hpp - message on UI-Bus to cause changes to tangible UI elements + + Copyright (C) Lumiera.org + 2016, Hermann Vosseler + + 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 mutation-message.hpp + ** Message on the UI-Bus to cause changes on the targeted [UI-Element](\ref Tangible). + ** The UI-Bus offers a dedicated API to direct MutationMessages towards Tangible elements, + ** as designated by the given ID. Actually, such messages serve as capsule to transport a + ** diff-sequence -- since a diff sequence as such is always concrete and tied to a specific context, + ** we can not represent it directly as an abstract type on interface level. The receiver of a diff + ** sequence must offer the ability to be reshaped through diff messages, which is expressed through + ** the interface DiffMutable. In the case at question here, gui::model::Tangible offers this interface + ** and thus the ability to construct a concrete lib::diff::TreeMutator, which in turn is bound to the + ** internals of the actual UI-Element. Together this allows for a generic implementation of MutationMessage + ** handling, where the designated UI-Element is reshaped by applying an embedded concrete diff message + ** with the help of a `DiffApplicator`, based on the TreeMutator exposed. + ** + ** ## Creating mutation messages + ** The UI-Bus invocation actually takes a reference to MutationMessage, and thus on usage a + ** concrete instance needs to be created. This concrete Message embeds an actual diff sequence, + ** which is an iterable sequence of lib::diff::DiffStep records. + ** + ** @todo as of 10/2016 this is WIP-WIP-WIP + ** + ** @see [AbstractTangible_test] + ** + */ + + +#ifndef GUI_CTRL_MUTATION_MESSAGE_H +#define GUI_CTRL_MUTATION_MESSAGE_H + + +#include "lib/error.hpp" +//#include "lib/symbol.hpp" +//#include "lib/util.hpp" +//#include "lib/idi/entry-id.hpp" +//#include "lib/diff/gen-node.hpp" + +//#include +//#include +#include + + +namespace gui { +namespace model { + class Tangible; +} +namespace ctrl{ + +// using lib::HashVal; +// using util::isnil; +// using lib::idi::EntryID; +// using lib::diff::GenNode; + using std::string; + + + /** + * Message on the UI-Bus holding an embedded diff sequence. + * The Nexus (hub of the UI-Bus) will prompt the designated Tangible + * to expose a TreeMutator, and then apply the embedded diff. + */ + class MutationMessage + { + protected: + + public: + virtual ~MutationMessage(); ///< this is an interface + + operator string() const + { + UNIMPLEMENTED("string representation of diff/mutation messages"); + } + + protected: + }; + + + + + /** */ + + +}} // namespace gui::ctrl +#endif /*GUI_CTRL_MUTATION_MESSAGE_H*/ diff --git a/src/gui/ctrl/nexus.hpp b/src/gui/ctrl/nexus.hpp index 0956a86f0..193492447 100644 --- a/src/gui/ctrl/nexus.hpp +++ b/src/gui/ctrl/nexus.hpp @@ -114,6 +114,15 @@ namespace ctrl{ return routingTable_.size(); } + + /** */ + virtual void + change (ID subject, MutationMessage& diff) override + { + UNIMPLEMENTED("actually apply a diff to the target Tangible"); + } + + /** add a new down-link connection to the routing table * @param identity the [endpoint-ID](\ref BusTerm::endpointID_) used * to address the new element to be connected to the bus. diff --git a/tests/gui/test/test-nexus.cpp b/tests/gui/test/test-nexus.cpp index 80f8d7b08..66edbe8ed 100644 --- a/tests/gui/test/test-nexus.cpp +++ b/tests/gui/test/test-nexus.cpp @@ -75,6 +75,7 @@ using lib::diff::DataValues; using lib::idi::instanceTypeID; using lib::test::EventLog; using gui::ctrl::BusTerm; +using gui::ctrl::MutationMessage; using gui::interact::PresentationStateManager; using gui::interact::StateRecorder; using proc::control::Command; @@ -211,6 +212,14 @@ namespace test{ return cnt; } + virtual void + change (ID subject, MutationMessage& diff) override + { + log_.call (this, "change", subject, diff); + BusHub::change (subject, diff); + log_.event ("TestNexus", _Fmt("applied diff to %s |%s") % subject % diff); + } + virtual BusTerm& routeAdd (ID identity, Tangible& newNode) override { @@ -345,6 +354,14 @@ namespace test{ return 0; } + virtual void + change (ID subject, MutationMessage& diff) override + { + log().call(this, "change", subject, diff); + log().error ("request to apply a diff message via ZombieNexus"); + cerr << "change diff -> ZombieNexus" < + + + + + + + + + + + + + + + + + + + + + + + + + + +