From 28d18a7326bdc2f48adc38d4b22d941271a34dc1 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 8 Jan 2015 15:13:27 +0100 Subject: [PATCH] refactoring: better name for the query focus shifting operation previously this operation was named 'attach', which an be confused with attching an object to this location. Indeed, the session interface even offers such an attach function. By renaming the focus moving operation into QueryFocus::shift(Scope), this ambiguity is resolved --- src/gui/model/session-facade.cpp | 1 + src/proc/mobject/session/query-focus.cpp | 10 +- src/proc/mobject/session/query-focus.hpp | 2 +- src/proc/mobject/session/session-impl.cpp | 2 +- .../proc/mobject/session/query-focus-test.cpp | 6 +- tests/gui/tangible-update-test.cpp | 114 ++++++++++++++++++ wiki/renderengine.html | 8 +- 7 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 tests/gui/tangible-update-test.cpp diff --git a/src/gui/model/session-facade.cpp b/src/gui/model/session-facade.cpp index 87b799301..2a457ccf7 100644 --- a/src/gui/model/session-facade.cpp +++ b/src/gui/model/session-facade.cpp @@ -26,6 +26,7 @@ ** This header defines the basics of... ** ** @note as of X/2014 this is complete bs + ** @todo THE NAME IS UNFORTUNATE!!!! "SessionFacade" should rather be a facade in Proc! ** @todo WIP ///////////////////////TICKET # ** ** @see ////TODO_test usage example diff --git a/src/proc/mobject/session/query-focus.cpp b/src/proc/mobject/session/query-focus.cpp index 5ab530589..351d1c2e8 100644 --- a/src/proc/mobject/session/query-focus.cpp +++ b/src/proc/mobject/session/query-focus.cpp @@ -51,7 +51,7 @@ namespace session { /** * @internal build a new QueryFocus - * as attached to an existing path. + * as located to an existing path. */ QueryFocus::QueryFocus(ScopePath& path_to_attach) : focus_( &path_to_attach) @@ -97,14 +97,14 @@ namespace session { - /** attach this QueryFocus to a container-like scope, + /** shift this QueryFocus to a container-like scope, * causing it to \em navigate, changing the * current ScopePath as a side-effect * @throw error::Invalid if the given container is * invalid or can't be located within the model */ QueryFocus& - QueryFocus::attach (Scope const& container) + QueryFocus::shift (Scope const& container) { ___check_validTaget (container); @@ -124,7 +124,7 @@ namespace session { ___check_validTaget (otherContainer); QueryFocus newFocus (ScopeLocator::instance().pushPath()); - newFocus.attach (otherContainer); + newFocus.shift (otherContainer); return newFocus; } @@ -138,7 +138,7 @@ namespace session { ENSURE (currentLocation.isValid()); QueryFocus newFocus (ScopeLocator::instance().pushPath()); - newFocus.attach (currentLocation); + newFocus.shift (currentLocation); return newFocus; } diff --git a/src/proc/mobject/session/query-focus.hpp b/src/proc/mobject/session/query-focus.hpp index e8fcfbc2a..35cd7c978 100644 --- a/src/proc/mobject/session/query-focus.hpp +++ b/src/proc/mobject/session/query-focus.hpp @@ -97,7 +97,7 @@ namespace session { operator Scope() const; operator string() const; - QueryFocus& attach (Scope const&); + QueryFocus& shift (Scope const&); static QueryFocus push (Scope const&); static QueryFocus push (); QueryFocus& reset (); diff --git a/src/proc/mobject/session/session-impl.cpp b/src/proc/mobject/session/session-impl.cpp index d1a73760e..decf06612 100644 --- a/src/proc/mobject/session/session-impl.cpp +++ b/src/proc/mobject/session/session-impl.cpp @@ -116,7 +116,7 @@ namespace session { , LUMIERA_ERROR_INVALID_SCOPE); QueryFocus currentFocus; - currentFocus.attach (Scope(placement).getParent()); + currentFocus.shift (Scope(placement).getParent()); contents_.clear (placement); } ENSURE (!contents_.contains (placement)); diff --git a/tests/core/proc/mobject/session/query-focus-test.cpp b/tests/core/proc/mobject/session/query-focus-test.cpp index 7c433d481..1fac93072 100644 --- a/tests/core/proc/mobject/session/query-focus-test.cpp +++ b/tests/core/proc/mobject/session/query-focus-test.cpp @@ -109,13 +109,13 @@ namespace test { // we know this object is root -> ps2 -> ps3 CHECK (Scope(focus).isRoot()); - focus.attach (someObj); + focus.shift (someObj); CHECK (!Scope(focus).isRoot()); ScopePath path = focus.currentPath(); CHECK (someObj == path.getLeaf()); CHECK (Scope(focus).getParent().getParent().isRoot()); - focus.attach (path.getLeaf().getParent()); + focus.shift (path.getLeaf().getParent()); CHECK (Scope(focus) == path.getLeaf().getParent()); CHECK (someObj != Scope(focus)); CHECK (path.contains (focus.currentPath())); @@ -153,7 +153,7 @@ namespace test { ScopeQuery::iterator ii = subF2.explore(); while (ii) // drill down depth first { - subF2.attach(*ii); + subF2.shift(*ii); cout << string(subF2) << endl; ii = subF2.explore(); } diff --git a/tests/gui/tangible-update-test.cpp b/tests/gui/tangible-update-test.cpp new file mode 100644 index 000000000..3b5755458 --- /dev/null +++ b/tests/gui/tangible-update-test.cpp @@ -0,0 +1,114 @@ +/* + SessionStructureMapping(Test) - map session structure to GUI widgets + + Copyright (C) Lumiera.org + 2014, 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 session-structure-mapping-test.cpp + ** This test is a concept study how to organise the proxy model + ** in the Lumiera GUI. This mediating model shields access to the + ** actual "high-level model" in Proc-Layer, it translates signals + ** into command invocations and helps to push structure changes + ** up to the timeline display. + ** + ** @note as of 10/2014 this is a initial draft into the blue... + ** @todo WIP ///////////////////////TICKET #955 + ** @todo WIP ///////////////////////TICKET #961 + ** + ** @see gui::model::SessionFacade + ** + */ + + +#include "lib/test/run.hpp" +#include "gui/model/session-facade.hpp" +#include "gui/model/diagnostics.hpp" +//#include "lib/util.hpp" + + +//#include +//#include +//#include +//#include + +//using boost::lexical_cast; +//using util::contains; +//using std::string; +//using std::cout; +//using std::endl; + + +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 SessionStructureMapping_test : public Test + { + + virtual void + run (Arg) + { + gui::model::Diagnostics lock(TEST_SESSION_1); + retrieveSessionStructure(); + } + + + /** @test how to retrieve and enumerate session contents + * as operation initiated from GUI display code + */ + void + retrieveSessionStructure () + { + + } + + }; + + + /** Register this test class... */ + LAUNCHER (SessionStructureMapping_test, "unit gui"); + + +}}} // namespace gui::model::test diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 057bb99b2..d10264e61 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -4895,11 +4895,11 @@ For the initial version of the implementation, just storing a string in Prolog s !handling of queries Queries are are always exposed or revealed at some point or facility allowing to pose queries. This facility remains the owner of the query instances and knows its concrete flavour (type). But queries can be referred to and exchanged through the {{{Query<TY>}}}-abstraction. -
+
When querying contents of the session or sub-containers within the session, the QueryFocus follows the current point-of-query. As such queries can be issued to explore the content of container-like objects holding other MObjects, the focus is always attached to a container, which also acts as [[scope|PlacementScope]] for the contained objects. QueryFocus is an implicit state (the current point of interrest). This sate especially remembers the path down from the root of the HighLevelModel, which was used to access the current scope. Because this path constitutes a hierarchy of scopes, it can be relevant for querying and resolving placement properties. (&rarr; SessionStructureQuery)
 
 !provided operations
-* attach to a given scope-like object. Causes the current focus to //navigate//
+* shift to a given scope-like object. Causes the current focus to //navigate//
 * open a new focus, thereby pushing the existing focus onto a [[focus stack|QueryFocusStack]]
 * return (pop) to the previous focus
 * get the current scope, represented by the "top" Placement of this scope
@@ -5586,7 +5586,7 @@ The session and the models rely on dependent objects beeing kept updated and con
 &rarr; see [[details here...|ModelDependencies]]
 
-
+
"Session Interface", when used in a more general sense, denotes a compound of several interfaces and facilities, together forming the primary access point to the user visible contents and state of the editing project.
 * the API of the session class
 * the accompanying management interface (SessionManager API)
@@ -5656,7 +5656,7 @@ When adding an object, a [[scope|PlacementScope]] needs to be specified. Thus it
 * how is all of this related to the LayerSeparationInterfaces, here SessionFacade und EditFacade?
 
 <<<
-__preliminary notes__: {{red{3/2010}}} Discovery functions accessible from the session API are always written such as to return ~MObjectRefs. These expose generic functions for modifying the structure: {{{attach(MObjectRef)}}} and {{{purge()}}}. The session API exposes variations of these functions. Actually, all these functions do dispatch the respective commands automatically. To the contrary, the raw functions for adding and removing placements are located on the PlacementIndex; they are accessible as SessionServices &mdash; which are intended for Proc-Layer's internal use solely. This separation isn't meant to be airtight, just an reminder for proper use.
+__preliminary notes__: {{red{3/2010}}} Discovery functions accessible from the session API are always written such as to return ~MObjectRefs. These expose generic functions for modifying the structure: {{{attach(MObjectRef)}}} and {{{purge()}}}. The session API exposes variations of these functions. Actually, all these functions do dispatch the respective commands automatically. {{red{Note 1/2015 not implemented, not sure if thats a good idea}}} To the contrary, the raw functions for adding and removing placements are located on the PlacementIndex; they are accessible as SessionServices &mdash; which are intended for Proc-Layer's internal use solely. This separation isn't meant to be airtight, just an reminder for proper use.
 
 Currently, I'm planning to modify MObjectRef to return only a const ref to the underlying facilities by default. Then, there would be a subclass which is //mutation enabled.// But this subclass will check for the presence of a mutation-permission token &mdash; which is exposed via thread local storage, but //only within a command dispatch.// Again, no attempt is made to make this barrier airtight. Indeed, for tests, the mutation-permission token can just be created in the local scope. After all, this is not conceived as an authorisation scheme, rather as a automatic sanity check. It's the liability of the client code to ensure any mutation is dispatched.
 <<<