Remove unsafe Proxy system

This commit is contained in:
Thinkofname 2016-03-27 17:45:12 +01:00
parent e36a0f4579
commit 93c58aad89
5 changed files with 41 additions and 123 deletions

View File

@ -22,6 +22,9 @@ use std::marker::PhantomData;
use std::mem;
use std::ptr;
use world;
use render;
/// Used to reference an entity.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Entity {
@ -71,12 +74,12 @@ impl Filter {
/// A system processes entities
pub trait System {
fn filter(&self) -> &Filter;
fn update(&mut self, m: &mut Manager);
fn update(&mut self, m: &mut Manager, world: &mut world::World, renderer: &mut render::Renderer);
fn entity_added(&mut self, _m: &mut Manager, _e: Entity) {
fn entity_added(&mut self, _m: &mut Manager, _e: Entity, _world: &mut world::World, _renderer: &mut render::Renderer) {
}
fn entity_removed(&mut self, _m: &mut Manager, _e: Entity) {
fn entity_removed(&mut self, _m: &mut Manager, _e: Entity, _world: &mut world::World, _renderer: &mut render::Renderer) {
}
}
@ -142,36 +145,36 @@ impl Manager {
}
/// Ticks all tick systems
pub fn tick(&mut self) {
self.process_entity_changes();
pub fn tick(&mut self, world: &mut world::World, renderer: &mut render::Renderer) {
self.process_entity_changes(world, renderer);
let mut systems = mem::replace(&mut self.systems, unsafe { mem::uninitialized() });
for sys in &mut systems {
sys.update(self);
sys.update(self, world, renderer);
}
mem::forget(mem::replace(&mut self.systems, systems));
self.process_entity_changes();
self.process_entity_changes(world, renderer);
}
/// Ticks all render systems
pub fn render_tick(&mut self) {
self.process_entity_changes();
pub fn render_tick(&mut self, world: &mut world::World, renderer: &mut render::Renderer) {
self.process_entity_changes(world, renderer);
let mut systems = mem::replace(&mut self.render_systems, unsafe { mem::uninitialized() });
for sys in &mut systems {
sys.update(self);
sys.update(self, world, renderer);
}
mem::forget(mem::replace(&mut self.render_systems, systems));
self.process_entity_changes();
self.process_entity_changes(world, renderer);
}
fn process_entity_changes(&mut self) {
fn process_entity_changes(&mut self, world: &mut world::World, renderer: &mut render::Renderer) {
let changes = self.changed_entity_components.clone();
self.changed_entity_components = HashSet::with_hasher(BuildHasherDefault::default());
for entity in changes {
let state = self.entities[entity.id].0.as_mut().unwrap().clone();
self.trigger_add_for_systems(entity, &state.last_components, &state.components);
self.trigger_add_for_render_systems(entity, &state.last_components, &state.components);
self.trigger_remove_for_systems(entity, &state.last_components, &state.components);
self.trigger_remove_for_render_systems(entity, &state.last_components, &state.components);
self.trigger_add_for_systems(entity, &state.last_components, &state.components, world, renderer);
self.trigger_add_for_render_systems(entity, &state.last_components, &state.components, world, renderer);
self.trigger_remove_for_systems(entity, &state.last_components, &state.components, world, renderer);
self.trigger_remove_for_render_systems(entity, &state.last_components, &state.components, world, renderer);
for i in 0 .. self.components.len() {
if !state.components.get(i) && state.last_components.get(i) {
let components = self.components.get_mut(i).and_then(|v| v.as_mut()).unwrap();
@ -245,14 +248,14 @@ impl Manager {
}
/// Deallocates all entities/components excluding the world entity
pub fn remove_all_entities(&mut self) {
pub fn remove_all_entities(&mut self, world: &mut world::World, renderer: &mut render::Renderer) {
for e in &mut self.entities[1..] {
if let Some(set) = e.0.as_mut() {
set.components = BSet::new(self.components.len());
set.removed = true;
}
}
self.process_entity_changes();
self.process_entity_changes(world, renderer);
}
/// Returns whether an entity reference is valid.
@ -315,21 +318,21 @@ impl Manager {
components.add(entity.id, val);
}
fn trigger_add_for_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet) {
fn trigger_add_for_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer) {
let mut systems = mem::replace(&mut self.systems, unsafe { mem::uninitialized() });
for sys in &mut systems {
if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) {
sys.entity_added(self, e);
sys.entity_added(self, e, world, renderer);
}
}
mem::forget(mem::replace(&mut self.systems, systems));
}
fn trigger_add_for_render_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet) {
fn trigger_add_for_render_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer) {
let mut systems = mem::replace(&mut self.render_systems, unsafe { mem::uninitialized() });
for sys in &mut systems {
if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) {
sys.entity_added(self, e);
sys.entity_added(self, e, world, renderer);
}
}
mem::forget(mem::replace(&mut self.render_systems, systems));
@ -374,21 +377,21 @@ impl Manager {
true
}
fn trigger_remove_for_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet) {
fn trigger_remove_for_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer) {
let mut systems = mem::replace(&mut self.systems, unsafe { mem::uninitialized() });
for sys in &mut systems {
if !new_set.includes_set(&sys.filter().bits) && old_set.includes_set(&sys.filter().bits) {
sys.entity_removed(self, e);
sys.entity_removed(self, e, world, renderer);
}
}
mem::forget(mem::replace(&mut self.systems, systems));
}
fn trigger_remove_for_render_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet) {
fn trigger_remove_for_render_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer) {
let mut systems = mem::replace(&mut self.render_systems, unsafe { mem::uninitialized() });
for sys in &mut systems {
if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) {
sys.entity_removed(self, e);
sys.entity_removed(self, e, world, renderer);
}
}
mem::forget(mem::replace(&mut self.render_systems, systems));

View File

@ -101,46 +101,6 @@ impl Bounds {
}
}
/// Hack to allow temp access to a type
pub struct Proxy<T> {
inner: Option<T>,
}
impl <T> ::std::ops::Deref for Proxy<T> {
type Target = T;
fn deref(&self) -> &T {
self.inner.as_ref().unwrap()
}
}
impl <T> ::std::ops::DerefMut for Proxy<T> {
fn deref_mut(&mut self) -> &mut T {
self.inner.as_mut().unwrap()
}
}
impl <T> Proxy<T> {
pub fn new() -> Proxy<T> {
Proxy {
inner: None,
}
}
pub fn give(&mut self, v: &mut T) {
use std::mem;
self.inner = Some(mem::replace(v, unsafe { mem::uninitialized() }));
}
pub fn take(&mut self, v: &mut T) {
use std::mem;
mem::forget(mem::replace(v, self.inner.take().unwrap()));
}
}
pub struct GameInfo {
pub delta: f64,
}

View File

@ -6,10 +6,10 @@ use super::{
Rotation,
Gravity,
Bounds,
Proxy,
GameInfo,
};
use world;
use render;
use types::Gamemode;
use collision::{Aabb, Aabb3};
use cgmath::{self, Point3};
@ -94,7 +94,6 @@ struct MovementHandler {
movement: ecs::Key<PlayerMovement>,
gravity: ecs::Key<Gravity>,
gamemode: ecs::Key<Gamemode>,
world: ecs::Key<Proxy<world::World>>,
position: ecs::Key<Position>,
velocity: ecs::Key<Velocity>,
game_info: ecs::Key<GameInfo>,
@ -119,7 +118,6 @@ impl MovementHandler {
movement: movement,
gravity: m.get_key(),
gamemode: m.get_key(),
world: m.get_key(),
position: position,
velocity: velocity,
game_info: m.get_key(),
@ -135,9 +133,8 @@ impl ecs::System for MovementHandler {
&self.filter
}
fn update(&mut self, m: &mut ecs::Manager) {
fn update(&mut self, m: &mut ecs::Manager, world: &mut world::World, _: &mut render::Renderer) {
let world_entity = m.get_world();
let world: &world::World = m.get_component(world_entity, self.world).unwrap();
let delta = m.get_component(world_entity, self.game_info).unwrap().delta;
for e in m.find(&self.filter) {
let movement = m.get_component_mut(e, self.movement).unwrap();

View File

@ -1,6 +1,8 @@
use super::*;
use ecs;
use world;
use render;
pub struct ApplyVelocity {
filter: ecs::Filter,
@ -30,7 +32,7 @@ impl ecs::System for ApplyVelocity {
&self.filter
}
fn update(&mut self, m: &mut ecs::Manager) {
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
for e in m.find(&self.filter) {
if m.get_component(e, self.movement).is_some() {
// Player's handle their own phyiscs
@ -69,7 +71,7 @@ impl ecs::System for ApplyGravity {
&self.filter
}
fn update(&mut self, m: &mut ecs::Manager) {
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
for e in m.find(&self.filter) {
if m.get_component(e, self.movement).is_some() {
// Player's handle their own phyiscs
@ -107,7 +109,7 @@ impl ecs::System for UpdateLastPosition {
&self.filter
}
fn update(&mut self, m: &mut ecs::Manager) {
fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) {
for e in m.find(&self.filter) {
let pos = m.get_component_mut(e, self.position).unwrap();

View File

@ -50,8 +50,6 @@ pub struct Server {
version: usize,
// Entity accessors
world_proxy: ecs::Key<entity::Proxy<world::World>>,
renderer_proxy: ecs::Key<entity::Proxy<render::Renderer>>,
game_info: ecs::Key<entity::GameInfo>,
player_movement: ecs::Key<entity::player::PlayerMovement>,
gravity: ecs::Key<entity::Gravity>,
@ -189,10 +187,6 @@ impl Server {
entity::add_systems(&mut entities);
let world_entity = entities.get_world();
let world_proxy = entities.get_key();
entities.add_component(world_entity, world_proxy, entity::Proxy::new());
let renderer_proxy = entities.get_key();
entities.add_component(world_entity, renderer_proxy, entity::Proxy::new());
let game_info = entities.get_key();
entities.add_component(world_entity, game_info, entity::GameInfo::new());
@ -214,8 +208,6 @@ impl Server {
pressed_keys: HashMap::with_hasher(BuildHasherDefault::default()),
// Entity accessors
world_proxy: world_proxy,
renderer_proxy: renderer_proxy,
game_info: game_info,
player_movement: entities.get_key(),
gravity: entities.get_key(),
@ -266,13 +258,6 @@ impl Server {
fn entity_tick(&mut self, renderer: &mut render::Renderer, delta: f64) {
let world_entity = self.entities.get_world();
// Borrow the world and renderer
self.entities.get_component_mut(world_entity, self.world_proxy)
.unwrap()
.give(&mut self.world);
self.entities.get_component_mut(world_entity, self.renderer_proxy)
.unwrap()
.give(renderer);
// Update the game's state for entities to read
self.entities.get_component_mut(world_entity, self.game_info)
.unwrap().delta = delta;
@ -301,40 +286,15 @@ impl Server {
self.entity_tick_timer += delta;
while self.entity_tick_timer >= 3.0 && self.is_connected() {
self.entities.tick();
self.entities.tick(&mut self.world, renderer);
self.entity_tick_timer -= 3.0;
}
self.entities.render_tick();
// Return what we borrowed
self.entities.get_component_mut(world_entity, self.world_proxy)
.unwrap()
.take(&mut self.world);
self.entities.get_component_mut(world_entity, self.renderer_proxy)
.unwrap()
.take(renderer);
self.entities.render_tick(&mut self.world, renderer);
}
pub fn remove(&mut self, renderer: &mut render::Renderer) {
let world_entity = self.entities.get_world();
// Borrow the world and renderer
self.entities.get_component_mut(world_entity, self.world_proxy)
.unwrap()
.give(&mut self.world);
self.entities.get_component_mut(world_entity, self.renderer_proxy)
.unwrap()
.give(renderer);
self.entities.remove_all_entities();
// Return what we borrowed
self.entities.get_component_mut(world_entity, self.world_proxy)
.unwrap()
.take(&mut self.world);
self.entities.get_component_mut(world_entity, self.renderer_proxy)
.unwrap()
.take(renderer);
self.entities.remove_all_entities(&mut self.world, renderer);
}
fn update_time(&mut self, renderer: &mut render::Renderer, delta: f64) {
@ -497,9 +457,7 @@ impl Server {
}
fn on_chunk_data(&mut self, chunk_data: packet::play::clientbound::ChunkData) {
let world_entity = self.entities.get_world();
let world = self.entities.get_component_mut(world_entity, self.world_proxy).unwrap();
world.load_chunk(
self.world.load_chunk(
chunk_data.chunk_x,
chunk_data.chunk_z,
chunk_data.new,
@ -509,9 +467,7 @@ impl Server {
}
fn on_chunk_unload(&mut self, chunk_unload: packet::play::clientbound::ChunkUnload) {
let world_entity = self.entities.get_world();
let world = self.entities.get_component_mut(world_entity, self.world_proxy).unwrap();
world.unload_chunk(chunk_unload.x, chunk_unload.z);
self.world.unload_chunk(chunk_unload.x, chunk_unload.z);
}
}