UI-Coordinates: implement low-level data manipulation incl. storage expansion

This commit is contained in:
Fischlurch 2017-10-02 02:18:58 +02:00
parent ee5bc046ae
commit 7826d6dc24
4 changed files with 54 additions and 16 deletions

View file

@ -249,7 +249,8 @@ namespace interact {
void
setComponent (UIPathElm idx, Literal newContent)
{
UNIMPLEMENTED ("forcibly change data, maybe extend storage");
Literal* storage = maybeExpandTo (idx);
setContent (storage, newContent);
}
@ -295,7 +296,7 @@ namespace interact {
/* == Builder functions == */
Builder&&
Builder
window (Literal windowID)
{
uic_.setComponent (UIC_WINDOW, windowID);
@ -303,15 +304,15 @@ namespace interact {
}
/** augment UI coordinates to mandate a specific perspective to be active within the window */
Builder&&
Builder
persp (Literal perspectiveID)
{
uic_.setComponent (UIC_PART, perspectiveID);
uic_.setComponent (UIC_PERSP, perspectiveID);
return std::move (*this);
}
/** augment UI coordinates to indicate a specific view to be used */
Builder&&
Builder
view (Literal viewID)
{
uic_.setComponent (UIC_VIEW, viewID);
@ -319,7 +320,7 @@ namespace interact {
}
/** augment UI coordinates to indicate a specific tab within the view" */
Builder&&
Builder
tab (Literal tabID)
{
uic_.setComponent (UIC_TAB, tabID);
@ -327,7 +328,7 @@ namespace interact {
}
/** augment UI coordinates to indicate a tab specified by index number */
Builder&&
Builder
tab (uint tabIdx)
{
uic_.setComponent (UIC_TAB, Symbol{"#"+util::toString (tabIdx)});
@ -336,21 +337,21 @@ namespace interact {
/** augment UI coordinates to define a complete local path */
Builder&&
Builder
path (string pathDefinition)
{
UNIMPLEMENTED ("set path");
}
/** augment UI coordinates by appending a further component at the end */
Builder&&
Builder
append (Literal elmID)
{
UNIMPLEMENTED ("mutate: append");
}
/** augment partially defined UI coordinates by extending them towards the root */
Builder&&
Builder
prepend (Literal elmID)
{
UNIMPLEMENTED ("mutate: preprend");

View file

@ -101,7 +101,7 @@ namespace lib {
PStorage
newCopy() const
{
size_t siz = size (unConst(this)->storage_);
size_t siz = 1 + size (unConst(this)->storage_);
const char** alloc = new const char*[siz];
std::copy (storage_, storage_+siz, alloc);
return reinterpret_cast<PStorage> (alloc);
@ -198,9 +198,20 @@ namespace lib {
}
void
trimTo (size_t cnt)
resizeTo (size_t cnt)
{
REQUIRE (cnt <= size());
if (cnt > size())
{ // copy to expanded storage
auto target = new const char* [cnt+1];
auto pos = std::copy (storage_, storage_+1+size(), target);
for ( ; pos < target+1+cnt; ++pos)
*pos = nullptr;
if (storage_)
delete[] storage_;
storage_ = reinterpret_cast<PStorage> (target);
size (storage_) = cnt;
return;
}
if (not storage_) return;
if (cnt == 0)
{
@ -437,6 +448,22 @@ namespace lib {
return const_cast<Literal*> (elm);
}
/**
* @internal ensure storage for the indicated position exists
* @return pointer to the storage, either existing or reallocated
*/
Literal*
maybeExpandTo (size_t idx)
{
if (chunk_size <= idx and size() <= idx)
tail_.resizeTo(idx+1 - chunk_size);
if (idx < chunk_size)
return elms_.begin() + idx;
ENSURE (idx-chunk_size < tail_.size());
return const_cast<Literal*> (&tail_[idx-chunk_size]);
}
/** @internal force new content into the given entry */
void
setContent (Literal* pos, const char* val)
@ -487,9 +514,9 @@ namespace lib {
setContent (getPosition(idx), nullptr);
if (idx >= chunk_size-1)
tail_.trimTo (idx+1 - chunk_size);
tail_.resizeTo (idx+1 - chunk_size);
else
tail_.trimTo (0);
tail_.resizeTo (0);
}
};

View file

@ -143,7 +143,7 @@ namespace test {
verify_builder()
{
UICoord uic1 = UICoord::window("window");
UICoord uic2 = uic2.view("view");
UICoord uic2 = uic1.view("view");
CHECK ("UI:window" == string(uic1));
CHECK ("UI:window[*]-*.view" == string(uic2));
CHECK (1 == uic1.size());

View file

@ -481,6 +481,16 @@ namespace test {
CHECK (ParrT("" ,"Δ","Θ","Ξ","" ,"Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ",nullptr,"Ψ","Φ"));
CHECK (ParrT("" ,"Δ","Θ","Ξ","*","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ",nullptr,"Ψ","Φ"));
CHECK (ParrT("" ,"Δ","Θ","Ξ","*","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ","", "Ψ","Φ"));
ParrT src{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"};
ParrT copy{src};
CHECK (not isnil(copy));
CHECK (src == copy);
ParrT target {std::move (copy)};
CHECK (src == target);
CHECK (copy != target);
CHECK (copy != src);
}
};