LocationSolver: draft outline of the solving loop

This commit is contained in:
Fischlurch 2018-02-08 01:50:11 +01:00
parent bf314482da
commit 6022a8afb1
6 changed files with 62 additions and 8 deletions

View file

@ -420,6 +420,19 @@ namespace interact {
}
/** mutate the path to resolve all wildcards to achieve partial coverage
* - anchorage and all wildcards will be resolved against current UI
* - but an extraneous, uncovered, explicit suffix is retained
* @note if the coordinate spec can not be (partially) covered at all,
* it will be truncated to zero size
*/
UICoordResolver&&
coverPartially()
{
UNIMPLEMENTED ("mutate to partial coverage, retaining extension");
}
/** mutate the window part of the path such as
* to make the anchorage explicit, if possible
* @remark if the path starts with meta specs like

View file

@ -487,6 +487,9 @@ namespace interact {
/** @remark moving a builder instance is acceptable */
Builder (Builder &&) = default;
size_t size() const { return uic_.size(); }
bool empty() const { return uic_.empty();}
/* == Builder functions == */

View file

@ -87,6 +87,16 @@ namespace interact {
, createParents_{rr.createParents_}
{ }
operator UICoord const&() const
{
return pattern_;
}
size_t
size() const
{
return pattern_.size();
}
};
@ -114,6 +124,11 @@ namespace interact {
clauses_.emplace_back (move (furtherRule));
return move (*this);
}
using iterator = lib::RangeIter<Clauses::const_iterator>;
iterator begin() const { return iterator{clauses_.begin(), clauses_.end()}; }
iterator end() const { return iterator(); }
};
@ -143,30 +158,47 @@ namespace interact {
/**
* Access or allocate a UI component view
*
* @todo initial draft as of 9/2017 -- actual implementation need to be filled in
* @todo initial draft as of 2/2018 -- actual implementation need to be filled in
*/
class UILocationSolver
: boost::noncopyable
{
// ctrl::GlobalCtx& globals_;
LocationQueryAccess getLocationQuery;
public:
explicit
UILocationSolver (LocationQueryAccess)
UILocationSolver (LocationQueryAccess accessor)
: getLocationQuery{accessor}
{ }
explicit
UILocationSolver (LocationQuery&)
UILocationSolver (LocationQuery& locationQueryService)
: getLocationQuery{[&]() -> LocationQuery& { return locationQueryService; }}
{ }
/**
* Access and possibly create _just some_ component view of the desired type
* Solve for a location according to the given location rule.
* @param depth desired kind of UI element (and thus the depth in the UI topology tree)
* @param elementType designator of the specific element to be created at that level
* @return a explicit location, resolved against the current UI topology. May be empty
* @remarks the returned path is either empty (no solution exists), or it is "partially covered"
* by the existing UI; here, the "covered" part are the already existing UI elements,
* while the remaining, uncovered extension describes additional elements to be created.
* When the resolution process found an already existing UI element, the returned path
* is completely covered. The degree of coverage of a path can be found out with the
* help of a UICoordResolver, which also needs a LocationQuery (service) to find out
* about the currently existing UI topology.
*/
UICoord
solve (LocationRule& rule, size_t depth, Symbol elementName)
solve (LocationRule& rule, size_t depth, Symbol elementType)
{
UNIMPLEMENTED ("actually solve for a location according to the given rule");
for (auto& clause : rule)
{
if (clause.size() > depth+1) continue;
UICoordResolver resolver{clause, getLocationQuery()};
}
}
private:

View file

@ -82,6 +82,7 @@ namespace interact {
* Typically, this is provided by the Navigator service in conjunction with the ViewLocator;
* both are components managed by the InteractionDirector. Thus, when the UI starts, a suitable
* access functor will be installed here, and likewise removed/disabled on shutdown.
* ///////////////////////////////////////////////////////////////////////////////////////TICKET #1127 looks like we could get rid of that global state
*/
LocationQueryAccess locationQuery = LOCATION_QUERY_SERIVCE_NOT_AVAILABLE;

View file

@ -20,3 +20,8 @@ END
TEST "resolving UI coordinates" UICoordResolver_test <<END
return: 0
END
PLANNED "solving for UI location" UILocationSolver_test <<END
return: 0
END

View file

@ -2838,7 +2838,7 @@ Command instances are like prototypes -- thus each additional level of different
see the description in &amp;rarr; CommandSetup
</pre>
</div>
<div title="GuiComponentView" creator="Ichthyostega" modifier="Ichthyostega" created="201709021521" modified="201802011751" tags="def GuiPattern design" changecount="45">
<div title="GuiComponentView" creator="Ichthyostega" modifier="Ichthyostega" created="201709021521" modified="201802080022" tags="def GuiPattern design" changecount="46">
<pre>//A view within the UI, featuring some component of relevance to »the model«.//
While any UI is comprised of numerous widgets acting as //view of something,// only some of those views play the prominent role to act as //building block component// of the user interface.
Such UI component views exhibit some substantial traits
@ -2957,7 +2957,7 @@ The given UICoord specs are matched one by one, using the first one applicable.
The coordinate specs as written within the DSL are slightly abridged, as the final element, the actual component to be created, can be omitted and will be supplied automatically. This is possible insofar the ID of the queried element is actually more like a type specifier, and thus drawn from a finite and well known collection of possible elements (Timeline, Asset Bin, Error Log, Media Viewer, etc.). The elements to be created must invoke existing code and must be able to interface with their actual environment after all.
However, the semantics of UI coordinate resolution and matching are applied against the coordinate specs //as given in the DSL.// Since, by default, what is given is required to exist, it makes quite a difference as to what kind of element is used as terminal element of a given spec. Since our UI coordinate system establishes a distinct depth for each kind of element, we can and even must reject any spec which does not yield a definite location for at least the parent element; we do not interpolate or even invent arbitrary elements, we only ever match against existing ones. Thus any DSL definition must encompass a sane default, a final alternative clause which always succeeds -- and the DSL considered broken if it doesn't.
However, the semantics of UI coordinate resolution and matching are applied against the coordinate specs //as given in the DSL.// Since, by default, what is given is required to exist, it makes quite a difference as to what kind of element is used as terminal element of a given spec. Since our UI coordinate system establishes a distinct depth for each kind of element, we can and even must reject any spec which does not yield a definite location for at least the parent element; we do not interpolate or even invent arbitrary elements, we only ever match against existing ones. Thus any DSL definition must encompass a sane default, a final alternative clause which always succeeds -- and the DSL is considered broken if it doesn't.
!!!Semantics of allocation
While the process of probing and matching the location specification finally yields an explicit UICoord path to the desired element, it is up to the allocation step actually to decide on the action to be taken. Some allocation operations impose some kind of limit, and are thus free to ignore the given spec and rather return an existing element in place. In the end, the purpose of this whole matching and allocation process is to get hold of a suitable UI component without knowing its precise coordinates in the UI topology. And this is the very property to enable flexible mapping of the strictly hierarchical session structures onto the UI in a fluid way.