1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::collections::HashMap;
use std::any::{Any, TypeId};

use super::component::Component;

// @TODO: Write comment
pub trait ComponentManagerTrait {
    fn as_any(&self) -> &dyn Any;
    fn as_any_mut(&mut self) -> &mut dyn Any;

	// @TODO: Write comment

	fn has(&self, entity_id: usize) -> bool;
	fn remove(&mut self, entity_id: usize);
	fn get_type_id(&self) -> TypeId;
}

impl<T: 'static + Component> ComponentManagerTrait for ComponentManager<T> {
    fn as_any(&self) -> &dyn Any {
        self as &dyn Any
    }

    fn as_any_mut(&mut self) -> &mut dyn Any {
        self as &mut dyn Any
    }

	fn has(&self, entity_id: usize) -> bool {
		let manager = cast_manager::<T>(self);
		manager.has(entity_id)
	}

	fn remove(&mut self, entity_id: usize) {
		let manager = cast_manager_mut::<T>(self);
		manager.remove(entity_id);
	}

	fn get_type_id(&self) -> TypeId {
		TypeId::of::<T>()
	}
}

// @TODO: Write comment
pub fn cast_manager<T: 'static + Component>
	(manager: &dyn ComponentManagerTrait) -> &ComponentManager<T> {
	manager
		.as_any()
		.downcast_ref::<ComponentManager<T>>()
		.unwrap()
}

// @TODO: Write comment
pub fn cast_manager_mut<T: 'static + Component>
	(manager: &mut dyn ComponentManagerTrait) -> &mut ComponentManager<T> {
	manager
		.as_any_mut()
		.downcast_mut::<ComponentManager<T>>()
		.unwrap()
}

pub struct ComponentManager<T: Component> {
	components: Vec<T>, // Component contents
	entity_ids: Vec<usize>, // Same order with components
	entity_id_map: HashMap<usize, usize>  // entity_id -> index in components
}

impl<T: Component> ComponentManager<T> {
	pub fn new() -> Self {
		ComponentManager {
			components: Vec::new(),
			entity_ids: Vec::new(),
			entity_id_map: HashMap::new(),
		}
	}

	pub fn has(&self, entity_id: usize) -> bool {
		self.entity_id_map.contains_key(&entity_id)
	}

	pub fn add(&mut self, entity_id: usize, component: T) {
		if self.has(entity_id) {
			// Nothing to do? Throw error? Update component?
			return;
		}
		self.components.push(component);
		self.entity_ids.push(entity_id);
		let component_index = self.components.len() - 1;
		self.entity_id_map.insert(entity_id, component_index);
	}

	pub fn remove(&mut self, entity_id: usize) {
		if !self.has(entity_id) {
			// Nothing to do? Throw error? Update component?
			return;
		}
		let index = *self.entity_id_map.get(&entity_id).unwrap();
		self.entity_id_map.insert(*self.entity_ids.last().unwrap(), index);
		self.components.swap_remove(index);
		self.entity_ids.swap_remove(index);
		self.entity_id_map.remove(&entity_id);
	}

	pub fn borrow_component(&self, entity_id: usize) -> Option<&T> {
		if !self.has(entity_id) {
			return None;
		}
		let index = self.entity_id_map.get(&entity_id).unwrap();
		Some(&self.components[*index])
	}

	pub fn borrow_component_mut(&mut self, entity_id: usize) -> Option<&mut T> {
		if !self.has(entity_id) {
			return None;
		}
		let index = self.entity_id_map.get(&entity_id).unwrap();
		Some(&mut self.components[*index])
	}

	pub fn borrow_entity_ids(&self) -> &Vec<usize> {
		&self.entity_ids
	}

	pub fn borrow_components(&self) -> &Vec<T> {
		&self.components
	}

	pub fn borrow_components_mut(&mut self) -> &mut Vec<T> {
		&mut self.components
	}
}