ViewSpec: recast the ElementAccess API to work around the design problem

...it is not really solved, rather postponed.
But who knows. Maybe it's already good enough...
This commit is contained in:
Fischlurch 2018-06-15 16:42:51 +02:00
parent 2e8bc9227a
commit 800fc5915a
6 changed files with 85 additions and 63 deletions

View file

@ -83,7 +83,7 @@ namespace ctrl{
/* == ElementAccess interface == */
RawResult
performAccessTo (UICoord const&, size_t limitCreation) override
performAccessTo (UICoord::Builder & target, size_t limitCreation) override
{
UNIMPLEMENTED ("implementation of access function based on real UI widgets");
}

View file

@ -522,6 +522,14 @@ namespace interact {
size_t size() const { return uic_.size(); }
bool empty() const { return uic_.empty();}
/** @warning exposes transient state,
* not normalised. */
UICoord const&
uiCoord()
{
return uic_;
}
/* == Builder functions == */

View file

@ -101,17 +101,14 @@ namespace model {
template<class TAR>
lib::Result<TAR&> access (UICoord const& destination);
template<class TAR>
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);
UICoord locate_or_create (UICoord const& destination, size_t limitCreation = LUMIERA_MAX_ORDINAL_NUMBER);
protected:
using RawResult = lib::Variant<Types<model::Tangible*, Gtk::Widget*>>;
/** @internal drill down according to coordinates, maybe create element */
virtual RawResult performAccessTo (UICoord const&, size_t limitCreation) =0;
virtual RawResult performAccessTo (UICoord::Builder &, size_t limitCreation) =0;
private:
template<class TAR>
@ -141,7 +138,7 @@ namespace model {
struct ElementAccess::TypeConverter
: RawResult::Visitor
{
lib::Result<TAR&> result{"not convertible"};
lib::Result<TAR&> result{"not convertible to desired target widget"};
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
@ -152,7 +149,11 @@ namespace model {
handle (Base& pb) override
{
if (pb)
result = *dynamic_cast<TAR*> (pb);
{
TAR* downcasted = dynamic_cast<TAR*> (pb);
if (downcasted)
result = *downcasted;
}
else
result = lib::Result<TAR&>{"access returns empty answer"};
}
@ -175,25 +176,25 @@ namespace model {
inline lib::Result<TAR&>
ElementAccess::access (UICoord const& destination)
{
return access_or_create<TAR> (destination, 0);
UICoord::Builder targetLocation{destination.rebuild()};
TypeConverter<TAR> converter;
RawResult targetElm = performAccessTo (targetLocation, 0);
targetElm.accept (converter);
return converter.result;
}
/** Navigate to the designated component, possibly create the element and parents
* @return suitably converted direct (language) reference to the desired element
* wrapped as _result proxy_
* @return location of the actual element to use, as UI-coordinates.
* @note when access was not possible because the element could not been created,
* or is not convertible to the desired target type, the result proxy is empty,
* and convertible to `bool(false)` (or raises an exception on attempted access)
* the indicated location returned is an _empty coordinate spec._
*/
template<class TAR>
inline lib::Result<TAR&>
ElementAccess::access_or_create (UICoord const& destination, size_t limitCreation)
inline UICoord
ElementAccess::locate_or_create (UICoord const& destination, size_t limitCreation)
{
TypeConverter<TAR> converter;
RawResult targetElm = performAccessTo (destination, limitCreation);
targetElm.accept (converter);
return converter.result;
UICoord::Builder targetLocation{destination.rebuild()};
performAccessTo (targetLocation, limitCreation);
return targetLocation;
}

View file

@ -51,25 +51,14 @@ using lib::diff::Rec;
//using util::isnil;
namespace gui {
namespace gui {
namespace idi { //------Mock ViewSpec definitions for component test
struct MockView1
: gui::test::DummyWidget
{
using DummyWidget::DummyWidget;
};
struct MockView2
: gui::test::DummyWidget
{
using DummyWidget::DummyWidget;
};
/* ==== Dummy ViewSpec rules for those two mock view types (--> see id-scheme.hpp) ==== */
template<>
struct Descriptor<MockView1>
struct Descriptor<test::DummyView>
{
ViewSpec locate = UICoord::currentWindow().panel("parentLocation");
Allocator alloc = limitAllocation(2);
@ -222,12 +211,11 @@ namespace test {
//--------------------------------------------------------------Staging: Testcase-1
using idi::MockView1;
fakeAccessor->existingPath = UICoord{"win-1","perspective","parentLocation"};
CHECK (not fakeAccessor->response); // not yet created
//--------------------------------------------------------------Staging: Testcase-1
MockView1& view1 = viewLocator.get<MockView1>();
DummyView& view1 = viewLocator.get<DummyView>();
cout << "created view:" << view1.getID() << endl;
/////////////////////////////////////////////TICKET 1129 : some way to verify the last allocated path. Should be a child of "parentLocation"

View file

@ -125,18 +125,20 @@ namespace test {
/* == ElementAccess interface == */
RawResult
performAccessTo (UICoord const& target, size_t limitCreation) override
performAccessTo (UICoord::Builder & target, size_t limitCreation) override
{
CHECK (existingPath >= target);
if (existingPath > target and !response)
UICoord const& location = target.uiCoord();
CHECK (existingPath >= location);
if (existingPath > location and !response)
{
if (target.leafLevel() == UIC_VIEW)
response.reset(new DummyView(target[UIC_VIEW]));
if (location.leafLevel() == UIC_VIEW)
response.reset(new DummyView(location[UIC_VIEW]));
else
if (target.leafLevel() == UIC_TAB)
response.reset(new DummyTab(target[UIC_TAB]));
if (location.leafLevel() == UIC_TAB)
response.reset(new DummyTab(location[UIC_TAB]));
else
throw error::Invalid("Mock ElementAccess supports only creation of VIEW and TAB. Requested Target was "+string(target));
throw error::Invalid("Mock ElementAccess supports only creation of VIEW and TAB. Requested Target was "+string(location));
}
return response.get();

View file

@ -11451,14 +11451,14 @@
<node CREATED="1515634282345" ID="ID_788516837" MODIFIED="1518487921071" TEXT="kl&#xe4;ren, wer sie umsetzt">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1523752547477" ID="ID_1121433532" MODIFIED="1523752551764" TEXT="limitAllocation">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1523752559939" ID="ID_597346628" MODIFIED="1525564300862" TEXT="umsetzen auf ElementAccess-API">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1523752547477" ID="ID_1121433532" MODIFIED="1529073662084" TEXT="limitAllocation">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1523752559939" ID="ID_597346628" MODIFIED="1529073653822" TEXT="umsetzen auf ElementAccess-API">
<linktarget COLOR="#97cad5" DESTINATION="ID_597346628" ENDARROW="Default" ENDINCLINATION="126;9;" ID="Arrow_ID_89575203" SOURCE="ID_1979012219" STARTARROW="None" STARTINCLINATION="567;-16;"/>
<icon BUILTIN="flag-yellow"/>
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1525567190247" ID="ID_42079899" MODIFIED="1525567200526" TEXT="Problem: API noch nicht vollst&#xe4;ndig">
<icon BUILTIN="flag-pink"/>
<node COLOR="#338800" CREATED="1525567190247" ID="ID_42079899" MODIFIED="1529073619928" TEXT="Problem: API noch nicht vollst&#xe4;ndig">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1525567207940" HGAP="76" ID="ID_1154047307" MODIFIED="1525567222800" TEXT="wirklich zwei Zugriffe?" VSHIFT="-9">
<icon BUILTIN="help"/>
<node CREATED="1525567242728" ID="ID_408728922" MODIFIED="1525567256385" TEXT="Finden / Allozieren">
@ -11479,8 +11479,8 @@
</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 COLOR="#338800" CREATED="1525567474513" HGAP="136" ID="ID_492657286" MODIFIED="1529073647301" TEXT="ElementAccess-API umbauen" VSHIFT="5">
<icon BUILTIN="button_ok"/>
<node CREATED="1529016810234" ID="ID_190701762" MODIFIED="1529016835751" TEXT="M&#xf6;glichkeiten">
<node CREATED="1528988155980" ID="ID_425314989" MODIFIED="1528988170052" TEXT="Variante-1">
<icon BUILTIN="full-1"/>
@ -11519,7 +11519,7 @@
<node CREATED="1529018125015" ID="ID_740978949" MODIFIED="1529018137465" TEXT="f&#xfc;gt den Variant-Record und den Konverter hinzu"/>
</node>
</node>
<node CREATED="1529016854248" ID="ID_1664191705" MODIFIED="1529016857972" TEXT="Abw&#xe4;gung">
<node CREATED="1529016854248" HGAP="37" ID="ID_1664191705" MODIFIED="1529073423992" TEXT="Abw&#xe4;gung" VSHIFT="5">
<node CREATED="1529016871262" ID="ID_957194065" MODIFIED="1529017825322" TEXT="Variante-2 verschiebt das Problem">
<richcontent TYPE="NOTE"><html>
<head>
@ -11536,8 +11536,7 @@
Mithin schiebe ich mir Platzhalter von der linken in die rechte Tasche
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1529017693432" ID="ID_70956393" MODIFIED="1529018209759" TEXT="Variante-3 verwendet zwei Repr&#xe4;sentationen f&#xfc;r die gleiche Sache">
<richcontent TYPE="NOTE"><html>
@ -11563,8 +11562,7 @@
und an der Implementierung zu kleben
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1529018409007" ID="ID_1460094266" MODIFIED="1529018714798" TEXT="Variante-3b w&#xe4;re nur interessant als eigenst&#xe4;ndige Entit&#xe4;t">
<richcontent TYPE="NOTE"><html>
@ -11597,14 +11595,14 @@
<i>dann und nur dann</i>&#160;w&#252;rde die zus&#228;tzliche API-Komplexit&#228;t Sinn machen.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1529019621707" ID="ID_537306231" MODIFIED="1529019680878" STYLE="fork" TEXT="Beschlu&#xdf;">
<font NAME="SansSerif" SIZE="12"/>
<node CREATED="1529019899294" ID="ID_514740736" MODIFIED="1529019930053" TEXT="Variante-3b wird als Option f&#xfc;r sp&#xe4;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">
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1529019621707" ID="ID_537306231" MODIFIED="1529065532539" TEXT="Beschlu&#xdf;">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
<node CREATED="1529019899294" ID="ID_514740736" MODIFIED="1529065532532" TEXT="Variante-3b wird als Option f&#xfc;r sp&#xe4;ter festgehalten"/>
<node CREATED="1529019931210" ID="ID_963819454" MODIFIED="1529065532532" TEXT="Variante-1 mit API-Erweiterung ist naheliegend"/>
<node CREATED="1529019962989" ID="ID_1964052993" MODIFIED="1529065532532">
<richcontent TYPE="NODE"><html>
<head>
@ -11614,9 +11612,34 @@
die <b>verfickte</b>&#160;Performance wird ignoriert
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1529073415777" HGAP="19" ID="ID_834523571" MODIFIED="1529073575521" TEXT="L&#xf6;sung" VSHIFT="12">
<icon BUILTIN="button_ok"/>
<node CREATED="1529073429723" ID="ID_100395564" MODIFIED="1529073437526" TEXT="Funktion locate_or_create()">
<node CREATED="1529073456407" ID="ID_838325275" MODIFIED="1529073466881" TEXT="macht Zugriff und erzeugt ggfs neu"/>
<node CREATED="1529073467710" ID="ID_149127263" MODIFIED="1529073477217" TEXT="gibt UICoord::Builder nach unten"/>
<node CREATED="1529073477988" ID="ID_1842592627" MODIFIED="1529073484271" TEXT="dieser wird dort ggfs umgeschrieben"/>
<node CREATED="1529073485027" ID="ID_1766613398" MODIFIED="1529073496141" TEXT="gibt nur UICoord zur&#xfc;ck"/>
</node>
<node CREATED="1529073497945" ID="ID_1104671546" MODIFIED="1529073502069" TEXT="Funktion access()">
<node CREATED="1529073503466" ID="ID_1047392798" MODIFIED="1529073510052" TEXT="darf niemals neu erzeugen"/>
<node CREATED="1529073510904" ID="ID_403151375" MODIFIED="1529073549243" TEXT="navigiert den vorbereiten Pfad nochmal hinunter">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
....jaaaaa, das ist verschwenderisch
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1529073559905" ID="ID_1370869277" MODIFIED="1529073571068" TEXT="liefert nun aber den verpackten Ergebnis-Zeiger"/>
</node>
</node>
</node>