Skip to content

Commit 5c1455c

Browse files
committed
TypeTreeNode - fix from_list, impl to_dict, to_dict_list and add tests
1 parent 22b2637 commit 5c1455c

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

UnityPy/helpers/TypeTreeNode.py

+40-2
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,28 @@ def __attrs_post_init__(self):
3535
self._clean_name = clean_name(self.m_Name)
3636

3737

38+
TYPETREENODE_KEYS = [
39+
"m_Level",
40+
"m_Type",
41+
"m_Name",
42+
"m_ByteSize",
43+
"m_Version",
44+
"m_Children",
45+
"m_TypeFlags",
46+
"m_VariableCount",
47+
"m_Index",
48+
"m_MetaFlag",
49+
"m_RefTypeHash",
50+
]
51+
52+
3853
class TypeTreeNode(TypeTreeNodeC):
3954
def traverse(self) -> Iterator[TypeTreeNode]:
4055
stack: list[TypeTreeNode] = [self]
4156
while stack:
4257
node = stack.pop()
43-
stack.extend(reversed(node.m_Children))
4458
yield node
59+
stack.extend(reversed(node.m_Children))
4560

4661
@classmethod
4762
def parse(cls, reader: EndianBinaryReader, version: int) -> TypeTreeNode:
@@ -132,7 +147,7 @@ def from_list(cls, nodes: List[dict]) -> TypeTreeNode:
132147

133148
for node in nodes:
134149
if isinstance(node, dict):
135-
node = cls(node)
150+
node = cls(**node)
136151

137152
if node.m_Level > prev.m_Level:
138153
stack.append(parent)
@@ -224,6 +239,22 @@ def dump_structure(self, indent: str = " ") -> str:
224239
sb.append(child.dump_structure(indent + " "))
225240
return "\n".join(sb)
226241

242+
def to_dict(self) -> dict:
243+
return {
244+
key: value
245+
for key, value in ((key, getattr(self, key)) for key in TYPETREENODE_KEYS)
246+
if value is not None
247+
}
248+
249+
def to_dict_list(self) -> List[dict]:
250+
return [
251+
self.to_dict(),
252+
*(item for child in self.m_Children for item in child.to_dict_list()),
253+
]
254+
255+
def __eq__(self, other: TypeTreeNode) -> bool:
256+
return self.to_dict() == other.to_dict() and self.m_Children == other.m_Children
257+
227258

228259
COMMONSTRING_CACHE: Dict[Optional[UnityVersion], Dict[int, str]] = {}
229260

@@ -284,3 +315,10 @@ def clean_name(name: str) -> str:
284315
if name[0].isdigit():
285316
name = f"x{name}"
286317
return name
318+
319+
320+
__all__ = (
321+
"TypeTreeNode",
322+
"get_common_strings",
323+
"clean_name",
324+
)

tests/test_typetree.py

+10
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,16 @@ def test_class_node_clz():
197197
assert re_value == TEST_CLASS_NODE_OBJ
198198

199199

200+
def test_node_from_list_clz():
201+
node = TypeTreeNode.from_list(list(TEST_CLASS_NODE.traverse()))
202+
assert node == TEST_CLASS_NODE
203+
204+
205+
def test_node_from_list_dict():
206+
node = TypeTreeNode.from_list(TEST_CLASS_NODE.to_dict_list())
207+
assert node == TEST_CLASS_NODE
208+
209+
200210
if __name__ == "__main__":
201211
for x in list(locals()):
202212
if str(x)[:4] == "test":

0 commit comments

Comments
 (0)