#Issue with recycling nodes in a quad
1 messages · Page 1 of 1 (latest)
I wrote this system that manages nodes for an lod system, but for some reason as soon as I try to recycle the nodes using the FreeNode funciton my hierachy breaks and I get stack overflows
this post should be on advanced i think..
but just continuous here
i think my implementation is similar to you
I just found the first mistake which was causing it to free the same node multiple times, but it still did not resolve the issue
private void DeleteNodeChildren(int myIndex)
{
Node node = _nodeData[myIndex];
if (node.HasChildren)
{
for (int i = 0; i < 4; i++)
{
DeleteNode(node.children[i]);//DeleteNode(myIndex);
}
node.HasChildren = false;
node.children = new int4(-1);
_nodeData[myIndex] = node;
}
}```#
that s cool, are you sharing it with others?
i see you havent set hasChildren after the subtree is freed
you can just use a get{} return true if one of the children is assigned, since you allocate four children at once
hm hdym
as far as I understand my system there are always either 4 or 0 children assigned
oh yeah that s pretty smart, I currently use a bitset but yours looks more handy
it s just so weird I don t see the difference between a node being reused or not since all new nodes get build with a non default constructor
your previous deletXXX will keep freeing same nodes if you have no double free check, it should be like that, delete all its children
do you not trust index operator?
you keep passing myIndex for four times
oh yeah, but I already fixed that here sry for not pointing it out
oh sorry i miss it
the issue has to be somewhere else but I don t understand how the fact that I implemented recyneling nodes broke everything
where is the stack overflow is thrown? deleteNode? i see the free node function is just one line of enqueue
no usually in the nodeloop
the error is caused because a node has him self in as a child
you have check the return index of AllocNode() ?
so your allocator implementation is wrong
I doubt that to me it rather looks as if it s freeing a different node, I will have the nodes track their own index to see if there is a missmatch, that did not fix it/ the index being freed is correct
private static UnsafeList<Node> pool;
private static UnsafeList<int> stack;
private void InitPool(int capacity=1024){
pool=new UnsafeList<Node>(capacity,Allocator.Persistent);
pool.Length=capacity;
stack=new UnsafeList<int>(capacity,Allocator.Persistent);
for(int i=0;i<capacity;i++){
stack.Add(i);
}
}
unsafe private Node* Get(){
if(stack.Length<=0){
int oldcap=pool.Capacity;
pool.Capacity=oldcap<<1;
pool.Length=oldcap<<1;
stack.Capacity=oldcap<<1;
for(int i=oldcap;i<(oldcap<<1);i++){
stack.Add(i);
}
}
int idx=stack[stack.Length-1];
stack.Length--;
return pool.Ptr+idx;
}
unsafe private void Release(Node* node){
stack.Add((int)(node-pool.Ptr));
}
maybe you can try this design first
it basically store all available index
push if release pop if get
ou cool you use unsafe code?
it always crashes for me even if I just write one line of unsafe
yes unsafe (pointer) is much easier to work with
you can directly get the pointer with calling any other method
yeah how do yo enable it in unity tho?
you means allow unsafe code?
https://docs.unity3d.com/ScriptReference/PlayerSettings-allowUnsafeCode.html in player setting
is this your implementation?
yes
this design is easier to understand, i have another memory optimized one but the allocation time is slightly slower
does unsafe allow you to have int as template parameter?
the T should be unmanaged
hey thanks for your help but it s gonna take some time for me to get into writing unsafe code so I guess helping me rn is a waste of time
you can use an additional bitvector to check if the address double free
without stroing this on the tree node itself
hm I don t understand
maybe i misunderstand your code, i am not sure the inqueue is indicating the node in drawqueue or freeslot
oh so you can add the node either to the freeSlots queue, which means that the memory of the node can be reused and the node should no longer be used and to the drawQueue which means that in one of the next frames the queue will be picked up, when picked up it undraws all it s parents and deletes all it s children