mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-21 15:21:15 +00:00
Node rotate inline functions are better, added more code everywhere else
This commit is contained in:
parent
3ae3d2fe20
commit
fcfc475eb1
@ -18,13 +18,50 @@ MxAtomId::MxAtomId(const char *p_str, LookupMode p_mode)
|
|||||||
// OFFSET: LEGO1 0x100acfd0
|
// OFFSET: LEGO1 0x100acfd0
|
||||||
MxAtomId::~MxAtomId()
|
MxAtomId::~MxAtomId()
|
||||||
{
|
{
|
||||||
// TODO
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100acfe0
|
||||||
|
void MxAtomId::Destroy()
|
||||||
|
{
|
||||||
|
if (*m_internal == '\0')
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!MxOmni::GetInstance())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!AtomIdTree())
|
||||||
|
return;
|
||||||
|
|
||||||
|
TreeValue value = TreeValue(m_internal);
|
||||||
|
TreeValue *p = &value;
|
||||||
|
|
||||||
|
// 100ad052
|
||||||
|
MxBinaryTree *tree = AtomIdTree();
|
||||||
|
TreeNode *root = tree->m_root;
|
||||||
|
|
||||||
|
// should inline Search but NOT TreeValueCompare
|
||||||
|
TreeNode *node = tree->Search(p);
|
||||||
|
|
||||||
|
TreeNode *ass = node;
|
||||||
|
if (node == root->m_parent || TreeValueCompare(p, node->m_value)) {
|
||||||
|
ass = root->m_parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->m_value->RefCountDec();
|
||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100ad1c0
|
// OFFSET: LEGO1 0x100ad1c0
|
||||||
MxAtomId &MxAtomId::operator=(const MxAtomId &id)
|
MxAtomId &MxAtomId::operator=(const MxAtomId &atomId)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
|
const char *temp = m_internal;
|
||||||
|
if (m_internal)
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
if (atomId.m_internal && MxOmni::GetInstance() && AtomIdTree())
|
||||||
|
try_to_open(temp, LookupMode_Exact);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,16 +81,17 @@ TreeValue *MxAtomId::try_to_open(const char *p_str, LookupMode p_mode)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LAB_100ad2a1
|
||||||
MxBinaryTree *tree = AtomIdTree();
|
MxBinaryTree *tree = AtomIdTree();
|
||||||
// get the closest node that matches the given value
|
// get the closest node that matches the given value
|
||||||
|
// should NOT inline
|
||||||
node = tree->Search(value);
|
node = tree->Search(value);
|
||||||
|
|
||||||
// pointer reuse???
|
// pointer reuse???
|
||||||
TreeNode *ptr_reuse = node;
|
TreeNode *ptr_reuse = node;
|
||||||
|
|
||||||
// is the node an exact match?
|
// is the node an exact match?
|
||||||
if (tree->m_root == node ||
|
if (tree->m_root == node || TreeValueCompare(value, node->m_value)) {
|
||||||
strcmp(value->m_str.GetData(), node->m_value->m_str.GetData()) > 0) {
|
|
||||||
ptr_reuse = tree->m_root;
|
ptr_reuse = tree->m_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,3 +108,10 @@ TreeValue *MxAtomId::try_to_open(const char *p_str, LookupMode p_mode)
|
|||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100ad7e0
|
||||||
|
void MxAtomId::Clear()
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
m_internal = NULL;
|
||||||
|
}
|
||||||
|
|||||||
@ -33,6 +33,8 @@ class MxAtomId
|
|||||||
|
|
||||||
// TODO: belongs here?
|
// TODO: belongs here?
|
||||||
TreeValue *try_to_open(const char *, LookupMode);
|
TreeValue *try_to_open(const char *, LookupMode);
|
||||||
|
void Destroy();
|
||||||
|
void Clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *m_internal;
|
const char *m_internal;
|
||||||
|
|||||||
@ -3,6 +3,12 @@
|
|||||||
// 0x101013f0
|
// 0x101013f0
|
||||||
TreeNode *MxBinaryTree::g_Node_Nil = NULL;
|
TreeNode *MxBinaryTree::g_Node_Nil = NULL;
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100ad170
|
||||||
|
TreeValue::~TreeValue()
|
||||||
|
{
|
||||||
|
// nothing.
|
||||||
|
}
|
||||||
|
|
||||||
inline void MxBinaryTree::LeftRotate(TreeNode *x)
|
inline void MxBinaryTree::LeftRotate(TreeNode *x)
|
||||||
{
|
{
|
||||||
TreeNode *y = x->m_child1;
|
TreeNode *y = x->m_child1;
|
||||||
@ -14,23 +20,22 @@ inline void MxBinaryTree::LeftRotate(TreeNode *x)
|
|||||||
y->m_parent = x->m_parent;
|
y->m_parent = x->m_parent;
|
||||||
|
|
||||||
if (m_root->m_parent != x) {
|
if (m_root->m_parent != x) {
|
||||||
if (x == x->m_parent->m_child0) {
|
if (x != x->m_parent->m_child0) {
|
||||||
x->m_parent->m_child0 = y;
|
|
||||||
y->m_child0 = x; //?
|
|
||||||
x->m_parent = y; //?
|
|
||||||
} else {
|
|
||||||
x->m_parent->m_child1 = y;
|
x->m_parent->m_child1 = y;
|
||||||
y->m_child1 = x; //?
|
y->m_child0 = x;
|
||||||
x->m_parent = y; //?
|
x->m_parent = y;
|
||||||
|
} else {
|
||||||
|
x->m_parent->m_child0 = y;
|
||||||
|
y->m_child0 = x;
|
||||||
|
x->m_parent = y;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ?
|
m_root->m_parent->m_child0 = y;
|
||||||
y->m_child0 = x;
|
y->m_child0 = x;
|
||||||
x->m_parent = y;
|
x->m_parent = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void MxBinaryTree::RightRotate(TreeNode *x)
|
inline void MxBinaryTree::RightRotate(TreeNode *x)
|
||||||
{
|
{
|
||||||
TreeNode *y = x->m_child0;
|
TreeNode *y = x->m_child0;
|
||||||
@ -42,17 +47,17 @@ inline void MxBinaryTree::RightRotate(TreeNode *x)
|
|||||||
y->m_parent = x->m_parent;
|
y->m_parent = x->m_parent;
|
||||||
|
|
||||||
if (m_root->m_parent != x) {
|
if (m_root->m_parent != x) {
|
||||||
if (x == x->m_parent->m_child1) {
|
if (x != x->m_parent->m_child1) {
|
||||||
x->m_parent->m_child1 = y;
|
|
||||||
y->m_child1 = x; //?
|
|
||||||
x->m_parent = y; //?
|
|
||||||
} else {
|
|
||||||
x->m_parent->m_child0 = y;
|
x->m_parent->m_child0 = y;
|
||||||
y->m_child0 = x; //?
|
y->m_child1 = x;
|
||||||
x->m_parent = y; //?
|
x->m_parent = y;
|
||||||
|
} else {
|
||||||
|
x->m_parent->m_child1 = y;
|
||||||
|
y->m_child1 = x;
|
||||||
|
x->m_parent = y;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//?
|
m_root->m_parent->m_child1 = y;
|
||||||
y->m_child1 = x;
|
y->m_child1 = x;
|
||||||
x->m_parent = y;
|
x->m_parent = y;
|
||||||
}
|
}
|
||||||
@ -93,26 +98,24 @@ void mini_walk(TreeNode* &p_node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OFFSET: LEGO1 0x100ad4d0
|
// OFFSET: LEGO1 0x100ad4d0
|
||||||
void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_parent, TreeValue *&p_value)
|
void MxBinaryTree::Insert(TreeNode **p_output, TreeNode *p_leaf, TreeNode *p_parent, TreeValue *&p_value)
|
||||||
{
|
{
|
||||||
TreeNode *node = newTreeNode(p_parent, NODE_COLOR_RED);
|
TreeNode *node = newTreeNode(p_parent, NODE_COLOR_RED);
|
||||||
node->m_child0 = g_Node_Nil;
|
node->m_child0 = g_Node_Nil;
|
||||||
node->m_child1 = g_Node_Nil;
|
node->m_child1 = g_Node_Nil;
|
||||||
|
|
||||||
// TODO: ???
|
// TODO: ???
|
||||||
if (node->m_value) {
|
if (&node->m_value)
|
||||||
node->m_value = p_value;
|
node->m_value = p_value;
|
||||||
}
|
|
||||||
|
|
||||||
this->m_p3++; // node count?
|
this->m_nodeCount++;
|
||||||
|
|
||||||
// if tree is NOT empty
|
// if tree is NOT empty
|
||||||
// if param_2 is tree_nil (always true I think?)
|
// if param_2 is tree_nil (always true I think?)
|
||||||
//
|
//
|
||||||
if (this->m_root != p_parent
|
if (m_root != p_parent
|
||||||
&& p_leaf == MxBinaryTree::g_Node_Nil
|
&& p_leaf == MxBinaryTree::g_Node_Nil
|
||||||
&& strcmp(p_value->m_str.GetData(),
|
&& TreeValueCompare(p_value, p_parent->m_value)) {
|
||||||
p_parent->m_value->m_str.GetData()) <= 0) {
|
|
||||||
p_parent->m_child1 = node;
|
p_parent->m_child1 = node;
|
||||||
|
|
||||||
if (m_root->m_child1 == p_parent)
|
if (m_root->m_child1 == p_parent)
|
||||||
@ -120,8 +123,9 @@ void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode
|
|||||||
} else {
|
} else {
|
||||||
p_parent->m_child0 = node;
|
p_parent->m_child0 = node;
|
||||||
|
|
||||||
if (m_root != p_parent && m_root->m_child0 == p_parent) {
|
if (m_root != p_parent) {
|
||||||
m_root->m_child0 = p_parent;
|
if (m_root->m_child0 == p_parent)
|
||||||
|
m_root->m_child0 = node;
|
||||||
} else {
|
} else {
|
||||||
m_root->m_parent = node;
|
m_root->m_parent = node;
|
||||||
m_root->m_child1 = node;
|
m_root->m_child1 = node;
|
||||||
@ -129,7 +133,7 @@ void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LAB_100ad593
|
// LAB_100ad593
|
||||||
// rebalance??
|
// rebalance the tree
|
||||||
TreeNode *cur = node;
|
TreeNode *cur = node;
|
||||||
while (m_root->m_parent != cur) {
|
while (m_root->m_parent != cur) {
|
||||||
TreeNode *parent = cur->m_parent;
|
TreeNode *parent = cur->m_parent;
|
||||||
@ -137,12 +141,10 @@ void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode
|
|||||||
if (parent->m_color != NODE_COLOR_RED)
|
if (parent->m_color != NODE_COLOR_RED)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
TreeNode *grandparent = parent->m_parent;
|
TreeNode *uncle = parent->m_parent->m_child0;
|
||||||
TreeNode *uncle = grandparent->m_child0;
|
|
||||||
|
|
||||||
if (uncle == parent) {
|
if (uncle == parent) {
|
||||||
// wrong uncle
|
// wrong uncle
|
||||||
uncle = grandparent->m_child1;
|
uncle = parent->m_parent->m_child1;
|
||||||
|
|
||||||
if (uncle->m_color != NODE_COLOR_RED) {
|
if (uncle->m_color != NODE_COLOR_RED) {
|
||||||
|
|
||||||
@ -150,23 +152,6 @@ void MxBinaryTree::FUN_100ad4d0(TreeNode **p_output, TreeNode *p_leaf, TreeNode
|
|||||||
if (parent->m_child1 == cur) {
|
if (parent->m_child1 == cur) {
|
||||||
cur = parent;
|
cur = parent;
|
||||||
LeftRotate(cur);
|
LeftRotate(cur);
|
||||||
// rotate.
|
|
||||||
/*
|
|
||||||
parent->m_child1 = parent->m_child1->m_child0;
|
|
||||||
|
|
||||||
// 100ad5e2
|
|
||||||
if (parent->m_child1 != g_Node_Nil)
|
|
||||||
parent->m_child1->m_parent = cur;
|
|
||||||
|
|
||||||
parent->m_child1->m_parent = grandparent;
|
|
||||||
if (m_root->m_parent == cur || grandparent->m_child0 == cur)
|
|
||||||
grandparent->m_child1 = parent;
|
|
||||||
else
|
|
||||||
grandparent->m_child0 = parent;
|
|
||||||
|
|
||||||
parent->m_child0 = cur;
|
|
||||||
grandparent->m_child0 = parent;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LAB_100ad60f
|
// LAB_100ad60f
|
||||||
@ -210,10 +195,7 @@ TreeNode *MxBinaryTree::Search(TreeValue*& p_value)
|
|||||||
TreeNode *t_node = node_match->m_parent;
|
TreeNode *t_node = node_match->m_parent;
|
||||||
|
|
||||||
while (t_node != g_Node_Nil) {
|
while (t_node != g_Node_Nil) {
|
||||||
int result = strcmp(t_node->m_value->m_str.GetData(), p_value->m_str.GetData());
|
if (!TreeValueCompare(t_node->m_value, p_value)) {
|
||||||
|
|
||||||
if (result <= 0) {
|
|
||||||
// if strings equal or less than search string
|
|
||||||
// closest match?
|
// closest match?
|
||||||
// it either does match or is where we will insert the new node.
|
// it either does match or is where we will insert the new node.
|
||||||
node_match = t_node;
|
node_match = t_node;
|
||||||
|
|||||||
@ -15,6 +15,7 @@ class TreeValue {
|
|||||||
m_str = p_str;
|
m_str = p_str;
|
||||||
m_t0 = 0;
|
m_t0 = 0;
|
||||||
}
|
}
|
||||||
|
~TreeValue();
|
||||||
|
|
||||||
void RefCountInc();
|
void RefCountInc();
|
||||||
void RefCountDec();
|
void RefCountDec();
|
||||||
@ -27,12 +28,6 @@ class TreeValue {
|
|||||||
// SIZE 0x14
|
// SIZE 0x14
|
||||||
class TreeNode {
|
class TreeNode {
|
||||||
public:
|
public:
|
||||||
TreeNode(TreeNode *p_parent, int p_color)
|
|
||||||
{
|
|
||||||
m_parent = p_parent;
|
|
||||||
m_color = p_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeNode *m_child0; // +0 // string sorts after
|
TreeNode *m_child0; // +0 // string sorts after
|
||||||
TreeNode *m_parent; // +4 // parent node
|
TreeNode *m_parent; // +4 // parent node
|
||||||
TreeNode *m_child1; // +8 // string sorts before
|
TreeNode *m_child1; // +8 // string sorts before
|
||||||
@ -40,6 +35,21 @@ class TreeNode {
|
|||||||
int m_color; // +10 // BLACK or RED.
|
int m_color; // +10 // BLACK or RED.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: helper to avoid using a non-default constructor
|
||||||
|
inline TreeNode *newTreeNode(TreeNode *p_parent, int p_color)
|
||||||
|
{
|
||||||
|
TreeNode *t = new TreeNode();
|
||||||
|
t->m_parent = p_parent;
|
||||||
|
t->m_color = p_color;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OFFSET: LEGO1 0x100ad120
|
||||||
|
inline int TreeValueCompare(TreeValue *&p_val0, TreeValue *&p_val1)
|
||||||
|
{
|
||||||
|
return strcmp(p_val0->m_str.GetData(), p_val1->m_str.GetData()) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
// SIZE 0x10
|
// SIZE 0x10
|
||||||
class MxBinaryTree
|
class MxBinaryTree
|
||||||
{
|
{
|
||||||
@ -59,13 +69,13 @@ class MxBinaryTree
|
|||||||
|
|
||||||
void LeftRotate(TreeNode *);
|
void LeftRotate(TreeNode *);
|
||||||
void RightRotate(TreeNode *);
|
void RightRotate(TreeNode *);
|
||||||
void FUN_100ad4d0(TreeNode **, TreeNode *, TreeNode *, TreeValue *&);
|
void Insert(TreeNode **, TreeNode *, TreeNode *, TreeValue *&);
|
||||||
TreeNode *Search(TreeValue *&);
|
TreeNode *Search(TreeValue *&);
|
||||||
|
|
||||||
int m_p0; // +0
|
int m_p0; // +0
|
||||||
TreeNode *m_root; // +4
|
TreeNode *m_root; // +4
|
||||||
int m_p2; // +8
|
int m_p2; // +8
|
||||||
int m_p3; // +c
|
int m_nodeCount; // +c
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //MXBINARYTREE_H
|
#endif //MXBINARYTREE_H
|
||||||
Loading…
Reference in New Issue
Block a user