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; static const int RESTORE_AT_TOP = 0x1;
private: private:
void extract(df::viewscreen*); void extract();
void merge(df::viewscreen*); void merge();
df::viewscreen* screen; df::viewscreen* screen;
df::viewscreen* prev_parent;
int flags; int flags;
}; };
} }

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