parent
43e73ebb1e
commit
56a8fd12be
@ -0,0 +1,130 @@
|
||||
import uuid
|
||||
from typing import Optional, List, Dict, Callable
|
||||
|
||||
from base import Transform2D, Vector2D
|
||||
from pygame import Surface
|
||||
|
||||
|
||||
class Node:
|
||||
|
||||
def __init__(self, name: str = ""):
|
||||
self._id = str(uuid.uuid4())
|
||||
self.name = name or f"Node_{self._id[:8]}"
|
||||
self.parent: Optional[Node] = None
|
||||
self.children: List[Node] = []
|
||||
self._is_in_tree = False
|
||||
self._ready_called = False
|
||||
self._process_enabled = False
|
||||
self._physics_process_enabled = False
|
||||
self.signals: Dict[str, List[Callable]] = {}
|
||||
|
||||
def _enter_tree(self):
|
||||
self.enter_tree()
|
||||
self._is_in_tree = True
|
||||
for child in self.children:
|
||||
child._enter_tree()
|
||||
|
||||
def _exit_tree(self):
|
||||
self.exit_tree()
|
||||
self._is_in_tree = False
|
||||
for child in self.children:
|
||||
child._exit_tree()
|
||||
|
||||
def _ready(self):
|
||||
if not self._ready_called:
|
||||
self._ready_called = True
|
||||
self.ready()
|
||||
for child in self.children:
|
||||
child._ready()
|
||||
|
||||
def _process(self, delta: float):
|
||||
if not self._process_enabled:
|
||||
return
|
||||
self.process(delta)
|
||||
for child in self.children:
|
||||
child._process(delta)
|
||||
|
||||
def _physics_process(self, delta: float):
|
||||
if not self._process_enabled:
|
||||
return
|
||||
self.physics_process(delta)
|
||||
for child in self.children:
|
||||
child._physics_process(delta)
|
||||
|
||||
def _unhandled_input(self, event):pass
|
||||
def _unhandled_key_input(self, event):pass
|
||||
|
||||
"""
|
||||
def _draw(self, surface: Surface):
|
||||
if self._visible:
|
||||
self.draw(surface)
|
||||
for child in self.children:
|
||||
child._draw(surface)
|
||||
"""
|
||||
|
||||
def enter_tree(self): pass
|
||||
def exit_tree(self): pass
|
||||
def ready(self): pass
|
||||
def process(self, delta: float): pass
|
||||
def physics_process(self, delta: float): pass
|
||||
# def draw(self, surface: Surface): pass
|
||||
|
||||
def add_child(self, node: 'Node'):
|
||||
if node.parent:
|
||||
node.parent.remove_child(node)
|
||||
self.children.append(node)
|
||||
node.parent = self
|
||||
|
||||
def remove_child(self, node: 'Node'):
|
||||
if node in self.children:
|
||||
self.children.remove(node)
|
||||
node.parent = None
|
||||
|
||||
def get_node(self, path: str) -> Optional['Node']:
|
||||
if path == ".":
|
||||
return self
|
||||
|
||||
parts = path.split("/")
|
||||
current = self
|
||||
|
||||
for part in parts:
|
||||
if part == "..":
|
||||
current = current.parent
|
||||
if not current:
|
||||
return None
|
||||
else:
|
||||
found = False
|
||||
for child in current.children:
|
||||
if child.name == part:
|
||||
current = child
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
return None
|
||||
return current
|
||||
|
||||
return current
|
||||
|
||||
def connect(self, signal: str, callback: Callable):
|
||||
if signal not in self.signals:
|
||||
self.signals[signal] = []
|
||||
self.signals[signal].append(callback)
|
||||
|
||||
def emit(self, signal: str, *args):
|
||||
if signal in self.signals:
|
||||
for callback in self.signals[signal]:
|
||||
callback(*args)
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
"type": self.__class__.__name__,
|
||||
"name": self.name,
|
||||
"children": [child.to_dict() for child in self.children],
|
||||
}
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> 'Node':
|
||||
node = cls(data["name"])
|
||||
for child_data in data["children"]:
|
||||
child = Node.from_dict(child_data)
|
||||
node.add_child(child)
|
||||
return node
|
||||
Loading…
Reference in new issue