Skip to content

Commit

Permalink
Performance|Widgets|libappfw: Optionally recycle children in a virtua…
Browse files Browse the repository at this point in the history
…lized menu

Provides better performance in menus where all the items use the same kind
of widget.
  • Loading branch information
skyjake committed Jan 21, 2017
1 parent a88c946 commit 5087096
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
10 changes: 10 additions & 0 deletions doomsday/sdk/libappfw/include/de/framework/childwidgetorganizer.h
Expand Up @@ -124,6 +124,16 @@ class LIBAPPFW_PUBLIC ChildWidgetOrganizer
*/
void setVirtualizationEnabled(bool enabled);

/**
* Enables or disables child recycling. Deleted children will be put up for
* recycling instead of being deleted, and new children will first be taken
* from the set of old recycled widgets.
*
* It is only possible to use this when all the items being managed have the
* same kind of widget representing them.
*/
void setRecyclingEnabled(bool enabled);

void setVirtualTopEdge(Rule const &topEdge);

void setVisibleArea(Rule const &minimum, Rule const &maximum);
Expand Down
34 changes: 32 additions & 2 deletions doomsday/sdk/libappfw/src/childwidgetorganizer.cpp
Expand Up @@ -71,6 +71,9 @@ DENG2_PIMPL(ChildWidgetOrganizer)
float totalCorrection = 0;
float correctionPerUnit = 0;

bool recyclingEnabled = false;
QList<GuiWidget *> recycledWidgets; // Not GL-deinitialized to facilitate fast reuse.

Impl(Public *i, GuiWidget *c)
: Base(i)
, container(c)
Expand All @@ -79,6 +82,11 @@ DENG2_PIMPL(ChildWidgetOrganizer)

~Impl()
{
foreach (GuiWidget *recycled, recycledWidgets)
{
GuiWidget::destroy(recycled);
}

releaseRef(virtualTop);
releaseRef(virtualMin);
releaseRef(virtualMax);
Expand Down Expand Up @@ -130,7 +138,15 @@ DENG2_PIMPL(ChildWidgetOrganizer)

ui::Item const &item = dataItems->at(pos);

GuiWidget *w = factory->makeItemWidget(item, container);
GuiWidget *w = nullptr;
if (recyclingEnabled && !recycledWidgets.isEmpty())
{
w = recycledWidgets.takeFirst();
}
else
{
w = factory->makeItemWidget(item, container);
}
if (!w) return nullptr; // Unpresentable.

// Update the widget immediately.
Expand Down Expand Up @@ -213,7 +229,16 @@ DENG2_PIMPL(ChildWidgetOrganizer)
{
//pendingStrutAdjust.remove(w);
w->audienceForDeletion() -= this;
GuiWidget::destroy(w);

if (recyclingEnabled)
{
w->orphan();
recycledWidgets << w;
}
else
{
GuiWidget::destroy(w);
}
}

void clearWidgets()
Expand Down Expand Up @@ -580,6 +605,11 @@ void ChildWidgetOrganizer::setVirtualizationEnabled(bool enabled)
}
}

void ChildWidgetOrganizer::setRecyclingEnabled(bool enabled)
{
d->recyclingEnabled = enabled;
}

void ChildWidgetOrganizer::setVirtualTopEdge(Rule const &topEdge)
{
changeRef(d->virtualTop, topEdge);
Expand Down

0 comments on commit 5087096

Please sign in to comment.