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:
parent
1c0e86d373
commit
41a711120c
5 changed files with 245 additions and 5 deletions
120
src/gui/model/diagnostics.hpp
Normal file
120
src/gui/model/diagnostics.hpp
Normal 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_*/
|
||||
|
|
@ -78,6 +78,11 @@ namespace model {
|
|||
|
||||
protected:
|
||||
string maybe () const;
|
||||
|
||||
void lock_to_TestContent();
|
||||
void releaseTestMode();
|
||||
|
||||
friend class Diagnostics;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
112
tests/gui/session-structure-mapping-test.cpp
Normal file
112
tests/gui/session-structure-mapping-test.cpp
Normal 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
|
||||
|
|
@ -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 "tangible stuff" is what matters, but you can not build any significant piece of technology if all you want is to "serve" 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 &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(&raquoMagicAttachment&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(&raquo;MagicAttachment&laquo;), which then need to trigger a special handling.
|
||||
|
||||
{{red{planned feature as of 6/2010)}}}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue