summaryrefslogtreecommitdiff
path: root/engine-ecs/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine-ecs/src/lib.rs')
-rw-r--r--engine-ecs/src/lib.rs70
1 files changed, 65 insertions, 5 deletions
diff --git a/engine-ecs/src/lib.rs b/engine-ecs/src/lib.rs
index 8b3b8c3..2e30bb8 100644
--- a/engine-ecs/src/lib.rs
+++ b/engine-ecs/src/lib.rs
@@ -18,6 +18,7 @@ use crate::component::{
IntoParts as IntoComponentParts,
Parts as ComponentParts,
Sequence as ComponentSequence,
+ Type as ComponentType,
};
use crate::entity::{Declaration as EntityDeclaration, Handle as EntityHandle};
use crate::error::{
@@ -47,10 +48,17 @@ use crate::query::{
TermsBuilderInterface,
MAX_TERM_CNT as QUERY_MAX_TERM_CNT,
};
+use crate::reflection::Type as TypeReflection;
use crate::sole::{Single, Sole};
use crate::stats::Stats;
use crate::system::observer::Observer;
-use crate::system::{Callbacks, Metadata as SystemMetadata, System, SystemComponent};
+use crate::system::{
+ Callbacks,
+ Metadata as SystemMetadata,
+ Param as SystemParam,
+ System,
+ SystemComponent,
+};
use crate::uid::Uid;
pub mod actions;
@@ -75,6 +83,8 @@ pub use engine_ecs_macros::{Component, Sole};
pub use crate::query::Query;
+pub extern crate engine_reflection as reflection;
+
#[derive(Debug)]
pub struct World
{
@@ -540,13 +550,12 @@ impl World
let component_iter = components.into_iter();
for component_parts in component_iter {
- let comp_id = component_parts.id();
-
- let comp_name = component_parts.name();
+ let comp_id = component_parts.id;
+ let comp_name = component_parts.name;
if let Err(err) = component_storage.add_entity_component(
entity_uid,
- (comp_id, comp_name, component_parts.into_data()),
+ (comp_id, comp_name, component_parts.data),
) {
tracing::error!("Failed to add component {comp_name} to entity: {err}");
continue;
@@ -556,6 +565,14 @@ impl World
continue;
}
+ if let Some(type_reflection) = component_parts.type_reflection {
+ Self::create_component_type_entity(
+ comp_id,
+ type_reflection,
+ component_storage,
+ );
+ }
+
event_submitter.submit_event(
&Pair::builder()
.relation::<Added>()
@@ -566,6 +583,39 @@ impl World
}
}
+ fn create_component_type_entity(
+ comp_id: Uid,
+ type_reflection: &'static TypeReflection,
+ component_storage: &mut ComponentStorage,
+ )
+ {
+ if let Some(comp_ent_archetype) = component_storage.get_entity_archetype(comp_id)
+ {
+ if comp_ent_archetype.contains_component_with_exact_id(ComponentType::id()) {
+ return;
+ }
+ } else {
+ if let Err(EntityAlreadyExistsError) =
+ component_storage.create_entity(comp_id)
+ {
+ unreachable!();
+ }
+ }
+
+ let ComponentParts {
+ id: comp_type_id,
+ name: comp_type_name,
+ type_reflection: _,
+ data: comp_type_data,
+ } = ComponentType { type_reflection }.into_parts();
+
+ if let Err(err) = component_storage
+ .add_entity_component(comp_id, (comp_type_id, comp_type_name, comp_type_data))
+ {
+ tracing::error!("Failed to add component {comp_type_name} to entity: {err}");
+ }
+ }
+
fn remove_entity_components(
entity_uid: Uid,
component_ids: impl IntoIterator<Item = Uid>,
@@ -625,6 +675,16 @@ impl Default for World
}
}
+impl<'world> SystemParam<'world> for &'world World
+{
+ type Input = ();
+
+ fn new(world: &'world World, _system_metadata: &SystemMetadata) -> Self
+ {
+ world
+ }
+}
+
/// The result of calling [`World::step`].
pub enum StepResult
{