planning the access structure to session content

initial considerations; there is a concurrency problem, since
all of session handling within Proc is deliberately not threadsafe.
Thus the decision is to make this the gui::model::SessionFacade's responsibility
This commit is contained in:
Fischlurch 2014-10-19 05:54:20 +02:00
parent 1c0e86d373
commit 41a711120c
5 changed files with 245 additions and 5 deletions

View file

@ -0,0 +1,120 @@
/*
DIAGNOSTICS.hpp - helper for verifying the GUI-session connection
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 diagnostics.hpp
** Service for diagnostics.
** This header defines the basics of...
**
** @note as of X/2014 this is complete bs
** @todo WIP ///////////////////////TICKET #
**
** @see ////TODO_test usage example
** @see diagnostics.cpp implementation
**
*/
#ifndef GUI_MODEL_DIAGNOSTICS_H_
#define GUI_MODEL_DIAGNOSTICS_H_
#include "lib/error.hpp"
//#include "lib/symbol.hpp"
//#include "lib/util.hpp"
#include <boost/noncopyable.hpp>
//#include <string>
namespace gui {
namespace model {
// using util::isnil;
// using std::string;
enum ProbeMode {
TEST_SESSION_1
};
/**
* Basic (abstracted) view of...
*
* @see SomeSystem
* @see NA_test
*/
class Diagnostics
: boost::noncopyable
{
public:
explicit
Diagnostics (ProbeMode m)
{ }
~Diagnostics()
{
}
/* == Adapter interface for == */
void
setSolution (string const& solution ="")
{
UNIMPLEMENTED ("tbw");
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
if (isDeaf())
this->transmogrify (solution);
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
}
protected:
void maybe () const;
};
/** @internal in case
*/
inline void
Diagnostics::maybe () const
{
UNIMPLEMENTED ("tbw");
}
}} // namespace gui::model
#endif /*GUI_MODEL_DIAGNOSTICS_H_*/

View file

@ -78,6 +78,11 @@ namespace model {
protected:
string maybe () const;
void lock_to_TestContent();
void releaseTestMode();
friend class Diagnostics;
};

View file

@ -55,7 +55,7 @@
** \par placement scopes
** When adding a Placement to the index, it is mandatory to specify a Scope: this is
** another Placement already registered within the index; the new Placement can be thought
** off as being located "within" or "below" this scope-defining reference Placement. An
** of as being located "within" or "below" this scope-defining reference Placement. An
** typical example would be the addition of a \c Placement<session::Clip>, specifying
** a \c Placement<session::Track> as scope. Thus, all "object instances" within the
** session are arranged in a tree-like fashion. On creation of the PlacementIndex,

View file

@ -0,0 +1,112 @@
/*
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
**
** @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

View file

@ -2280,13 +2280,16 @@ Thus, the Proc-Layer exposes (one or several) facade interfaces for the GUI to u
Probably the most important aspect regarding the GUI integration is how to get [[access to and operate on the Session|SessionInterface]]. More specifically, this includes [[referring to individual objects|MObjectRef]]. On top of these generic access mechanisms, we create a [[proxy GUI model|GuiModel]] for binding. The interface of this GUI model is tailored for display and translation into UI entities.</pre>
</div>
<div title="GuiModel" creator="Ichthyostega" modifier="Ichthyostega" created="201410170142" tags="GuiIntegration design draft" changecount="1">
<div title="GuiModel" creator="Ichthyostega" modifier="Ichthyostega" created="201410170142" modified="201410190352" tags="GuiIntegration design draft" changecount="3">
<pre>Building a layered architecture is a challenge, since the lower layer //really// needs to be self-contained, while prepared for usage by the higher layer.
A major fraction of all desktop applications is written in a way where operational logic is built around the invocation from UI events -- what should be a shell turns into a backbone. One possible way to escape from this common anti pattern is to introduce a mediating entity, to translate between two partially incompatible demands and concerns: Sure, the &quot;tangible stuff&quot; is what matters, but you can not build any significant piece of technology if all you want is to &quot;serve&quot; the user.
Within the Lumiera GTK GUI, we use a proxying model as a mediating entity. It is based upon the ''generic aspect'' of the SessionInterface, but packaged and conditioned in a way to allow a direct mapping of GUI entities on top. The widgets in the GUI can be conceived as decorating this model. Callbacks can be wired back, allowing to transform UI events into a stream of commands for the Proc-Layer sitting below.
The GUI model is largely comprised of immutable ID elements, which can be treated as values. A mutated model configuration in Proc-Layer is pushed upwards as a new structure to be consumed by the GUI widgets; it is broken into parts while being consumed -- leaving it to the leaf widgets to adapt themselves to reflect the new situation.</pre>
The GUI model is largely comprised of immutable ID elements, which can be treated as values. A mutated model configuration in Proc-Layer is pushed upwards as a new structure to be consumed by the GUI widgets; it is broken into parts while being consumed -- leaving it to the leaf widgets to adapt themselves to reflect the new situation.
!synchronisation guarantees
We acknowledge that the gui model is typically used from within the GUI event dispatch thread. This is //not// the thread where any session state is mutated. Thus it is the repsonsibility of this proxying model within the GUI to ensure that the retrieved structure is a coherent snapshot of the session state. Especially the {{{gui::model::SessionFacade}}} ensures that there was a read barrier between the state retrieval and any preceding mutation command. Actually, this is implemented down in Proc-Layer, with the help of the ProcDispatcher.</pre>
</div>
<div title="GuiNotificationFacade" modifier="Ichthyostega" created="200902080659" tags="spec">
<pre>LayerSeparationInterface provided by the GUI.
@ -5349,8 +5352,8 @@ ScopePath represents an ''effective scoping location'' within the model &amp;mda
** clear a path (reset to default)
</pre>
</div>
<div title="ScopeTrigger" modifier="Ichthyostega" created="201006132139" modified="201006132140" tags="SessionLogic impl draft">
<pre>An implementation mechanism used within the PlacementIndex to detect some specific kinds of object connections(&amp;raquoMagicAttachment&amp;laquo;), which then need to trigger a special handling.
<div title="ScopeTrigger" modifier="Ichthyostega" created="201006132139" modified="201410190030" tags="SessionLogic impl draft" changecount="1">
<pre>An implementation mechanism used within the PlacementIndex to detect some specific kinds of object connections(&amp;raquo;MagicAttachment&amp;laquo;), which then need to trigger a special handling.
{{red{planned feature as of 6/2010)}}}