Skip to content
This repository was archived by the owner on Nov 27, 2022. It is now read-only.

Commit 307bc08

Browse files
committed
initial work on adding specs
1 parent acea20d commit 307bc08

File tree

11 files changed

+404
-0
lines changed

11 files changed

+404
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ legion_2_4 = { package = "legion", version = "0.2.4" }
1818
bevy_ecs = "0.1"
1919
hecs = "0.2"
2020
shipyard = "0.4"
21+
specs = "0.16.1"
2122

2223
[dev-dependencies]
2324
criterion = "0.3"

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ pub mod bevy;
44
pub mod legion;
55
pub mod legion_2_4;
66
pub mod shipyard;
7+
pub mod specs;

src/specs/add_remove.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use specs::prelude::*;
2+
3+
struct A(f32);
4+
impl Component for A {
5+
type Storage = VecStorage<Self>;
6+
}
7+
struct B(f32);
8+
impl Component for B {
9+
type Storage = VecStorage<Self>;
10+
}
11+
12+
pub struct Benchmark(World, Vec<Entity>);
13+
14+
impl Benchmark {
15+
pub fn new() -> Self {
16+
let mut world = World::default();
17+
world.register::<A>();
18+
let entities = (0..10000)
19+
.map(|_| world.create_entity().with(A(0.0)).build())
20+
.collect();
21+
world.register::<B>();
22+
Self(world, entities)
23+
}
24+
25+
pub fn run(&mut self) {
26+
let mut b_storage = self.0.write_storage::<B>();
27+
for entity in &self.1 {
28+
b_storage.insert(*entity, B(0.0));
29+
}
30+
31+
for entity in &self.1 {
32+
b_storage.remove(*entity);
33+
}
34+
}
35+
}

src/specs/frag_iter.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use specs::prelude::*;
2+
3+
macro_rules! create_entities {
4+
($world:ident; $( $variants:ident ),*) => {
5+
$(
6+
struct $variants(f32);
7+
impl Component for $variants {
8+
type Storage = DenseVecStorage<Self>;
9+
}
10+
(0..20)
11+
.for_each(|_| {$world.create_entity().with($variants(0.0)).with(Data(1.0)).build();});
12+
)*
13+
};
14+
}
15+
16+
struct Data(f32);
17+
impl Component for Data {
18+
type Storage = VecStorage<Self>;
19+
}
20+
21+
struct FragIterSystem;
22+
23+
impl<'a> System<'a> for FragIterSystem {
24+
type SystemData = WriteStorage<'a, Data>;
25+
26+
fn run(&mut self, mut data_storage: Self::SystemData) {
27+
for mut data in (&mut data_storage).join() {
28+
data.0 *= 2.0;
29+
}
30+
}
31+
}
32+
pub struct Benchmark(World, FragIterSystem);
33+
34+
impl Benchmark {
35+
pub fn new() -> Self {
36+
let mut world = World::default();
37+
38+
create_entities!(world; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);
39+
40+
Self(world, FragIterSystem)
41+
}
42+
43+
pub fn run(&mut self) {
44+
self.1.run_now(&self.0)
45+
}
46+
}

src/specs/heavy_compute.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use cgmath::*;
2+
use specs::prelude::*;
3+
4+
#[derive(Copy, Clone)]
5+
struct Position(Vector3<f32>);
6+
7+
#[derive(Copy, Clone)]
8+
struct Rotation(Vector3<f32>);
9+
10+
#[derive(Copy, Clone)]
11+
struct Velocity(Vector3<f32>);
12+
13+
pub struct Benchmark(World, Query<(Write<Position>, Write<Matrix4<f32>>)>);
14+
15+
impl Benchmark {
16+
pub fn new() -> Self {
17+
let mut world = World::default();
18+
19+
world.extend((0..1000).map(|_| {
20+
(
21+
Matrix4::<f32>::from_angle_x(Rad(1.2)),
22+
Position(Vector3::unit_x()),
23+
Rotation(Vector3::unit_x()),
24+
Velocity(Vector3::unit_x()),
25+
)
26+
}));
27+
world.pack(PackOptions::force());
28+
29+
let query = <(Write<Position>, Write<Matrix4<f32>>)>::query();
30+
31+
Self(world, query)
32+
}
33+
34+
pub fn run(&mut self) {
35+
self.1.par_for_each_mut(&mut self.0, |(pos, mat)| {
36+
for _ in 0..100 {
37+
*mat = mat.invert().unwrap();
38+
}
39+
pos.0 = mat.transform_vector(pos.0);
40+
});
41+
}
42+
}

src/specs/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pub mod add_remove;
2+
pub mod frag_iter;
3+
pub mod heavy_compute;
4+
pub mod schedule;
5+
pub mod serialize_binary;
6+
pub mod serialize_text;
7+
pub mod simple_insert;
8+
pub mod simple_iter;

src/specs/schedule.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use legion::*;
2+
use storage::PackOptions;
3+
4+
struct A(f32);
5+
struct B(f32);
6+
struct C(f32);
7+
struct D(f32);
8+
struct E(f32);
9+
10+
#[system(for_each)]
11+
fn ab(a: &mut A, b: &mut B) {
12+
std::mem::swap(&mut a.0, &mut b.0);
13+
}
14+
15+
#[system(for_each)]
16+
fn cd(c: &mut C, d: &mut D) {
17+
std::mem::swap(&mut c.0, &mut d.0);
18+
}
19+
20+
#[system(for_each)]
21+
fn ce(c: &mut C, e: &mut E) {
22+
std::mem::swap(&mut c.0, &mut e.0);
23+
}
24+
25+
pub struct Benchmark(World, Resources, Schedule);
26+
27+
impl Benchmark {
28+
pub fn new() -> Self {
29+
let mut world = World::default();
30+
31+
world.extend((0..10000).map(|_| (A(0.0), B(0.0))));
32+
33+
world.extend((0..10000).map(|_| (A(0.0), B(0.0), C(0.0))));
34+
35+
world.extend((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), D(0.0))));
36+
37+
world.extend((0..10000).map(|_| (A(0.0), B(0.0), C(0.0), E(0.0))));
38+
39+
world.pack(PackOptions::force());
40+
41+
let schedule = Schedule::builder()
42+
.add_system(ab_system())
43+
.add_system(cd_system())
44+
.add_system(ce_system())
45+
.build();
46+
47+
Self(world, Resources::default(), schedule)
48+
}
49+
50+
pub fn run(&mut self) {
51+
self.2.execute(&mut self.0, &mut self.1);
52+
}
53+
}

src/specs/serialize_binary.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use legion::*;
2+
use serde::{de::DeserializeSeed, Deserialize, Serialize};
3+
4+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
5+
struct Transform([f32; 16]);
6+
7+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
8+
struct Position {
9+
x: f32,
10+
y: f32,
11+
z: f32,
12+
}
13+
14+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
15+
struct Rotation {
16+
x: f32,
17+
y: f32,
18+
z: f32,
19+
}
20+
21+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
22+
struct Velocity {
23+
x: f32,
24+
y: f32,
25+
z: f32,
26+
}
27+
28+
pub struct Benchmark(World, Registry<u8>);
29+
30+
impl Benchmark {
31+
pub fn new() -> Self {
32+
let mut world = World::default();
33+
34+
world.extend(
35+
(
36+
vec![Transform::default(); 1000],
37+
vec![Position::default(); 1000],
38+
vec![Rotation::default(); 1000],
39+
vec![Velocity::default(); 1000],
40+
)
41+
.into_soa(),
42+
);
43+
44+
let mut registry = Registry::default();
45+
registry.register::<Transform>(0);
46+
registry.register::<Position>(1);
47+
registry.register::<Rotation>(2);
48+
registry.register::<Velocity>(3);
49+
50+
Self(world, registry)
51+
}
52+
53+
pub fn run(&mut self) {
54+
let Self(world, registry) = self;
55+
let serializable = &world.as_serializable(any(), &*registry);
56+
57+
let encoded = bincode::serialize(serializable).unwrap();
58+
59+
use bincode::config::Options;
60+
let mut deserializer = bincode::de::Deserializer::from_slice(
61+
&encoded[..],
62+
bincode::config::DefaultOptions::new()
63+
.with_fixint_encoding()
64+
.allow_trailing_bytes(),
65+
);
66+
67+
registry
68+
.as_deserialize()
69+
.deserialize(&mut deserializer)
70+
.unwrap();
71+
}
72+
}

src/specs/serialize_text.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use legion::*;
2+
use serde::{de::DeserializeSeed, Deserialize, Serialize};
3+
4+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
5+
struct Transform([f32; 16]);
6+
7+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
8+
struct Position {
9+
x: f32,
10+
y: f32,
11+
z: f32,
12+
}
13+
14+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
15+
struct Rotation {
16+
x: f32,
17+
y: f32,
18+
z: f32,
19+
}
20+
21+
#[derive(Default, Copy, Clone, Serialize, Deserialize)]
22+
struct Velocity {
23+
x: f32,
24+
y: f32,
25+
z: f32,
26+
}
27+
28+
pub struct Benchmark(World, Registry<u8>);
29+
30+
impl Benchmark {
31+
pub fn new() -> Self {
32+
let mut world = World::default();
33+
34+
world.extend(
35+
(
36+
vec![Transform::default(); 1000],
37+
vec![Position::default(); 1000],
38+
vec![Rotation::default(); 1000],
39+
vec![Velocity::default(); 1000],
40+
)
41+
.into_soa(),
42+
);
43+
44+
let mut registry = Registry::default();
45+
registry.register::<Transform>(0);
46+
registry.register::<Position>(1);
47+
registry.register::<Rotation>(2);
48+
registry.register::<Velocity>(3);
49+
50+
Self(world, registry)
51+
}
52+
53+
pub fn run(&mut self) {
54+
let Self(world, registry) = self;
55+
let serializable = &world.as_serializable(any(), &*registry);
56+
57+
let serialized = ron::ser::to_string(serializable).unwrap();
58+
59+
let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap();
60+
registry
61+
.as_deserialize()
62+
.deserialize(&mut deserializer)
63+
.unwrap();
64+
}
65+
}

src/specs/simple_insert.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use cgmath::*;
2+
use legion::*;
3+
4+
#[derive(Copy, Clone)]
5+
struct Transform(Matrix4<f32>);
6+
7+
#[derive(Copy, Clone)]
8+
struct Position(Vector3<f32>);
9+
10+
#[derive(Copy, Clone)]
11+
struct Rotation(Vector3<f32>);
12+
13+
#[derive(Copy, Clone)]
14+
struct Velocity(Vector3<f32>);
15+
16+
pub struct Benchmark;
17+
18+
impl Benchmark {
19+
pub fn new() -> Self {
20+
Self
21+
}
22+
23+
pub fn run(&mut self) {
24+
let mut world = World::default();
25+
26+
world.extend(
27+
(
28+
vec![Transform(Matrix4::from_scale(1.0)); 10000],
29+
vec![Position(Vector3::unit_x()); 10000],
30+
vec![Rotation(Vector3::unit_x()); 10000],
31+
vec![Velocity(Vector3::unit_x()); 10000],
32+
)
33+
.into_soa(),
34+
);
35+
}
36+
}

0 commit comments

Comments
 (0)