Skip to content

Commit

Permalink
TNodeTree
Browse files Browse the repository at this point in the history
  • Loading branch information
AdventureT committed Dec 7, 2023
1 parent bea7e53 commit b0357d9
Show file tree
Hide file tree
Showing 9 changed files with 425 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Toshi/Include/Defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#define TOSHI_NAMESPACE_END }
#define TOSHI_NAMESPACE_USING using namespace Toshi;

#define TSTATICCAST(type, value) static_cast<type>(value)

#define _TS8(str) #str

typedef bool TBOOL;
Expand Down
6 changes: 6 additions & 0 deletions Toshi/Include/TKernel/TManagedPointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ class TOSHI_EXPORT TManagedPointer
delete m_pObject;
}

T* operator=(T* a_pObject)
{
m_pObject = a_pObject;
return m_pObject;
}

T& operator*() { TASSERT(m_pObject != TNULL); return *m_pObject; }

operator T* () { TASSERT(m_pObject!=TNULL); return m_pObject; }
Expand Down
57 changes: 57 additions & 0 deletions Toshi/Include/TKernel/TNTree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include <TKernel/TDebug.h>

TOSHI_NAMESPACE_BEGIN

class TOSHI_EXPORT TGenericNTree
{
class TNode
{
protected:


TINT FindChild(TNode const* a_pNode, TINT a_iCount)
{
for (TINT i = 0; i < a_iCount; i++) {
if (a_pNode == m_pChildren[i]) {
return i;
}
}
return -1;
}

TNode* Child(TINT a_iIndex) const { return m_pChildren[a_iIndex]; }
TNode* Parent() const { return m_pParent; }

private:
TNode* m_pParent; // 0x0
TNode** m_pChildren; // 0x4
};

protected:

TGenericNTree()
{
m_pRoot = TNULL;
}

void InsertRoot(TNode *a_pNode)
{
m_pRoot = a_pNode;
a_pNode = TNULL;
}

void RemoveRoot()
{
m_pRoot = TNULL;
}

TNode* Root() const { return m_pRoot; }
private:
TNode* m_pRoot; // 0x0
};



TOSHI_NAMESPACE_END
269 changes: 269 additions & 0 deletions Toshi/Include/TKernel/TNodeTree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
#pragma once
#include "TDebug.h"

TOSHI_NAMESPACE_BEGIN

// Since this won't be exported, is a template class and there is no 'TGenericNodeTree', we can't propably decompile it via ghidra
// Code from OpenToshi

template <class T>
class TNodeTree
{
public:
class TNode
{
public:
friend TNodeTree;

protected:
TNode()
{
m_Tree = TNULL;
m_Next = (T*)this;
m_Prev = (T*)this;
m_Parent = TNULL;
m_Attached = TNULL;
}

public:
TBOOL IsChildOfDefaultRoot() const
{
TASSERT(IsLinked() == TTRUE);
return m_Parent == (T*)(&Tree()->m_Root);
}

TBOOL IsLinked() const { return m_Tree != TNULL; }
T* Parent() const { return m_Parent; }
T* Next() const { return m_Next; }
T* Prev() const { return m_Prev; }
TNodeTree<T>* Tree() const { return m_Tree; }
T* Attached() const { return m_Attached; }

protected:
TNodeTree<T>* m_Tree;
T* m_Next;
T* m_Prev;
T* m_Parent;
T* m_Attached;
};

public:
TNodeTree()
{
m_Count = 0;
}

~TNodeTree()
{
DeleteAll();
TASSERT(IsLinked() == TFALSE);
}

/**
* Inserts node as a child of another node.
*
* @param parentNode Pointer to the parent node.
* @param sourceNode Pointer to the node you want to insert.
*/
void Insert(T* parentNode, T* sourceNode)
{
// Toshi::TNodeTree<Toshi::TResource>::Insert - 00691aa0
TASSERT(sourceNode->IsLinked() == TFALSE, "The source node shouldn't be linked");

// Remove the source node from the tree
Remove(*sourceNode, TFALSE);

// Get the first attached to parent node
T* firstAttached = parentNode->Attached();

if (firstAttached != TNULL)
{
// Attach node to other attached nodes
T* lastAttached = firstAttached->Prev();

lastAttached->m_Next = sourceNode;
firstAttached->m_Prev = sourceNode;

sourceNode->m_Next = firstAttached;
sourceNode->m_Prev = lastAttached;
}
else
{
// Attach node as the first one
parentNode->m_Attached = sourceNode;
}

sourceNode->m_Tree = this;
sourceNode->m_Parent = parentNode;
m_Count += 1;
}

/**
* Inserts node to the default tree.
*
* @param sourceNode Pointer to the node you want to insert.
*/
void InsertAtRoot(T* sourceNode)
{
Insert(GetRoot(), sourceNode);
}

/**
* Tries to remove sourceNode from the tree and inserts it to the parentNode or to the root
*/
void ReInsert(T* parentNode, T* sourceNode)
{
Remove(sourceNode, TFALSE);

if (parentNode == TNULL)
{
if (this != TNULL)
{
InsertAtRoot(sourceNode);
return;
}
}

Insert(parentNode, sourceNode);
}

T* Remove(T& node, TBOOL flag = TFALSE)
{
// Toshi::TNodeTree<Toshi::TResource>::Remove - 00691e70
TNodeTree<T>* nodeRoot = node.Tree();
T* nodeParent = node.Parent();

if (nodeRoot != TNULL)
{
// Check if the node belongs to the current tree
if (nodeRoot != this)
{
return &node;
}

m_Count -= 1;
}

if (flag)
{
T* attachedNode = node.Attached();

while (attachedNode != TNULL)
{
TNodeTree<T>* nodeRoot = node.Tree();

Remove(*attachedNode, TFALSE);
Insert(node.Parent(), attachedNode);

attachedNode = node.Attached();
TWARNING("It seems to be unused and I hope it is. I don't know if it works and what it should do\n");
}
}

if (nodeParent != TNULL)
{
// If it's the first attached to the root node, set it to next or just remove
if (nodeParent->Attached() == &node)
{
nodeParent->m_Attached = (node.Next() != &node) ? node.Next() : TNULL;
}

node.m_Parent = TNULL;
}

node.m_Prev->m_Next = node.m_Next;
node.m_Next->m_Prev = node.m_Prev;
node.m_Next = &node;
node.m_Prev = &node;
node.m_Tree = TNULL;
return &node;
}

T* Remove(T* node, TBOOL flag = TFALSE)
{
return Remove(*node, flag);
}

void DeleteRecurse(T* node)
{
while (node != TNULL)
{
T* next = (node->Next() != node) ? node->Next() : TNULL;

if (node->Attached() != TNULL)
{
DeleteRecurse(node->Attached());
}

if (node->Tree() == this)
{
m_Count -= 1;
}

if (node->Tree() == TNULL || node->Tree() == this)
{
T* nodeParent = node->Parent();

if (nodeParent != TNULL)
{
// If it's the first attached to the root node, set it to next or just remove
if (nodeParent->Attached() == node)
{
nodeParent->m_Attached = (node->Next() != node) ? node->Next() : TNULL;
}

node->m_Parent = TNULL;
}

node->m_Prev->m_Parent = node->m_Next;
node->m_Next->m_Attached = node->m_Prev;
node->m_Next = node;
node->m_Prev = node;
node->m_Tree = TNULL;
}

delete node;
node = next;
}
}

void DeleteAll()
{
T* node = GetRoot()->Attached();

while (node != TNULL)
{
Remove(node, TFALSE);
DeleteRecurse(node);
node = GetRoot()->Attached();
}

TASSERT(Count() == 0);
}

T* GetRoot()
{
return TSTATICCAST(T*, &m_Root);
}

T* AttachedToRoot()
{
return m_Root.Attached();
}

size_t Count() const
{
return m_Count;
}

TBOOL IsLinked() const
{
return m_Root.IsLinked();
}

protected:
TNode m_Root; // 0x0
size_t m_Count; // 0x14
};

TOSHI_NAMESPACE_END
5 changes: 3 additions & 2 deletions Toshi/Include/TKernel/TScheduler.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#pragma once

#include "TDebug.h"
#include "TObject.h"

TOSHI_NAMESPACE_BEGIN

class TOSHI_EXPORT TScheduler
class TOSHI_EXPORT TScheduler : public TObject
{
DECLARE_DYNAMIC(TKernelInterface);
public:
void Update();
};
Expand Down
Loading

0 comments on commit b0357d9

Please sign in to comment.