solve the inception problem

where hideGuard smashes the viewscreen stack with multiple insertions
for the same screen
develop
Myk Taylor 2023-01-28 08:02:46 -08:00
parent 277a37a12f
commit 863ca2ca65
No known key found for this signature in database
2 changed files with 33 additions and 26 deletions

@ -318,9 +318,10 @@ namespace DFHack
static const int RESTORE_AT_TOP = 0x1;
private:
void extract(df::viewscreen*);
void merge(df::viewscreen*);
void extract();
void merge();
df::viewscreen* screen;
df::viewscreen* prev_parent;
int flags;
};
}

@ -527,43 +527,49 @@ void Screen::raise(df::viewscreen *screen) {
namespace DFHack { namespace Screen {
Hide::Hide(df::viewscreen* screen, int flags) :
screen{screen}, flags{flags}
{
extract(screen);
screen{screen}, prev_parent{nullptr}, flags{flags} {
if (!screen)
return;
// don't extract a screen that's not even in the stack
if (screen->parent)
extract();
}
Hide::~Hide()
{
Hide::~Hide() {
if (screen)
merge(screen);
merge();
}
void Hide::extract(df::viewscreen* a)
{
df::viewscreen* ap = a->parent;
df::viewscreen* ac = a->child;
void Hide::extract() {
prev_parent = screen->parent;
df::viewscreen *prev_child = screen->child;
ap->child = ac;
if (ac) ac->parent = ap;
else Core::getInstance().top_viewscreen = ap;
screen->parent = nullptr;
screen->child = nullptr;
prev_parent->child = prev_child;
if (prev_child) prev_child->parent = prev_parent;
else Core::getInstance().top_viewscreen = prev_parent;
}
void Hide::merge() {
if (screen->parent) {
// we're somehow back on the stack; do nothing
return;
}
void Hide::merge(df::viewscreen* a)
{
if (flags & RESTORE_AT_TOP) {
a->parent = NULL;
a->child = NULL;
Screen::show(std::unique_ptr<df::viewscreen>(a));
Screen::show(std::unique_ptr<df::viewscreen>(screen));
return;
}
df::viewscreen* ap = a->parent;
df::viewscreen* ac = a->parent->child;
df::viewscreen* new_child = prev_parent->child;
ap->child = a;
a->child = ac;
if (ac) ac->parent = a;
else Core::getInstance().top_viewscreen = a;
prev_parent->child = screen;
screen->child = new_child;
if (new_child) new_child->parent = screen;
else Core::getInstance().top_viewscreen = screen;
}
} }