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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
//! Entities, collections of components
//! 
//! An entity is a collection of components.

// Collections
use std::collections::HashMap;

// Traits
use std::fmt::Debug;
use std::iter::Iterator;

// Crate
use crate::{KeyType, Storage, Component};

// Macros
//--------------------------------------------------------------------------------------------------
	/// Creates an entity from it's components
	/// 
	/// # Example
	/// 
	/// ```rust
	/// use mecs::{Entity, DynStorage};
	/// 
	/// let entity: Entity<DynStorage> = mecs::entity![
	/// 	DynStorage::new(23),
	/// 	DynStorage::new("Test"),
	/// 	DynStorage::new(5.257),
	/// ];
	/// ```
	#[macro_export]
	macro_rules! entity
	{
		[ $( $cmpt:expr ),* $(,)? ] => {{
			
			let mut entity = $crate::Entity::new();
			
			$(
				entity.add( $cmpt );
			)*
			
			entity
		}};
	}
//--------------------------------------------------------------------------------------------------

// Types
//--------------------------------------------------------------------------------------------------
	/// An entity
	#[derive(PartialEq, Eq, Clone, Debug)]
	pub struct Entity<'a, S>
	where
		S    : Storage<'a>,
		S::Id: KeyType,
	{
		/// All of the components
		components: HashMap<S::Id, S>,
	}
//--------------------------------------------------------------------------------------------------

// Impl
//--------------------------------------------------------------------------------------------------
	impl<'a, S> Entity<'a, S>
	where
		S    : Storage<'a>,
		S::Id: KeyType,
	{
		// Constructors
		//--------------------------------------------------------------------------------------------------
			/// Creates an empty entity
			#[must_use]
			pub fn new() -> Self {
				Self {
					components: HashMap::new(),
				}
			}
			
			/// Creates an entity from a list of components
			#[must_use]
			pub fn from_components(components: Vec<S>) -> Self
			{
				// Create an empty entity
				let mut entity = Self::new();
				
				// Move all components into it
				for component in components {
					entity.add(component);
				}
				
				// And return it
				entity
			}
		//--------------------------------------------------------------------------------------------------
		
		// Add / Remove
		//--------------------------------------------------------------------------------------------------
			/// Adds a new component to this entity
			/// 
			/// # Return
			/// If this entity already contains a component with
			/// the same id as the one in `storage`, it is returned.
			pub fn add(&mut self, storage: S) -> Option<S>
			{
				// Insert it and remove any that already existed
				self.components.insert(storage.id(), storage)
			}
			
			/// Remove a component from this entity given it's type
			pub fn remove<C: Component<'a, S>>(&mut self) -> Option<S>
			{
				// Remove it using `remove_id`
				self.remove_id( &C::id() )
			}
			
			/// Removes a component from this entity given it's id
			pub fn remove_id(&mut self, id: &S::Id) -> Option<S>
			{
				// Attempt to remove it from it's id
				self.components.remove(id)
			}
		//--------------------------------------------------------------------------------------------------
		
		// Access
		//--------------------------------------------------------------------------------------------------
			/// Returns a reference to a component given it's type
			/// 
			/// # Return
			/// If either the component is not present in this entity
			/// or the component could not be build from the storage
			/// associated with it's id, this function will return None.
			#[must_use]
			pub fn get<C: Component<'a, S>>(&self) -> Option<&C>
			{
				// Get the storage by id and try to get the component
				// from this storage.
				self.get_id( &C::id() )
					.map(C::get)
					.flatten()
			}
			
			/// Returns a mutable reference to a component given it's type
			/// 
			/// # Return
			/// If either the component is not present in this entity
			/// or the component could not be build from the storage
			/// associated with it's id, this function will return None.
			#[must_use]
			pub fn get_mut<C: Component<'a, S>>(&mut self) -> Option<&mut C>
			{
				// Get the storage by id and try to get the component
				// from this storage.
				self.get_mut_id( &C::id() )
					.map(C::get_mut)
					.flatten()
			}
			
			/// Returns a reference to a component's storage given it's id
			#[must_use]
			pub fn get_id(&self, id: &S::Id) -> Option<&S> {
				self.components.get(id)
			}
			
			/// Returns a mutable reference to a component's storage given it's id
			#[must_use]
			pub fn get_mut_id(&mut self, id: &S::Id) -> Option<&mut S> {
				self.components.get_mut(id)
			}
		//--------------------------------------------------------------------------------------------------
		
		// Iterators
		//--------------------------------------------------------------------------------------------------
			/// Returns an iterator over all component ids in this entity
			pub fn ids(&self) -> impl Iterator<Item = &<S as Storage<'a>>::Id> {
				self.components.keys()
			}
			
			/// Returns an iterator over all components in this entity
			// TODO: Use impl Trait when possible
			#[must_use]
			pub fn components(&self) -> std::collections::hash_map::Values<'_, S::Id, S> {
				self.components.values()
			}
			
			/// Returns a mutable iterator over all components in this entity
			// TODO: Use impl Trait when possible
			#[must_use]
			pub fn components_mut(&mut self) -> std::collections::hash_map::ValuesMut<'_, S::Id, S> {
				self.components.values_mut()
			}
		//--------------------------------------------------------------------------------------------------
		
		// Checks
		//--------------------------------------------------------------------------------------------------
			/// Checks if this entity has a component given it's type
			#[must_use]
			pub fn has<C: Component<'a, S>>(&self) -> bool {
				self.has_id( &C::id() )
			}
			
			/// Checks if this entity has a component given it's id
			#[must_use]
			pub fn has_id(&self, id: &S::Id) -> bool {
				self.components.contains_key(id)
			}
		//--------------------------------------------------------------------------------------------------
	}
	
	impl<'a, S> Default for Entity<'a, S>
	where
		S    : Storage<'a>,
		S::Id: KeyType,
	{
		#[must_use]
		fn default() -> Self {
			Self::new()
		}
	}
	
	// Serde
	//--------------------------------------------------------------------------------------------------
		#[cfg(feature = "serde-serialize")]
		impl<'a, S> serde::Serialize for Entity<'a, S>
		where
			S    : Storage<'a> + serde::Serialize,
			S::Id: KeyType,
		{
			fn serialize<SS>(&self, serializer: SS) -> Result<SS::Ok, SS::Error>
			where
				SS: serde::Serializer,
			{
				use serde::ser::SerializeSeq;
				
				let mut seq = serializer.serialize_seq( Some(self.components.len()) )?;
				
				for component in self.components.values() {
					seq.serialize_element(component)?;
				}
				
				seq.end()
			}
		}
		
		#[cfg(feature = "serde-serialize")]
		impl<'a, 'de, S> serde::Deserialize<'de> for Entity<'a, S>
		where
			S    : Storage<'a> + serde::Deserialize<'de>,
			S::Id: KeyType,
		{
			fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
			where
				D: serde::Deserializer<'de>,
			{
				// Get all components as a vec
				let components = Vec::deserialize(deserializer)?;
				
				// And create the entity from all components
				Self::from_components(components)
			}
		}
	//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------