diff --git a/doc/technical/library/DiffFramework.txt b/doc/technical/library/DiffFramework.txt index b5f38210a..23ea5906a 100644 --- a/doc/technical/library/DiffFramework.txt +++ b/doc/technical/library/DiffFramework.txt @@ -48,6 +48,12 @@ diff application:: _target_ of diff application. Typically we want to apply a diff to a data sequence, to mutate it into a new shape, conforming with the shape of the diff's ``target sequence'' +tree mutator:: + a customisable intermediary, allowing to apply a diff sequence against an opaque data structure. + For the purpose of diff application, the TreeMutator serves as target object, while in fact it is itself + attached by a _binding_ to the actual target data structure, which remains a hidden implementation detail. + This allows to manipulate the target data structure without knowing its concrete representation. + diff generator:: a facility producing a diff, which is a sequence of diff verbs. Typically, a diff generator works lazily, demand driven. diff --git a/src/gui/ctrl/bus-term.hpp b/src/gui/ctrl/bus-term.hpp index 81bdfcdce..9aae4415d 100644 --- a/src/gui/ctrl/bus-term.hpp +++ b/src/gui/ctrl/bus-term.hpp @@ -69,7 +69,7 @@ namespace lib { - namespace diff { class DiffMessage; } + namespace diff { class MutationMessage; } } namespace gui { namespace model { @@ -79,7 +79,7 @@ namespace ctrl{ using lib::idi::EntryID; using lib::diff::GenNode; - using lib::diff::DiffMessage; + using lib::diff::MutationMessage; using std::string; @@ -121,7 +121,7 @@ namespace ctrl{ virtual bool mark (ID subject, GenNode const& mark); virtual size_t markAll (GenNode const& mark); - virtual bool change (ID subject, DiffMessage&& diff); + virtual bool 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 deleted file mode 100644 index c2733a153..000000000 --- a/src/gui/ctrl/mutation-message.hpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - 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 model::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 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 - ** 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 some iterable sequence of lib::diff::DiffStep records. - ** @warning be sure to understand that the diff sequence is really moved away and then consumed. - ** - ** @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 /////////////////////////////////TICKET #1066 : Concept for passing Diff Messages - ** - ** @see AbstractTangible_test - ** - */ - - -#ifndef GUI_CTRL_MUTATION_MESSAGE_H -#define GUI_CTRL_MUTATION_MESSAGE_H - - -#include "lib/error.hpp" -#include "lib/opaque-holder.hpp" -#include "lib/diff/tree-diff-application.hpp" -#include "gui/model/tangible.hpp" -#include "lib/format-util.hpp" - -#include -#include - - -namespace gui { -namespace ctrl{ - - using std::string; - - namespace diff_msg { // implementation details for embedding concrete diff messages - - using lib::diff::DiffApplicator; - using model::Tangible; - using std::move; - - class Holder - { - public: - virtual ~Holder() {}; ///< this is an interface - virtual void applyTo (Tangible&) =0; - virtual string describe() const =0; - }; - - template - class Wrapped - : public Holder - { - DIFF diff_; - - virtual void - applyTo (Tangible& target) override - { - DiffApplicator applicator(target); - applicator.consume (move(diff_)); - } - - virtual string - describe() const override - { - DIFF copy(diff_); // NOTE: we copy, since each iteration consumes. - return ::util::join (move(copy)); - } - - public: - Wrapped (DIFF&& diffSeq) - : diff_(move(diffSeq)) - { } - }; - - - /** standard size to reserve for the concrete diff representation - * @note this is a pragmatic guess, based on the actual usage pattern within Lumiera. - * This determines the size of the inline buffer within MutationMessage. - * You'll get an static assertion failure when creating a MutationMessage - * from a concrete diff representation requires more storage space... - */ - enum { SIZE_OF_DIFF_REPRESENTATION = sizeof(std::vector) - + sizeof(size_t) - + sizeof(void*) - }; - - using Buffer = lib::InPlaceBuffer; - }//(End) implementation details... - - - - - - /** - * 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 - : public diff_msg::Buffer - { - public: - /** build a MutationMessage by _consuming_ the given diff sequence - * @param diffSeq some iterable DiffStep sequence. - * @warning parameter will be moved into the embedded buffer and consumed - */ - template - MutationMessage(DIFF&& diffSeq) - : diff_msg::Buffer{ embedType>() - , std::move(diffSeq)} - { } - - void - applyTo (model::Tangible& target) - { - access()->applyTo(target); - } - - operator string() const - { - return unConst(this)->access()->describe(); - } - - 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 1586f312b..d76a4e23a 100644 --- a/src/gui/ctrl/nexus.hpp +++ b/src/gui/ctrl/nexus.hpp @@ -42,7 +42,7 @@ #include "lib/error.hpp" #include "lib/idi/genfunc.hpp" -#include "lib/diff/diff-message.hpp" +#include "lib/diff/mutation-message.hpp" #include "lib/diff/tree-diff-application.hpp" #include "gui/ctrl/bus-term.hpp" #include "gui/model/tangible.hpp" @@ -122,7 +122,7 @@ namespace ctrl{ * subject to this change */ virtual bool - change (ID subject, DiffMessage&& diff) override + change (ID subject, MutationMessage&& diff) override { auto entry = routingTable_.find (subject); if (entry == routingTable_.end()) diff --git a/src/gui/notification-interface-proxy.hpp b/src/gui/notification-interface-proxy.hpp index fb96e3e91..c6fa6cd2e 100644 --- a/src/gui/notification-interface-proxy.hpp +++ b/src/gui/notification-interface-proxy.hpp @@ -54,7 +54,7 @@ namespace gui { namespace lumiera { namespace facade { using gui::ID; - using lib::diff::DiffMessage; + using lib::diff::MutationMessage; typedef InstanceHandle< LUMIERA_INTERFACE_INAME(lumieraorg_GuiNotification, 0) , gui::GuiNotification @@ -70,9 +70,9 @@ namespace facade { //----Proxy-Implementation-of-GuiNotification-------- 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 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, MutationMessage&& 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 1a246baab..400d16497 100644 --- a/src/gui/notification-service.cpp +++ b/src/gui/notification-service.cpp @@ -39,8 +39,6 @@ ** but before closing the GuiNotification facade will just be enqueued, ** but then dropped on destruction of the UiDispatcher PImpl. ** - ** @todo 1/2017 find a solution for passing diff messages /////////////////////////////////////////////////TICKET #1066 - ** ** @see ui-dispatcher.hpp ** */ @@ -50,7 +48,7 @@ #include "gui/ctrl/ui-manager.hpp" #include "gui/ctrl/ui-dispatcher.hpp" #include "gui/notification-service.hpp" -#include "lib/diff/diff-message.hpp" +#include "lib/diff/mutation-message.hpp" #include "lib/diff/gen-node.hpp" #include "include/logging.h" #include "lib/util.hpp" @@ -64,7 +62,7 @@ extern "C" { using lib::diff::GenNode; using lib::diff::TreeMutator; -using lib::diff::DiffMessage; +using lib::diff::MutationMessage; using gui::ctrl::UiDispatcher; using gui::ctrl::BusTerm; using std::string; @@ -111,7 +109,7 @@ namespace gui { void - NotificationService::mutate (ID uiElement, DiffMessage&& diff) + NotificationService::mutate (ID uiElement, MutationMessage&& diff) { dispatch_->event ([=]() //////////////////////////////////TODO care for error handling!!! { @@ -250,7 +248,7 @@ namespace gui { { if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, "passing diff message"); else - _instance->mutate (reinterpret_cast (*element), move(*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 3097ca02f..12e4f6c76 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, MutationMessage&&) override; void triggerGuiShutdown (string const& cause) override; private: diff --git a/src/gui/ui-bus.cpp b/src/gui/ui-bus.cpp index 41fdf23bf..999dcedce 100644 --- a/src/gui/ui-bus.cpp +++ b/src/gui/ui-bus.cpp @@ -208,7 +208,7 @@ namespace ctrl { * which consequently will reshape and remould itself accordingly. */ bool - BusTerm::change (ID subject, DiffMessage&& diff) + BusTerm::change (ID subject, MutationMessage&& diff) { return theBus_.change(subject, move(diff)); } diff --git a/src/include/gui-notification-facade.h b/src/include/gui-notification-facade.h index 6dbcf05d3..759548f9d 100644 --- a/src/include/gui-notification-facade.h +++ b/src/include/gui-notification-facade.h @@ -44,7 +44,7 @@ #ifdef __cplusplus /* ============== C++ Interface ================= */ #include "include/interfaceproxy.hpp" -#include "lib/diff/diff-message.hpp" ///////////////////////////////////////////////////////////STICKET #1066 : placeholder +#include "lib/diff/mutation-message.hpp" #include "lib/idi/entry-id.hpp" #include @@ -53,7 +53,7 @@ namespace gui { using std::string; - using lib::diff::DiffMessage; + using lib::diff::MutationMessage; using ID = lib::idi::BareEntryID const&; @@ -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, MutationMessage&&) =0; /** causes the GUI to shut down unconditionally * @param cause user visible explanation of the diff --git a/src/lib/diff/gen-node.hpp b/src/lib/diff/gen-node.hpp index 6cc1f5cb7..e14944585 100644 --- a/src/lib/diff/gen-node.hpp +++ b/src/lib/diff/gen-node.hpp @@ -25,14 +25,14 @@ ** Generic building block for tree shaped (meta)data structures. ** A representation built from GenNode elements is intended to support ** (limited) introspection of data structures and exchange of mutations - ** in the form of \link diff-language.hpp diff messages. \endlink + ** in the form of [diff messages](\ref diff-language.hpp). ** ** Despite of the name, GenNode is \em not meant to be an universal ** data representation; rather it is limited to embody a fixed hard ** wired set of data types, able to stand-in for attributes ** and sub scope contents of the lumiera high-level data model. ** - ** \par Anatomy of a GenNode + ** # Anatomy of a GenNode ** ** GenNode is a polymorphic value with well defined identity and type. ** Each element is conceived to be »unique within context« -- as defined @@ -52,7 +52,7 @@ ** addressable by-name and an (ordered) collection of elements treated ** as children within the scope of the given record. ** - ** \par Requirements + ** # Requirements ** ** GenNode elements are to be used in the diff detection and implementation. ** This implies some requirements for the (opaque) elements used in diff: @@ -68,7 +68,7 @@ ** - finally, the handling of changes prompts us to support installation ** of a specifically typed change handling closure. ** - ** \par monadic nature? + ** ## monadic nature? ** ** As suggested by the usage for representation of tree shaped data, we acknowledge ** that GenNode could be a Monad. We support the basic operation \em construction, diff --git a/src/lib/diff/diff-message.hpp b/src/lib/diff/mutation-message.hpp similarity index 87% rename from src/lib/diff/diff-message.hpp rename to src/lib/diff/mutation-message.hpp index 99519b461..416bec91b 100644 --- a/src/lib/diff/diff-message.hpp +++ b/src/lib/diff/mutation-message.hpp @@ -1,5 +1,5 @@ /* - DIFF-MESSAGE.hpp - message to cause changes to generic model elements + MUTATION-MESSAGE.hpp - message to cause changes to generic model elements Copyright (C) Lumiera.org 2017, Hermann Vosseler @@ -87,8 +87,8 @@ */ -#ifndef LIB_DIFF_DIFF_MESSAGE_H -#define LIB_DIFF_DIFF_MESSAGE_H +#ifndef LIB_DIFF_MUTATION_MESSAGE_H +#define LIB_DIFF_MUTATION_MESSAGE_H #include "lib/error.hpp" @@ -130,26 +130,26 @@ namespace diff{ * the production context of diff messages need to be conserved beyond the producer's * thread context, because it will be pulled asynchronous from within the UI event thread! */ - struct DiffMessage + struct MutationMessage : DiffSource::iterator { using _FrontEnd = DiffSource::iterator; - DiffMessage() = default; - DiffMessage(DiffMessage&&) = default; - DiffMessage(DiffMessage const&) = default; - DiffMessage(DiffMessage& o) : DiffMessage((DiffMessage const&)o) { } - DiffMessage& operator= (DiffMessage const&) = default; - DiffMessage& operator= (DiffMessage &&) = default; - ////////////////////////TICKET #963 Forwarding shadows copy operations + MutationMessage() = default; + MutationMessage(MutationMessage&&) = default; + MutationMessage(MutationMessage const&) = default; + MutationMessage(MutationMessage& o) : MutationMessage((MutationMessage const&)o) { } + MutationMessage& operator= (MutationMessage const&) = default; + MutationMessage& operator= (MutationMessage &&) = default; + ////////////////////////TICKET #963 Forwarding shadows copy operations /** - * DiffMessage builder: + * MutationMessage builder: * take ownership of an opaque heap allocated context * from which the concrete diff can be pulled on demand */ explicit - DiffMessage(DiffSource* diffGenerationContext) + MutationMessage(DiffSource* diffGenerationContext) : _FrontEnd{DiffSource::build (diffGenerationContext)} { } @@ -158,8 +158,8 @@ namespace diff{ * @note initialiser elements will be _copied_ into a _heap alloacated_ * snapshot (vector), which is then managed by `shared_ptr` */ - DiffMessage(std::initializer_list const&& ili) - : DiffMessage{iter_stl::snapshot (move(ili))} + MutationMessage(std::initializer_list const&& ili) + : MutationMessage{iter_stl::snapshot (move(ili))} { } /** @@ -168,8 +168,8 @@ namespace diff{ * a _heap allocated snapshot_ */ template - DiffMessage(ARGS&& ...args) - : DiffMessage{ {std::forward(args)...} } + MutationMessage(ARGS&& ...args) + : MutationMessage{ {std::forward(args)...} } { } /** @@ -177,7 +177,7 @@ namespace diff{ * @note source iterator is copied into a heap allocated IterSource */ template - DiffMessage(IT&& ii, enable_if< can_IterForEach, void*> =nullptr) + MutationMessage(IT&& ii, enable_if< can_IterForEach, void*> =nullptr) : _FrontEnd{iter_source::wrapIter (std::forward(ii))} { } @@ -187,7 +187,7 @@ namespace diff{ * @warning like with any classical iterators, the container must stay alive and accessible */ template - DiffMessage(CON& container, enable_if< __and_< can_STL_ForEach + MutationMessage(CON& container, enable_if< __and_< can_STL_ForEach ,__not_>>, void*> =nullptr) : _FrontEnd{iter_source::eachEntry(container)} { } @@ -196,11 +196,11 @@ namespace diff{ /** * enable support to show content of the message. * After calling this function, operator string() renders all DiffSteps - * @warning since by design a DiffMessage can only be ``pulled'' once, + * @warning since by design a MutationMessage can only be ``pulled'' once, * this operation needs to impose a _side effect:_ it materialises * the complete diff sequence at once into a heap allocated buffer. */ - DiffMessage& updateDiagnostics(); + MutationMessage& updateDiagnostics(); }; @@ -211,7 +211,7 @@ namespace diff{ struct DiffSnapshot : std::vector { - DiffSnapshot(DiffMessage& srcMsg) + DiffSnapshot(MutationMessage& srcMsg) { for ( ; srcMsg; ++srcMsg ) push_back (*srcMsg); @@ -223,7 +223,7 @@ namespace diff{ using _Wrapped = WrappedLumieraIter<_RangeIT>; /** - * Decorator to be layered transparently on top of DiffMessage. + * Decorator to be layered transparently on top of MutationMessage. * Actually, what we do is to discharge the diff generator into * the DiffSnapshot buffer and then replace the link to the original * generator to this decorator, which, when iterated, yields the @@ -231,12 +231,12 @@ namespace diff{ * are now stored into that DiffSnapshot _buffer we control,_ we're * able to produce a diagnostic listing of the complete sequence. */ - class MaterialisedDiffMessageBuffer + class MaterialisedDiffBuffer : private DiffSnapshot , public _Wrapped { public: - MaterialisedDiffMessageBuffer(DiffMessage& srcMsg) + MaterialisedDiffBuffer(MutationMessage& srcMsg) : DiffSnapshot{srcMsg} , _Wrapped{_RangeIT{DiffSnapshot::begin(), DiffSnapshot::end()}} { } @@ -259,10 +259,10 @@ namespace diff{ * process can be repeated and then the [diagnostics](operator string()) * will show the remainder of the sequence _left at that point._ */ - inline DiffMessage& - DiffMessage::updateDiagnostics() + inline MutationMessage& + MutationMessage::updateDiagnostics() { - return *this = DiffMessage{new MaterialisedDiffMessageBuffer(*this)}; + return *this = MutationMessage{new MaterialisedDiffBuffer(*this)}; } @@ -270,4 +270,4 @@ namespace diff{ }} // namespace lib::diff -#endif /*LIB_DIFF_DIFF_MESSAGE_H*/ +#endif /*LIB_DIFF_MUTATION_MESSAGE_H*/ diff --git a/src/lib/diff/record.hpp b/src/lib/diff/record.hpp index ba095ecc8..638648c8b 100644 --- a/src/lib/diff/record.hpp +++ b/src/lib/diff/record.hpp @@ -26,13 +26,12 @@ ** To be used in a context where introspection, open, extensible definitions ** and loose coupling of data representation matters. Typically, structures ** defined in terms of Record elements are linked to the actual \em core - ** representation of the same entities relying on - ** \link diff-language.hpp diff messages. \endlink + ** representation of the same entities relying on [diff messages](\ref diff-language.hpp). ** Record is one of the supported flavours within the DataCap of GenNode elements, ** which in turn serve as the standard handle to refer to other elements, entities, ** attributes or references within the "backbone" of the Lumiera GUI. ** - ** \par design decisions + ** ## design decisions ** The Record type is shaped from its intended use: It serves to symbolically represent ** \em objects in the "external tree description". Here, \em objects means objects for ** real, i.e. with types, fields and an enclosed scope. But \em external means that we diff --git a/src/lib/diff/tree-mutator-attribute-binding.hpp b/src/lib/diff/tree-mutator-attribute-binding.hpp index a0e74b126..69221a1d2 100644 --- a/src/lib/diff/tree-mutator-attribute-binding.hpp +++ b/src/lib/diff/tree-mutator-attribute-binding.hpp @@ -69,7 +69,7 @@ ** it depends on the concrete setup of the data binding (TreeMutator), if some ** expression in diff language will be deemed incompatible -- which happens when ** in the end no "onion layer" of the concrete binding was able to absorb and - ** comply to the diff message. + ** comply to the MutationMessage. ** ** Another architectural consideration is relevant to the way attribute bindings are ** constructed: we rather construct a separate binding for each individual attribute, diff --git a/src/lib/diff/tree-mutator.hpp b/src/lib/diff/tree-mutator.hpp index 5969919e3..f03ade540 100644 --- a/src/lib/diff/tree-mutator.hpp +++ b/src/lib/diff/tree-mutator.hpp @@ -66,11 +66,11 @@ ** just supporting move construction, as will happen when using the DSL functions on ** the builder. This is also the only supported usage pattern: you create an anonymous ** TreeMutator sub type by using the Builder functions right within the scope about to - ** consume one strike of diff messages. These messages should cover anything to confirm - ** or reshape _all of the target's contents_. After that, you must not refer to the - ** exhausted TreeMutator anymore, just let it fall out of scope. Incidentally, this - ** also means that _any failure or exception encountered_ while applying a diff will - ** leave a **corrupted target data structure**. The basic assumption is that + ** consume one strike of DiffStep entries from a MutationMessage. These diff steps + ** should cover anything to confirm or reshape _all of the target's contents_. After that, + ** you must not refer to the exhausted TreeMutator anymore, just let it fall out of scope. + ** Incidentally, this also means that _any failure or exception encountered_ while applying + ** a diff will leave a **corrupted target data structure**. The basic assumption is that ** - the target data structure will actually be built through diff messages solely ** - and that all received diff messages are sane, as being drawn from a ** semantically and structurally equivalent source structure @@ -426,7 +426,7 @@ namespace diff{ /** set up binding to a GenNode tree: Special setup to build a concrete `TreeMutator`. * This decorator is already outfitted with the necessary closures to work on a * diff::Record -- which is typically used as "meta representation" of - * object-like structures. Thus this binding allows to apply a diff message onto + * object-like structures. Thus this binding allows to apply a MutationMessage onto * such a given »External Tree Description«, mutating it into new shape. * @remarks our meta representation of "objects" is based on Record, which * is implemented through two STL collections, one for the attributes and diff --git a/tests/51-gui-model.tests b/tests/51-gui-model.tests index 886d79d12..22f7cf813 100644 --- a/tests/51-gui-model.tests +++ b/tests/51-gui-model.tests @@ -25,8 +25,3 @@ END PLANNED "Concept demonstration: retrieve session contents" SessionStructureMapping_test < - - 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 tangible-update-test.cpp - ** This test is a concept study regarding a generic structure of UI elements. - ** Such gui::model::Tangible elements share the ability to be updated through - ** a structural diff message. Which implies this test to be also an integration - ** test of Lumiera's tree diff handling framework - ** - ** @note as of 1/2015 this is a draft into the blue... - ** @todo WIP ///////////////////////TICKET #959 - ** @todo WIP ///////////////////////TICKET #961 - ** - ** @see gui::UiBus - ** - */ - - -#include "lib/test/run.hpp" -//#include "gui/model/session-facade.hpp" -//#include "gui/model/diagnostics.hpp" -//#include "lib/util.hpp" - - -//#include - -//using util::contains; -//using std::string; - - -namespace gui { -namespace model{ -namespace test { - - namespace { // test fixture... - - }//(End) test fixture - - - - - - - /***********************************************************************//** - * @test demonstrate the fundamental patterns to access the current - * session structure and contents from the GUI, and to receive - * a notification with the updated structure and contents. - * - since we focus on the mapping and enumeration mechanism, - * the explored content is faked diagnostic data - * - in reality, these operations are intended to be run from - * within the GUI event thread and immediately interwoven - * with GTK / Cairo display code - * - it is the responsibility of the "Gui Model" (#SessionFacade) - * to ensure a read barrier, so the retrieved data can not be - * corrupted by concurrent session mutation operations. - * - * @see SessionElementQuery_test - * @see gui::model::SessionFacade - */ - class TangibleUpdate_test : public Test - { - - virtual void - run (Arg) - { - } - - - /** @test how to retrieve and enumerate session contents - * as operation initiated from GUI display code - */ - void - retrieveSessionStructure () - { - - } - - }; - - - /** Register this test class... */ - LAUNCHER (TangibleUpdate_test, "unit gui"); - - -}}} // namespace gui::model::test diff --git a/tests/gui/test/test-nexus.cpp b/tests/gui/test/test-nexus.cpp index bfb1f647c..5deb85cda 100644 --- a/tests/gui/test/test-nexus.cpp +++ b/tests/gui/test/test-nexus.cpp @@ -51,7 +51,7 @@ #include "proc/control/command.hpp" #include "gui/ctrl/nexus.hpp" #include "gui/ctrl/state-recorder.hpp" -#include "lib/diff/diff-message.hpp" +#include "lib/diff/mutation-message.hpp" #include "lib/diff/gen-node.hpp" #include "lib/idi/entry-id.hpp" #include "lib/idi/genfunc.hpp" @@ -70,7 +70,7 @@ using lib::transformIterator; using lib::diff::Rec; using lib::diff::GenNode; using lib::diff::DataCap; -using lib::diff::DiffMessage; +using lib::diff::MutationMessage; using lib::idi::instanceTypeID; using lib::test::EventLog; using gui::ctrl::BusTerm; @@ -156,7 +156,7 @@ namespace test{ } virtual bool - change (ID subject, DiffMessage&& diff) override + change (ID subject, MutationMessage&& diff) override { string diffSeqLog = diff.updateDiagnostics(); // snapshot of generated diff sequence log_.call (this, "change", subject, diffSeqLog); @@ -307,7 +307,7 @@ namespace test{ } virtual bool - change (ID subject, DiffMessage&& diff) override + change (ID subject, MutationMessage&& diff) override { log().call(this, "change", subject, diff); log().error ("request to apply a diff message via ZombieNexus"); diff --git a/tests/library/diff/diff-tree-application-test.cpp b/tests/library/diff/diff-tree-application-test.cpp index 3112ac22b..f118994f5 100644 --- a/tests/library/diff/diff-tree-application-test.cpp +++ b/tests/library/diff/diff-tree-application-test.cpp @@ -96,8 +96,8 @@ namespace test{ * [variant data node](\ref diff::GenNode). The key point to note * is the usage of Record elements as payload within GenNode, which * allows to represent tree shaped object like data structures. - * @note literally the same test case is repeated in DiffMessage_test, - * just there the diff is transported in a DiffMessage capsule, + * @note literally the same test case is repeated in MutationMessage_test, + * just there the diff is transported in a MutationMessage capsule, * as is the case in the real application as well. * @see DiffComplexApplication_test handling arbitrary data structures * @see GenericRecordRepresentation_test diff --git a/tests/library/diff/diff-message-test.cpp b/tests/library/diff/mutation-message-test.cpp similarity index 92% rename from tests/library/diff/diff-message-test.cpp rename to tests/library/diff/mutation-message-test.cpp index 20b412b32..209b55e0d 100644 --- a/tests/library/diff/diff-message-test.cpp +++ b/tests/library/diff/mutation-message-test.cpp @@ -1,5 +1,5 @@ /* - DiffMessage(Test) - demonstrate the basics of tree diff representation + MutationMessage(Test) - demonstrate the basics of tree diff representation Copyright (C) Lumiera.org 2017, Hermann Vosseler @@ -20,14 +20,14 @@ * *****************************************************/ -/** @file diff-message-test.cpp - ** unit test \ref DiffMessage_test +/** @file mutation-message-test.cpp + ** unit test \ref MutationMessage_test */ #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" -#include "lib/diff/diff-message.hpp" +#include "lib/diff/mutation-message.hpp" #include "lib/diff/tree-diff-application.hpp" #include "lib/iter-adapter-stl.hpp" #include "lib/time/timevalue.hpp" @@ -94,7 +94,7 @@ namespace test{ * - moreover we provide a simplified builder function to create * hard wired diff messages in a concise way * - and finally this test repeats the scenario of DiffTreeApplication_test, - * but this time the diff sequences are encapsulated as DiffMessage. + * but this time the diff sequences are encapsulated as MutationMessage. * @remarks like all the other _diff related_ tests, this code might be hard * to follow, unless you're familiar with the underlying concepts. Basically, * a _Diff_ is represented as _a linearised sequence of verb tokens_. Together @@ -112,10 +112,10 @@ namespace test{ * @see DiffTreeApplication_test change a tree-like data structure by diff * @see DiffComplexApplication_test handling arbitrary data structures * @see DiffListApplication_test - * @see DiffMessage + * @see MutationMessage * @see ui-bus.hpp */ - class DiffMessage_test + class MutationMessage_test : public Test , TreeDiffLanguage { @@ -163,7 +163,7 @@ namespace test{ CHECK (0 == instances); { - DiffMessage diffMsg{new Generator}; + MutationMessage diffMsg{new Generator}; CHECK (!isnil (diffMsg)); CHECK (1 == instances); @@ -186,7 +186,7 @@ namespace test{ // cloning is allowed, yet implementation defined // in the actual case the underlying generator is based on a vector + a pointer // and thus the full state can be cloned into an independent instance - DiffMessage clone{diffMsg}; + MutationMessage clone{diffMsg}; CHECK (clone == diffMsg); CHECK (set(ATTRIB1) == *clone); @@ -210,7 +210,7 @@ namespace test{ // So better don't do this at home... VERIFY_ERROR(ITER_EXHAUST, *diffMsg); - clone = DiffMessage{new Generator}; + clone = MutationMessage{new Generator}; CHECK (2 == instances); // now we got two independent generator instances CHECK (clone); CHECK (ins(TYPE_X) == *clone); @@ -228,9 +228,9 @@ namespace test{ void verify_builder() { - DiffMessage diffMsg{ins(TYPE_X) - ,set(ATTRIB1) - ,del(CHILD_T)}; + MutationMessage diffMsg{ins(TYPE_X) + ,set(ATTRIB1) + ,del(CHILD_T)}; CHECK (!isnil (diffMsg)); CHECK (ins(TYPE_X) == *diffMsg); @@ -242,10 +242,10 @@ namespace test{ // likewise works with a std::initializer_list - diffMsg = DiffMessage{{ins(TYPE_X) - ,set(ATTRIB1) - ,del(CHILD_T)} - }; + diffMsg = MutationMessage{{ins(TYPE_X) + ,set(ATTRIB1) + ,del(CHILD_T)} + }; CHECK (!isnil (diffMsg)); CHECK (ins(TYPE_X) == *diffMsg); @@ -256,10 +256,10 @@ namespace test{ // even passing any suitable iterable works - diffMsg = DiffMessage{snapshot({ins(TYPE_X) - ,set(ATTRIB1) - ,del(CHILD_T)}) - }; + diffMsg = MutationMessage{snapshot({ins(TYPE_X) + ,set(ATTRIB1) + ,del(CHILD_T)}) + }; CHECK (!isnil (diffMsg)); CHECK (ins(TYPE_X) == *diffMsg); @@ -276,7 +276,7 @@ namespace test{ ,set(ATTRIB1) ,del(CHILD_T)}), steps); - diffMsg = DiffMessage{steps}; + diffMsg = MutationMessage{steps}; CHECK (!isnil (diffMsg)); CHECK (ins(TYPE_X) == *diffMsg); @@ -289,9 +289,9 @@ namespace test{ void verify_diagnostics() { - DiffMessage diffMsg{ins(TYPE_X) - ,set(ATTRIB1) - ,del(CHILD_T)}; + MutationMessage diffMsg{ins(TYPE_X) + ,set(ATTRIB1) + ,del(CHILD_T)}; // initially only the default diagnostics of IterSource is shown (rendering the element type) CHECK (string(diffMsg) == "IterSource::DiffStep>"); @@ -328,7 +328,7 @@ namespace test{ - DiffMessage + MutationMessage populationDiff() { return { ins(TYPE_X) @@ -347,7 +347,7 @@ namespace test{ } - DiffMessage + MutationMessage mutationDiff() { // prepare for direct assignment of new value @@ -382,7 +382,7 @@ namespace test{ }; } - /** @test use DiffMessage to transport and apply changes to target data + /** @test use MutationMessage to transport and apply changes to target data * @remarks this almost literally repeats the DiffTreeApplication_test */ void demonstrate_treeApplication() @@ -435,7 +435,7 @@ namespace test{ /** Register this test class... */ - LAUNCHER (DiffMessage_test, "unit common"); + LAUNCHER (MutationMessage_test, "unit common"); diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index b0c81e0dc..affd1f4e2 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -866,21 +866,29 @@ - - - - + + + + + - - + + - - + + + + + - - - - + + + + + + + + @@ -902,8 +910,8 @@ - - + + @@ -920,7 +928,7 @@ - + @@ -1037,7 +1045,7 @@ - + @@ -1082,8 +1090,8 @@ - - + + @@ -1091,8 +1099,8 @@ - - + + @@ -1302,8 +1310,8 @@ - - + + @@ -10870,7 +10878,7 @@ - + @@ -10956,7 +10964,7 @@ - + @@ -11276,7 +11284,7 @@ - + @@ -12023,7 +12031,7 @@ - + @@ -14627,7 +14635,7 @@ - + @@ -16723,7 +16731,7 @@ - +