4个版本
0.1.3 | 2023年7月31日 |
---|---|
0.1.2 | 2023年6月30日 |
0.1.1 | 2023年6月28日 |
0.1.0 | 2023年6月27日 |
#331 in 游戏开发
34 每月下载量
69KB
1.5K SLoC
一个小巧的实体-组件-系统库
-
更少的依赖项
-
快速构建
-
易于使用
Hello World
// a function-system
fn hello_world() {
println!("Hello World")
}
fn main() {
// create a world
let mut world = tecs::World::new();
world
// add "hello world" system into world's start_up_systems
// startup_systems will only run once
.add_startup_system(hello_world)
// make the loop run once only
.run_until(|| true);
}
将组件添加到世界
您可以使用 spawn
方法将实现了 Bundle
或 Component
特性的任何类型添加到世界中
use tecs::tools::Command;
let mut world = tecs::World::new();
world.spawn(12345);
world.spawn("abcde");
您可以轻松推导 Bundle
和 Component
特性
Component
只是一个标记,它可以用于任何类型
use tecs::bundle::Component;
#[derive(Component)]
struct MyComponent{
name : String,
}
Bundle
的所有字段都应该实现 Component
use tecs::bundle::Bundle;
#[derive(Bundle)]
struct MyBundle{
inner : MyComponent,
}
Component
默认以下类型实现
- usize,u8,u16,u32,u64
- isize,i8,i16,i32,i64
- (),bool,&'static str
Bundle
默认为所有只包含实现了 Component
特性的类型的元组实现
例如
- (usize,&str)
在世界上查询组件
直接使用 Query
use tecs::world::Query;
use tecs::tool::Command;
let mut world = tecs::World::new();
// add two `Bundle` into world
world.spawn(12345);
world.spawn((54321,"abcde"));
// create a `Query` to get all i32'a refence
let query = Query::<&i32>::new(&mut world);
for item in query {
println!("{item}")
}
// this code will print:
// 12345
// 54321
或使用系统
use tecs::world::{Query,Commands};
use tecs::tool::Command;
// use command to do spawn
fn do_spawn(mut commands: Commands){
commands.spawn(12345);
commands.spawn((54321,"abcde"));
}
// note: you cant use conflict Query in one system, or the program will panic when you add system into world
// a example of conflict Query: Query<&i32> and Query<&mut i32>
fn print_all_i23(mut query : Query<&i32>){
for item in query {
println!("{item}")
}
}
world.add_startup_system(do_spawn);
world.add_startup_system(print_all_i23);
world.run_until(||true);
Query
是一个接收两个泛型的类型
pub struct Query<'a, F: WorldFetch, Q: WorldFilter = ()> {...}
WorldFetch 用于在世界上获取组件
它可以是组件的(不可变/可变)引用,或者只包含 WorldFetch 的元组
WorldFilter 用于在世界上获取 Bundle
它可以是
-
All 或 All<(Component1,Component1,...)> 以过滤包含所有组件的 Bundle
-
OneOf 或 OneOf<(Component1,Component1,...)> 以过滤包含至少一个组件的 Bundle
-
Not 或 Not<(Component1,Component1,...)> 以过滤不包含任何组件的 Bundle
示例
-
Query<&i32>
将查询包含i32
组件的所有组件,并在迭代器中提供i32
的不可变引用 -
使用
Query<&mut i32>
使迭代器提供i32
的可变引用 -
使用
Query<&i32,All<&str>>
将查询包含i32
和&str
的所有组件,并在迭代器中提供i32
的不可变引用 -
使用
Query<&i32,AnyOf<(&str,MyComponent)>>
将查询包含i32
、&str
和MyComponent
的所有组件,并在迭代器中提供i32
的不可变引用 -
使用
Query<&i32,All<&str>>
将查询包含i32
且不包含&str
的所有组件,并在迭代器中提供i32
的不可变引用
迭代器
可以使用 for 循环获取查询结果,fetch
的类型为 WorldFetch
for fetch in query {}
可以使用 for 循环和 .into_iter() 方法获取查询结果,以及结果的 Entity
for e in query.into_eiter() {}
e
的类型为 EBundle
pub struct EBundle<'a, F: WorldFetch> {...}
可以通过解引用 e
获取查询结果,使用 .entity() 方法获取结果的 Entity
Entity
可用于移除已查询的包
commands.remove(b.entity());
资源
资源按类型存储在世界类型中
use tecs::tools::ResManager;
let mut world = tecs::World::new();
// get resources usize, and init it to 1
world.get_res<usize>().get_or_init(||1);
assert_eq!(*world.get_res<usize>().get().unwrap(),1);
功能:系统
此功能非常有用
默认启用此功能
此功能允许在世界中运行系统以访问资源和组件
本版本仅支持功能系统
所有实现 SystemParm
特质的类型都可以作为功能系统的参数
以下类型实现了 SystemParm
特质
您可以在 tecs::world
模块中找到它们
类型 | 用法 | 注意 |
---|---|---|
Res | 在世界中获取类型为 T 的资源 | 一个系统中不能使用相同的 Res |
Resources | 在世界中获取任何类型的资源 | 不能与一个系统中的任何 Res 一起使用 |
Query |
查询世界中的组件 | 一个系统中不能使用冲突查询,如 Query<&T> 和 Query<&mut T> |
命令 | 向世界中添加和删除包 | 使用 spawn_many() 方法快速创建具有相同类型的多个包 |
要运行系统,您需要使用 .add_system()
方法或 .add_startup_system()
方法首先将系统添加到世界中
- 所有启动系统都只运行一次
- 系统运行预循环
要在世界中运行系统,您可以使用
-
使用
.startup()
方法运行所有启动系统 -
使用
.run_once()
方法一次性运行所有系统(不包括启动系统) -
使用
.run()
方法多次运行所有系统,该方法不会返回 -
使用
.run_until(f)
方法多次运行所有系统,当f
返回true
时循环将中断
特性:异步
默认情况下此特性是禁用的
此特性允许你在世界中运行异步函数系统
此特性使得你只能将异步函数系统添加到世界中,原因如下
note: upstream crates may add a new impl of trait `std::future::Future` for type `()` in future versions
‘.startup’、‘.run_once’、‘.run’、‘.run_until’ 方法变为异步函数
依赖关系
约300-740KB
约18K SLoC