From fdcf431a9bd08e42803a6d573f7f08ec68216bc5 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 11 Aug 2017 02:00:54 +0200 Subject: [PATCH] DiffMesage: use as payload within MutationMessage and pass Diff by RValue now this highlights the unsettled decision still the more, as can be seen by all that unnecessary copying. Basically we move the Diff into the lambda-closure, from there into an anonymous instance, from there into the embedded Buffer in MutationMessage, which again just happens to sit in the closure storage when the action is invoked. And all of this copying just to move the DiffMessage for consumption into the TreeMutator... thus by #1066 we should really get rid of the MutationMessage class altogether! --- src/gui/ctrl/mutation-message.hpp | 6 +++--- src/gui/notification-interface-proxy.hpp | 2 +- src/gui/notification-service.cpp | 13 +++++++++---- src/gui/notification-service.hpp | 2 +- src/gui/ui-bus.cpp | 3 ++- src/include/gui-notification-facade.h | 2 +- src/lib/diff/diff-message.hpp | 7 +++++-- 7 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/gui/ctrl/mutation-message.hpp b/src/gui/ctrl/mutation-message.hpp index ae2e9de50..965a1840e 100644 --- a/src/gui/ctrl/mutation-message.hpp +++ b/src/gui/ctrl/mutation-message.hpp @@ -26,7 +26,7 @@ ** 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 + ** we can not represent it easily 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 @@ -42,9 +42,9 @@ ** ** @todo as of 1/2017 there is an unsolved problem how such messages can be passed from lower layers. ** A direct symptom is the dependency of this header on model::Tangible, which in turn requires - ** sigc::Trackable. This is a challenging topic, since we need to hand over to the UI-Event Thread /////////////////////////////////#1066 : Concept for passing Diff Messages + ** `sigc::Trackable`. This is a challenging topic, since we need to hand over to the UI-Event Thread /////////////////////////////////TICKET #1066 : Concept for passing Diff Messages ** - ** @see [AbstractTangible_test] + ** @see AbstractTangible_test ** */ diff --git a/src/gui/notification-interface-proxy.hpp b/src/gui/notification-interface-proxy.hpp index cb8e3d52b..fb96e3e91 100644 --- a/src/gui/notification-interface-proxy.hpp +++ b/src/gui/notification-interface-proxy.hpp @@ -72,7 +72,7 @@ namespace facade { void displayInfo (Level level, string const& text) override { _i_.displayInfo (level, cStr(text)); } void markError (ID uiElement, string const& text) override { _i_.markError(uiElement.getHash().get(), cStr(text)); } void markNote (ID uiElement, string const& text) override { _i_.markNote (uiElement.getHash().get(), cStr(text)); } - void mutate (ID uiElement, DiffMessage& diff) override { _i_.mutate (uiElement.getHash().get(), &diff); } + void mutate (ID uiElement, DiffMessage&& diff) override { _i_.mutate (uiElement.getHash().get(), &diff); } void triggerGuiShutdown (string const& cause) override { _i_.triggerGuiShutdown (cStr(cause)); } diff --git a/src/gui/notification-service.cpp b/src/gui/notification-service.cpp index 5ffa34fb1..c9e539b05 100644 --- a/src/gui/notification-service.cpp +++ b/src/gui/notification-service.cpp @@ -49,6 +49,7 @@ #include "gui/ctrl/ui-manager.hpp" #include "gui/ctrl/ui-dispatcher.hpp" +#include "gui/ctrl/mutation-message.hpp" #include "gui/notification-service.hpp" #include "lib/diff/gen-node.hpp" #include "include/logging.h" @@ -63,6 +64,7 @@ extern "C" { using lib::diff::GenNode; using lib::diff::TreeMutator; +using gui::ctrl::MutationMessage; using gui::ctrl::UiDispatcher; using gui::ctrl::BusTerm; using std::string; @@ -109,10 +111,13 @@ namespace gui { void - NotificationService::mutate (ID uiElement, DiffMessage&) /////////////////////////////////////////////////TICKET #1066 : how to pass a diff message + NotificationService::mutate (ID uiElement, DiffMessage&& diff) { - UNIMPLEMENTED ("actually produce a MutationMessage on the UI-Bus"); ///////////////////////////////////TICKET #1066 : how to build and pass a MutationMessage - ////////////////////////TODO actually push the information to the GUI ///////////////////////////////////TICKET #1098 : use a suitable Dispatcher + dispatch_->event ([=]() + { + MutationMessage diffHolder{DiffMessage(diff)}; //////////////////////////////////TICKET #1066 : unnecessary repackaging; could get rid of MutationMessage altogether + this->change (uiElement, diffHolder); + }); } @@ -245,7 +250,7 @@ namespace gui { { if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, "passing diff message"); else - _instance->mutate (reinterpret_cast (*element), *reinterpret_cast (diff)); + _instance->mutate (reinterpret_cast (*element), move(*reinterpret_cast (diff))); } ) , LUMIERA_INTERFACE_INLINE (triggerGuiShutdown, diff --git a/src/gui/notification-service.hpp b/src/gui/notification-service.hpp index 55759ace7..3097ca02f 100644 --- a/src/gui/notification-service.hpp +++ b/src/gui/notification-service.hpp @@ -83,7 +83,7 @@ namespace gui { void displayInfo (NotifyLevel,string const& text) override; void markError (ID uiElement, string const& text) override; void markNote (ID uiElement, string const& text) override; - void mutate (ID uiElement, DiffMessage&) override; ////////////////////////////////////////TICKET #1066 : how to pass a diff message + void mutate (ID uiElement, DiffMessage&&) override; ////////////////////////////////////////TICKET #1066 : how to pass a diff message void triggerGuiShutdown (string const& cause) override; private: diff --git a/src/gui/ui-bus.cpp b/src/gui/ui-bus.cpp index 8369a7855..11b860fd2 100644 --- a/src/gui/ui-bus.cpp +++ b/src/gui/ui-bus.cpp @@ -198,7 +198,8 @@ 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 + * @return `true` if the target was known and the diff was applied without accident, + * `false` if no diff was applied because the desired target is unconnected. * @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 diff --git a/src/include/gui-notification-facade.h b/src/include/gui-notification-facade.h index 976850aac..6dbcf05d3 100644 --- a/src/include/gui-notification-facade.h +++ b/src/include/gui-notification-facade.h @@ -98,7 +98,7 @@ namespace gui { * the UI model elements subject to this change. * @see diff-language.hpp */ - virtual void mutate (ID uiElement, DiffMessage&) =0; /////////////////////////////////////TICKET #1066 : how to pass a diff message + virtual void mutate (ID uiElement, DiffMessage&&) =0; /////////////////////////////////////TICKET #1066 : how to pass a diff message /** causes the GUI to shut down unconditionally * @param cause user visible explanation of the diff --git a/src/lib/diff/diff-message.hpp b/src/lib/diff/diff-message.hpp index abd736d0a..f2adabe94 100644 --- a/src/lib/diff/diff-message.hpp +++ b/src/lib/diff/diff-message.hpp @@ -82,14 +82,17 @@ namespace diff{ * diff messages need to be conserved beyond the producer's thread context, because * it will be pulled asynchronous from within the UI event thread! */ - class DiffMessage - : public DiffSource::iterator + struct DiffMessage + : DiffSource::iterator { + DiffMessage() = default; + /** * DiffMessage builder: * take ownership of an opaque heap allocated context * from which the concrete diff can be pulled on demand */ + explicit DiffMessage(DiffSource* diffGenerationContext) : DiffSource::iterator{DiffSource::build (diffGenerationContext)} { }