ViewSpec: analysis of design alternatives
looks like I'm trapped with the choice between a convoluted API design and an braindead and inefficient implementation. I am leaning towards the latter
This commit is contained in:
parent
f55a8f606b
commit
2e8bc9227a
3 changed files with 140 additions and 31 deletions
|
|
@ -96,16 +96,15 @@ namespace model {
|
|||
virtual ~ElementAccess () { } ///< this is an interface
|
||||
|
||||
|
||||
template<class TAR>
|
||||
using Result = lib::Result<TAR>;
|
||||
|
||||
/* == Access by Location == */
|
||||
|
||||
template<class TAR>
|
||||
Result<TAR&> access (UICoord const& destination);
|
||||
lib::Result<TAR&> access (UICoord const& destination);
|
||||
|
||||
template<class TAR>
|
||||
Result<TAR&> access_or_create (UICoord const& destination, size_t limitCreation = LUMIERA_MAX_ORDINAL_NUMBER);
|
||||
lib::Result<TAR&> access_or_create (UICoord const& destination, size_t limitCreation = LUMIERA_MAX_ORDINAL_NUMBER);
|
||||
|
||||
UICoord allocate (UICoord const& destination, size_t limitCreation = LUMIERA_MAX_ORDINAL_NUMBER);
|
||||
|
||||
|
||||
protected:
|
||||
|
|
@ -142,7 +141,7 @@ namespace model {
|
|||
struct ElementAccess::TypeConverter
|
||||
: RawResult::Visitor
|
||||
{
|
||||
Result<TAR&> result{"not convertible"};
|
||||
lib::Result<TAR&> result{"not convertible"};
|
||||
|
||||
template<typename X> // note the "backward" use. We pick that base interface
|
||||
using canUpcast = std::is_convertible<TAR*, X>; // into which our desired result type can be upcast, because
|
||||
|
|
@ -155,7 +154,7 @@ namespace model {
|
|||
if (pb)
|
||||
result = *dynamic_cast<TAR*> (pb);
|
||||
else
|
||||
result = Result<TAR&>{"access returns empty answer"};
|
||||
result = lib::Result<TAR&>{"access returns empty answer"};
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -173,7 +172,7 @@ namespace model {
|
|||
* and convertible to `bool(false)`
|
||||
*/
|
||||
template<class TAR>
|
||||
inline ElementAccess::Result<TAR&>
|
||||
inline lib::Result<TAR&>
|
||||
ElementAccess::access (UICoord const& destination)
|
||||
{
|
||||
return access_or_create<TAR> (destination, 0);
|
||||
|
|
@ -188,7 +187,7 @@ namespace model {
|
|||
* and convertible to `bool(false)` (or raises an exception on attempted access)
|
||||
*/
|
||||
template<class TAR>
|
||||
inline ElementAccess::Result<TAR&>
|
||||
inline lib::Result<TAR&>
|
||||
ElementAccess::access_or_create (UICoord const& destination, size_t limitCreation)
|
||||
{
|
||||
TypeConverter<TAR> converter;
|
||||
|
|
|
|||
|
|
@ -9917,7 +9917,7 @@ In addition to querying the interpretation of a given coordinate spec with respe
|
|||
__Navigation mutations:__ //In theory,// it would even be possible to extend the path by creating suitable child components; but actually this would require all "elements" to implement a suitable mutation interface -- which in the case of //generic elements// might be far beyond the common ground. For this reason, we keep mutation of the backing environment outside of a path mutator's scope and rather keep mutation limited to the path itself.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="UILowLevelAccess" creator="Ichthyostega" modifier="Ichthyostega" created="201804062255" modified="201804150051" tags="spec draft GuiPattern" changecount="4">
|
||||
<div title="UILowLevelAccess" creator="Ichthyostega" modifier="Ichthyostega" created="201804062255" modified="201806142339" tags="spec draft GuiPattern" changecount="7">
|
||||
<pre>//Cross cutting access to elementary UI structures.//
|
||||
We have several orthogonal identification and access schemes within the UI. A naively written UI application just attaches the core logic below some widgets and controllers -- not only does this lead to a hard to maintain code base, this approach is even outright impossible in our case, due to the strict decoupling between core and GUI, which places us into the situation to connect a self contained core with a self contained UI. This is a binding, which, as a sideline, also generates a control structure of its own. We can indeed write code dealing with a generic UI element -- but there needs to be some place where this kind of generic designation is translated into internal structures of the UI toolkit (GTK in our case), to obtain a direct (language) reference to some implementation widget finally.
|
||||
|
||||
|
|
@ -9930,6 +9930,9 @@ At the time of this writing, it is not really clear if we need such a facility a
|
|||
* so effectively an access request will drill down the real UI topology, following the path of the given UI Coordinates.
|
||||
* the result can then be packaged into a {{{lib::Variant}}} and use a //variant visitor// (double dispatch) to invoke the apropriate {{{dynamic_cast}}}
|
||||
* together, this mechanism allows us to return direct language references to actual implementation widgets
|
||||
|
||||
!Extend UICoord to an opaque concrete {{{UILocation}}} handle?
|
||||
This is a possible different turn in the design, considered as an option {{red{as of 6/2018}}}. Such would complement a symbolic coordinate specification with an opaque handle pointing to an actually existing UI widget. Access to this widget requires knowledge about its actual type -- basically a variant record tacked onto the UICoord representation, packaged into a subclass of the latter. The obvious benefit would be to avoid drilling down into the UI widget tree repeatedly, since there is now a way to pass along hidden //insider information// regarding actual UI elements. However, such a design bears a "smell" of being implementation driven, and undercuts the whole idea of a entirely symbolic layer of location specifications. Building such an extension can be considered sensible only under the additional assumption that this kind of //location token// is to be passed over various interfaces and indeed becomes a generic token of exchange and interaction within the UI layer implementation -- which, right now is not a given.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="ViewConnection" modifier="Ichthyostega" created="201105221854" modified="201501091154" tags="def Model SessionLogic" changecount="3">
|
||||
|
|
|
|||
|
|
@ -11474,36 +11474,19 @@
|
|||
<node CREATED="1525567420608" ID="ID_1865194597" MODIFIED="1525567450407" TEXT="erscheint sinnvoll vom API her">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node CREATED="1525567432127" ID="ID_1190994966" MODIFIED="1525567453224" TEXT="aber dämlich von der Implementierung her">
|
||||
<node CREATED="1525567432127" ID="ID_1190994966" MODIFIED="1528992332480" TEXT="aber dämlich in der Implementierung">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1525567474513" HGAP="136" ID="ID_492657286" MODIFIED="1528988453047" TEXT="ElementAccess-API umbauen" VSHIFT="5">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1529016810234" ID="ID_190701762" MODIFIED="1529016835751" TEXT="Möglichkeiten">
|
||||
<node CREATED="1528988155980" ID="ID_425314989" MODIFIED="1528988170052" TEXT="Variante-1">
|
||||
<icon BUILTIN="full-1"/>
|
||||
<node CREATED="1528988234950" ID="ID_1668042554" MODIFIED="1528988252512" TEXT="UI-Coord zurückliefern"/>
|
||||
<node CREATED="1528988289119" ID="ID_1881432398" MODIFIED="1528988440865" TEXT="tricky conversion">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...wenn ich es irgendwie schaffe,
|
||||
</p>
|
||||
<p>
|
||||
doch auch noch UI-Coord als Rückgabewert
|
||||
</p>
|
||||
<p>
|
||||
da "hineinzuwürgen"...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1528988263818" ID="ID_480404928" MODIFIED="1528988286380" TEXT="Element-Cache"/>
|
||||
<node CREATED="1528988263818" ID="ID_480404928" MODIFIED="1529016940289" TEXT="Element-Cache?"/>
|
||||
<node CREATED="1529016904083" ID="ID_1517114370" MODIFIED="1529016934839" TEXT="API erweitern"/>
|
||||
</node>
|
||||
<node CREATED="1528988317699" ID="ID_1560503454" MODIFIED="1528988323954" TEXT="Variante-2 ">
|
||||
<icon BUILTIN="full-2"/>
|
||||
|
|
@ -11512,6 +11495,130 @@
|
|||
<node CREATED="1528988379946" ID="ID_131306130" MODIFIED="1528988391702" TEXT="brauche anderweitige Abstraktion"/>
|
||||
<node CREATED="1528988369596" ID="ID_1174830872" MODIFIED="1528988376583" TEXT="Allokator erzeugt anderweitig"/>
|
||||
</node>
|
||||
<node CREATED="1529016988678" ID="ID_1209500762" MODIFIED="1529016994968" TEXT="Variante-3">
|
||||
<icon BUILTIN="full-3"/>
|
||||
<node CREATED="1529017028938" ID="ID_359770283" MODIFIED="1529017068647" TEXT="Opaque Location Representation"/>
|
||||
<node CREATED="1529017070019" ID="ID_57519695" MODIFIED="1529017101538" TEXT="Allocator-API darauf umstellen"/>
|
||||
<node CREATED="1529017279135" ID="ID_707219104" MODIFIED="1529017285322" TEXT="(down)cast-Mechanismus"/>
|
||||
</node>
|
||||
<node CREATED="1529018080237" ID="ID_776753961" MODIFIED="1529018319679" TEXT="Variante-3b">
|
||||
<icon BUILTIN="full-4"/>
|
||||
<node CREATED="1529018093267" ID="ID_389715312" MODIFIED="1529018099078" TEXT="Hybrid-Lösung"/>
|
||||
<node CREATED="1529018100234" ID="ID_1628139323" MODIFIED="1529018119792">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
als <i>Subklasse</i> von UICoord
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1529018125015" ID="ID_740978949" MODIFIED="1529018137465" TEXT="fügt den Variant-Record und den Konverter hinzu"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1529016854248" ID="ID_1664191705" MODIFIED="1529016857972" TEXT="Abwägung">
|
||||
<node CREATED="1529016871262" ID="ID_957194065" MODIFIED="1529017825322" TEXT="Variante-2 verschiebt das Problem">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn das eigentliche Problem ist,
|
||||
</p>
|
||||
<p>
|
||||
daß ich noch keinerlei Implementierung schreiben kann.
|
||||
</p>
|
||||
<p>
|
||||
Mithin schiebe ich mir Platzhalter von der linken in die rechte Tasche
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1529017693432" ID="ID_70956393" MODIFIED="1529018209759" TEXT="Variante-3 verwendet zwei Repräsentationen für die gleiche Sache">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
und zwar für die abstrahierte GUI-Location
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
einmal symbolisch als UI-Koordinaten
|
||||
</li>
|
||||
<li>
|
||||
einmal opaque als eingekapselte Lösung
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Und sowas ist verwirrend und verlockt gradezu, die Schachtel aufzumachen
|
||||
</p>
|
||||
<p>
|
||||
und an der Implementierung zu kleben
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1529018409007" ID="ID_1460094266" MODIFIED="1529018714798" TEXT="Variante-3b wäre nur interessant als eigenständige Entität">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...was <i>bis jetzt</i> nicht gegeben ist!
|
||||
</p>
|
||||
<p>
|
||||
Bis jetzt haben wir einen "Durchlauf-Erhitzer": letztlich will man nur die Referenz
|
||||
</p>
|
||||
<p>
|
||||
auf das GUI-Element haben, und die dazwischenliegende symbolische Schicht
|
||||
</p>
|
||||
<p>
|
||||
dient nur der Konfiguration und Lösungs-Suche.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Wenn allerdings später mal diese <b>UILocation</b> == bereits decodierte UI-Koordinaten
|
||||
</p>
|
||||
<p>
|
||||
ein eigenständiges Token wird, welches über mehrere Schnittstellen hinweg geschoben wird,
|
||||
</p>
|
||||
<p>
|
||||
<i>dann und nur dann</i> würde die zusätzliche API-Komplexität Sinn machen.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1529019621707" ID="ID_537306231" MODIFIED="1529019680878" STYLE="fork" TEXT="Beschluß">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<node CREATED="1529019899294" ID="ID_514740736" MODIFIED="1529019930053" TEXT="Variante-3b wird als Option für später festgehalten"/>
|
||||
<node CREATED="1529019931210" ID="ID_963819454" MODIFIED="1529019961969" TEXT="Variante-1 mit API-Erweiterung ist naheliegend"/>
|
||||
<node CREATED="1529019962989" ID="ID_1964052993" MODIFIED="1529019985410">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
die <b>verfickte</b> Performance wird ignoriert
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1523752571241" ID="ID_1806352950" MODIFIED="1523752593134" TEXT="Anzahl Instanzen herausfinden">
|
||||
|
|
|
|||
Loading…
Reference in a new issue