在游戏开发领域,Godot 引擎以其直观易用的节点系统而闻名。如今,Rust 开发者也能体验到类似的便利!NodeTree,一个受 Godot 启发的 Rust 极简框架,为构建大型可扩展程序和游戏提供了全新的思路。本文将深入探讨 NodeTree 的核心概念、使用方法以及其带来的优势。
构建程序的全新方式
NodeTree 框架的核心思想是将程序分解成一个进程树,每个进程都是一个独立的单元,被称为“节点”(Node)。这些节点可以存储自身的状态和数据,并与其他节点进行通信,从而协同完成复杂的任务。
构建你的第一个 NodeTree
使用 NodeTree 非常简单。首先,将 node_tree
添加到你的项目依赖中:
cargo add node_tree
接下来,我们需要创建一个根节点。为了减少样板代码,可以使用 NodeTree 提供的 NodeSys
宏来实现必要的 Dynamic
和 NodeAbstract
trait。然后,我们只需要手动实现 Node
trait 即可。
use node_tree::prelude::*;
#[derive(Debug, Abstract)]
pub struct MyNode {
base: NodeBase, // 节点必须包含 NodeBase
}
impl MyNode {
fn new(name: String) -> Self {
MyNode { base: NodeBase::new(name) }
}
}
// 实现 Node trait,定义节点行为
impl Node for MyNode {
// 节点被添加到 NodeTree 时运行一次
fn ready(&mut self) {
// 示例:添加子节点
if self.depth() < 3 {
let new_depth = self.depth() + 1;
self.add_child(MyNode::new(format!("{}_Node", new_depth)));
self.add_child(MyNode::new(format!("{}_Node", new_depth)));
self.add_child(MyNode::new(format!("{}_Node", new_depth)));
}
if self.is_root() {
println!("{:?}", self.children());
}
}
// 每帧运行一次,提供帧间的时间差(秒)
fn process(&mut self, delta: f32) {
// 示例:计算帧率
println!("{} | {}", self.name(), 1f32 / delta);
// 使用 NodePath 和 TreePointer 可以引用 NodeTree 中的其他节点
if self.is_root() {
if let Some(node) = self.get_node::<MyNode>(NodePath::from_str("1_Node/2_Node1/3_Node2")) {
println!("{:?}", node);
}
}
// 节点可以被销毁,销毁后其在 NodeTree 中的引用也会被清理
// 如果根节点被销毁,程序会自动退出
if self.children().is_empty() {
self.free(); // 从树梢到树根逐步销毁节点
}
}
// 节点从 NodeTree 中移除时运行一次,无论程序是否终止
fn terminal(&mut self) {}
// 返回节点的处理模式
// 处理模式控制 NodeTree 暂停/运行时 process() 函数的行为
fn process_mode(&self) -> ProcessMode {
ProcessMode::Inherit // 默认值,继承父节点的行为
}
}
最后,我们需要实例化根节点并将其传递给 NodeTree
构造函数:
// ...之前的代码
use node_tree::trees::tree_simple::TreeSimple;
fn main() -> () {
// 创建树
let root = MyNode::new("Root".to_string());
let tree: Box<TreeSimple> = TreeSimple::new(root, LoggerVerbosity::NoDebug);
// 开始运行
tree.start();
loop {
if tree.process().has_terminated() {
break;
}
}
}
探索更多特性
除了基本的节点管理,NodeTree 还提供了丰富的功能:
灵活的节点通信: owner()
、parent()
、get_child()
、children()
和get_node()
等方法使得节点间通信变得轻而易举。智能指针: Tp<T>
和TpDyn
简化了节点引用,减少了语法噪音。缓存系统: NodeTree 内置缓存系统,提高了 Tp<T>
/TpDyn
的安全性.动态日志系统: 与节点框架深度集成的日志系统方便调试和错误处理。
总结
NodeTree 将 Godot 引擎中广受好评的节点系统引入 Rust,为开发者提供了一种构建大型可扩展程序的全新思路。其简洁易用的 API、丰富的功能以及对性能的关注,使其成为 Rust 游戏开发和其他领域的有力工具。
点击关注并扫码添加进交流群