Skip to content

Commit fed8209

Browse files
committed
send entities data to render thread
1 parent e438897 commit fed8209

13 files changed

+375
-46
lines changed

assets/textures/yv.png

-3.68 KB
Loading

flamegraph.sh

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
3+
APP=ecs
4+
5+
declare -r F=/usr/local/src/FlameGraph
6+
set -x
7+
./$APP $@ &>/dev/null&
8+
sudo perf record -F 80 -a -g -p $! -- sleep 60
9+
sudo perf script > /tmp/out.perf
10+
$F/stackcollapse-perf.pl /tmp/out.perf > /tmp/out.folded
11+
$F/flamegraph.pl /tmp/out.folded > /tmp/out.svg
12+
firefox /tmp/out.svg&
13+
pkill $APP

src/alloc/generational_allocator.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
use std::vec::Vec;
22

3-
#[derive(Default, Copy, Clone, Debug, PartialEq)]
3+
#[derive(Default, Copy, Clone, Debug, PartialEq, Hash)]
44
pub struct Generational_Index {
55
pub index: usize,
66
pub gen: u64,
77
}
88

9+
impl Eq for Generational_Index {}
10+
911
/// Generational_Allocator provides an interface to allocate/deallocate
1012
/// Generational Indices and check if an index is valid.
1113
/// The allocator is given an initial size and grows automatically when
@@ -45,7 +47,7 @@ impl Generational_Allocator {
4547

4648
pub fn allocate(&mut self) -> Generational_Index {
4749
let i = self.first_free_slot();
48-
let cur_size = self.gens.len();
50+
let cur_size = self.gens.len();
4951
if i == cur_size {
5052
// Grow the vectors
5153
let new_size = cur_size * 2;

src/core/app.rs

+34-5
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ use super::input;
66
use super::time;
77
use crate::audio;
88
use crate::cfg;
9+
use crate::ecs::components::gfx::C_Camera2D;
10+
use crate::ecs::components::transform::C_Transform2D;
11+
use crate::ecs::entity_manager::Entity;
912
use crate::fs;
1013
use crate::game::gameplay_system;
1114
use crate::gfx;
1215
use crate::resources;
16+
use std::collections::HashMap;
1317
use std::convert::TryFrom;
1418
use std::sync::mpsc;
1519
use std::thread::JoinHandle;
@@ -55,13 +59,14 @@ pub struct App<'r> {
5559
env: Env_Info,
5660

5761
config: cfg::Config,
58-
ui_req_tx: Option<std::sync::mpsc::Sender<gfx::ui::UI_Request>>,
62+
ui_req_tx: Option<mpsc::Sender<gfx::ui::UI_Request>>,
5963

6064
// Resources
6165
audio_resources: resources::audio::Audio_Resources<'r>,
6266

6367
// Engine Systems
6468
render_thread: Option<JoinHandle<()>>,
69+
render_thread_quit: Option<mpsc::Sender<()>>,
6570
input_actions_rx: Option<mpsc::Receiver<input::Action_List>>,
6671
audio_system: audio::system::Audio_System,
6772
gameplay_system: gameplay_system::Gameplay_System,
@@ -80,6 +85,7 @@ impl<'r> App<'r> {
8085
ui_req_tx: None,
8186
audio_resources: resources::audio::Audio_Resources::new(sound_loader),
8287
render_thread: None,
88+
render_thread_quit: None,
8389
input_actions_rx: None,
8490
audio_system: audio::system::Audio_System::new(10),
8591
gameplay_system: gameplay_system::Gameplay_System::new(),
@@ -99,8 +105,6 @@ impl<'r> App<'r> {
99105
}
100106

101107
fn init_all_systems(&mut self) -> Maybe_Error {
102-
self.gameplay_system.init(&self.config)?;
103-
104108
let config_watcher = Box::new(cfg::sync::Config_Watch_Handler::new(&self.config));
105109
fs::file_watcher::start_file_watch(
106110
self.env.get_cfg_root().to_path_buf(),
@@ -110,25 +114,39 @@ impl<'r> App<'r> {
110114
Ok(())
111115
}
112116

113-
fn start_render_thread(&mut self) {
117+
fn start_render_thread(
118+
&mut self,
119+
entity_transform_rx: mpsc::Receiver<(Entity, C_Transform2D)>,
120+
camera_transform_rx: mpsc::Receiver<C_Camera2D>,
121+
) {
114122
let (input_tx, input_rx) = mpsc::channel();
115123
self.input_actions_rx = Some(input_rx);
116124

117125
let (ui_tx, ui_rx) = mpsc::channel();
118126
self.ui_req_tx = Some(ui_tx);
119127

128+
let (quit_tx, quit_rx) = mpsc::channel();
129+
self.render_thread_quit = Some(quit_tx);
130+
120131
self.render_thread = Some(gfx::render_system::start_render_thread(
121132
self.env.clone(),
122133
input_tx,
123134
ui_rx,
135+
entity_transform_rx,
136+
camera_transform_rx,
137+
quit_rx,
124138
gfx::render_system::Render_System_Config {
125139
clear_color: colors::rgb(48, 10, 36),
126140
},
127141
));
128142
}
129143

130144
pub fn run(&mut self) -> Maybe_Error {
131-
self.start_render_thread();
145+
let (et_tx, et_rx) = mpsc::channel();
146+
let (cam_tx, cam_rx) = mpsc::channel();
147+
self.gameplay_system.init(&self.config, et_tx, cam_tx)?; // @Temporary workaround
148+
self.start_render_thread(et_rx, cam_rx);
149+
132150
self.start_game_loop()?;
133151
Ok(())
134152
}
@@ -193,6 +211,17 @@ impl<'r> App<'r> {
193211
}
194212
}
195213

214+
self.render_thread_quit
215+
.as_mut()
216+
.unwrap()
217+
.send(())
218+
.expect("[ ERR ] Failed to send quit message to render thread!");
219+
self.render_thread
220+
.take()
221+
.unwrap()
222+
.join()
223+
.expect("[ ERR ] Failed to join render thread!");
224+
196225
Ok(())
197226
}
198227

src/core/common/vector.rs

+5
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,8 @@ pub type Vec2i = Vector2<i32>;
1010
pub fn to_framework_vec(v: Vec2f) -> sfml::system::Vector2f {
1111
sfml::system::Vector2f::new(v.x, v.y)
1212
}
13+
14+
#[cfg(feature = "use-sfml")]
15+
pub fn from_framework_vec(v: sfml::system::Vector2f) -> Vec2f {
16+
Vec2f::new(v.x, v.y)
17+
}

src/ecs/components/gfx.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::transform::C_Transform2D;
12
use crate::core::common::rect::Rect;
23
use crate::resources;
34
use typename::TypeName;
@@ -23,3 +24,8 @@ pub struct C_Animated_Sprite {
2324
pub frame_time: f32,
2425
pub frame_time_elapsed: f32,
2526
}
27+
28+
#[derive(Copy, Clone, Debug, TypeName, Default)]
29+
pub struct C_Camera2D {
30+
pub transform: C_Transform2D,
31+
}

src/ecs/components/transform.rs

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::core::common::vector::Vec2f;
2-
use cgmath::Rad;
2+
use cgmath::{Matrix3, Rad};
33
use std::convert::Into;
44
use typename::TypeName;
55

@@ -8,6 +8,7 @@ pub struct C_Transform2D {
88
position: Vec2f,
99
rotation: Rad<f32>,
1010
scale: Vec2f,
11+
origin: Vec2f,
1112
}
1213

1314
impl Default for C_Transform2D {
@@ -16,6 +17,7 @@ impl Default for C_Transform2D {
1617
position: Vec2f::new(0.0, 0.0),
1718
rotation: Rad(0.0),
1819
scale: Vec2f::new(1.0, 1.0),
20+
origin: Vec2f::new(0.0, 0.0),
1921
}
2022
}
2123
}
@@ -69,6 +71,40 @@ impl C_Transform2D {
6971
pub fn rotation(&self) -> Rad<f32> {
7072
self.rotation
7173
}
74+
75+
pub fn set_origin(&mut self, x: f32, y: f32) {
76+
self.origin = Vec2f::new(x, y);
77+
}
78+
79+
pub fn get_matrix(&self) -> Matrix3<f32> {
80+
let Rad(angle) = self.rotation.into();
81+
let angle = -angle;
82+
let cosine = angle.cos();
83+
let sine = angle.sin();
84+
let sxc = self.scale.x * cosine;
85+
let syc = self.scale.y * cosine;
86+
let sxs = self.scale.x * sine;
87+
let sys = self.scale.y * sine;
88+
let tx = -self.origin.x * sxc - self.origin.y * sys + self.position.x;
89+
let ty = self.origin.x * sxs - self.origin.y * syc + self.position.y;
90+
91+
Matrix3::new(sxc, sys, tx, -sxs, syc, ty, 0.0, 0.0, 1.0)
92+
}
93+
94+
pub fn get_matrix_sfml(&self) -> sfml::graphics::Transform {
95+
let Rad(angle) = self.rotation.into();
96+
let angle = -angle;
97+
let cosine = angle.cos();
98+
let sine = angle.sin();
99+
let sxc = self.scale.x * cosine;
100+
let syc = self.scale.y * cosine;
101+
let sxs = self.scale.x * sine;
102+
let sys = self.scale.y * sine;
103+
let tx = -self.origin.x * sxc - self.origin.y * sys + self.position.x;
104+
let ty = self.origin.x * sxs - self.origin.y * syc + self.position.y;
105+
106+
sfml::graphics::Transform::new(sxc, sys, tx, -sxs, syc, ty, 0.0, 0.0, 1.0)
107+
}
72108
}
73109

74110
#[cfg(test)]

src/ecs/entity_manager.rs

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ pub struct Entity_Manager {
2020
pub type Entity = Generational_Index;
2121
type VecOpt<T> = Vec<Option<RefCell<T>>>;
2222

23+
impl Entity {
24+
pub const INVALID: Entity = Entity {
25+
gen: u64::max_value(),
26+
index: usize::max_value(),
27+
};
28+
}
29+
2330
impl Entity_Manager {
2431
pub fn new() -> Entity_Manager {
2532
Entity_Manager {

src/game/controllable_system.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,36 @@
11
use crate::cfg::Cfg_Var;
2+
use crate::core::common::vector::Vec2f;
23
use crate::core::input;
34
use crate::core::time;
45
use crate::ecs::components::base::C_Spatial2D;
56
use crate::ecs::entity_manager::Entity_Manager;
67
use std::time::Duration;
78
use typename::TypeName;
89

9-
#[derive(Clone, Default, Debug, TypeName)]
10+
#[derive(Clone, Debug, TypeName)]
1011
pub struct C_Controllable {
1112
pub speed: Cfg_Var<f32>,
13+
pub translation_this_frame: Vec2f,
14+
}
15+
16+
impl Default for C_Controllable {
17+
fn default() -> C_Controllable {
18+
C_Controllable {
19+
speed: Cfg_Var::default(),
20+
translation_this_frame: Vec2f::new(0.0, 0.0),
21+
}
22+
}
1223
}
1324

1425
pub fn update(dt: &Duration, actions: &input::Action_List, em: &mut Entity_Manager) {
1526
let movement = input::get_normalized_movement_from_input(actions);
1627
let dt_secs = time::to_secs_frac(&dt);
17-
let controllables = em.get_component_tuple_mut::<C_Spatial2D, C_Controllable>();
28+
let controllables = em.get_components_mut::<C_Controllable>();
1829

19-
for (spatial, ctrl) in controllables {
20-
let speed = *ctrl.borrow().speed;
30+
for mut ctrl in controllables {
31+
let speed = *ctrl.speed;
2132
let velocity = movement * speed;
22-
let mut spatial = spatial.borrow_mut();
2333
let v = velocity * dt_secs;
24-
spatial.velocity.set(v);
25-
spatial.transform.translate_v(v);
34+
ctrl.translation_this_frame = v;
2635
}
2736
}

0 commit comments

Comments
 (0)