From fdf9a1245d18ac962414f8df8a803f89914a30fe Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Mon, 11 May 2020 19:48:02 -0400 Subject: [PATCH] Wrote the code to check for parent cycles. I'm not going to actually hook it up yet; I want to resolve the one TODO about limiting the scope of the checkProgrammerError() calls first. --- common/controls.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/common/controls.c b/common/controls.c index 0ffe7269..0c6d3af5 100644 --- a/common/controls.c +++ b/common/controls.c @@ -190,6 +190,35 @@ void uiControlFree(uiControl *c) uiprivFree(c); } +static bool parentHasCycle(uiControl *c, uiControl *parent) +{ + uiprivArray parents; + size_t i; + + if (parent == NULL) + return false; + if (parent == c) // easy case + return true; + + uiprivArrayInit(parents, uiControl *, 16, "uiControl parent list"); + // add these now, as they are counted as part of any cycles + *((uiControl *) uiprivArrayAppend(parents, 1)) = c; + *((uiControl *) uiprivArrayAppend(parents, 1)) = parent; + for (c = parent->parent; c != NULL; c = c->parent) { + // TODO this doesn't need to be sequential, but I don't imagine this list will ever be long enough to make it matter... yet + for (i = 0; i < parents.len; i++) + if (c == uiprivArrayAt(parents, uiControl *, i)) { + uiprivArrayFree(parents); + return true; + } + // new parent; mark it as visited + *((uiControl *) uiprivArrayAppend(parents, 1)) = c; + } + + uiprivArrayFree(parents); + return false; +} + void uiControlSetParent(uiControl *c, uiControl *parent) { if (!uiprivCheckInitializedAndThread())