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
This commit is contained in:
parent
7bd3eafd46
commit
28d18a7326
7 changed files with 129 additions and 14 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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<TestSubMO21>::iterator ii = subF2.explore<TestSubMO21>();
|
||||
while (ii) // drill down depth first
|
||||
{
|
||||
subF2.attach(*ii);
|
||||
subF2.shift(*ii);
|
||||
cout << string(subF2) << endl;
|
||||
ii = subF2.explore<TestSubMO21>();
|
||||
}
|
||||
|
|
|
|||
114
tests/gui/tangible-update-test.cpp
Normal file
114
tests/gui/tangible-update-test.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
SessionStructureMapping(Test) - map session structure to GUI widgets
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2014, 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 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 <boost/lexical_cast.hpp>
|
||||
//#include <iostream>
|
||||
//#include <string>
|
||||
//#include <map>
|
||||
|
||||
//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
|
||||
|
|
@ -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.</pre>
|
||||
</div>
|
||||
<div title="QueryFocus" modifier="Ichthyostega" created="200910140244" modified="201006190505" tags="def spec img">
|
||||
<div title="QueryFocus" modifier="Ichthyostega" created="200910140244" modified="201501081405" tags="def spec img" changecount="1">
|
||||
<pre>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]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="SessionInterface" modifier="Ichthyostega" created="200904242108" modified="201402162033" tags="SessionLogic GuiIntegration design draft discuss" changecount="1">
|
||||
<div title="SessionInterface" modifier="Ichthyostega" created="200904242108" modified="201501081350" tags="SessionLogic GuiIntegration design draft discuss" changecount="2">
|
||||
<pre>"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.
|
||||
<<<
|
||||
|
|
|
|||
Loading…
Reference in a new issue