summaryrefslogtreecommitdiff
path: root/ecs/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r--ecs/src/lib.rs672
1 files changed, 460 insertions, 212 deletions
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index 78e526f..07b1cba 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -1,65 +1,75 @@
#![deny(clippy::all, clippy::pedantic)]
-use std::any::{type_name, TypeId};
+use std::any::{type_name, Any, TypeId};
use std::cell::RefCell;
-use std::collections::HashMap;
use std::fmt::Debug;
use std::mem::ManuallyDrop;
+use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
+use hashbrown::HashMap;
+
use crate::actions::Action;
+use crate::component::storage::archetype::EntityComponent as ArchetypeEntityComponent;
use crate::component::storage::Storage as ComponentStorage;
-use crate::component::{Component, Sequence as ComponentSequence};
-use crate::entity::CREATE_STATIC_ENTITIES;
-use crate::event::component::{
- create_added_id as create_component_added_event_id,
- create_removed_id as create_component_removed_event_id,
- TypeTransformComponentsToAddedEvents,
+use crate::component::{
+ Component,
+ IntoParts,
+ Parts as ComponentParts,
+ Removals as ComponentRemovals,
+ Sequence as ComponentSequence,
};
-use crate::event::start::Start as StartEvent;
-use crate::event::{Event, Id as EventId, Ids, Sequence as EventSequence};
+use crate::entity::{Handle as EntityHandle, CREATE_STATIC_ENTITIES};
+use crate::event::component::Added as ComponentAddedEvent;
use crate::extension::{Collector as ExtensionCollector, Extension};
-use crate::lock::{Lock, WriteGuard};
-use crate::query::options::Options as QueryOptions;
+use crate::lock::Lock;
+use crate::pair::{ChildOf, DependsOn, Pair};
+use crate::phase::{Phase, START as START_PHASE};
+use crate::query::flexible::Query as FlexibleQuery;
+use crate::query::term::Without;
+use crate::query::{
+ Iter as QueryIter,
+ TermWithFieldTuple as QueryTermWithFieldTuple,
+ TermWithoutFieldTuple as QueryTermWithoutFieldTuple,
+ Terms as QueryTerms,
+ TermsBuilderInterface,
+};
use crate::sole::Sole;
use crate::stats::Stats;
-use crate::system::{System, TypeErased as TypeErasedSystem};
-use crate::tuple::Reduce as TupleReduce;
-use crate::type_name::TypeName;
-use crate::uid::{Kind as UidKind, Uid};
+use crate::system::{System, SystemComponent};
+use crate::uid::{Kind as UidKind, Uid, Wildcard};
pub mod actions;
pub mod component;
pub mod entity;
pub mod event;
pub mod extension;
-pub mod lock;
+pub mod pair;
+pub mod phase;
pub mod query;
-pub mod relationship;
pub mod sole;
pub mod stats;
pub mod system;
pub mod tuple;
-pub mod type_name;
pub mod uid;
+pub mod util;
#[doc(hidden)]
pub mod private;
-mod archetype;
-mod util;
+mod lock;
pub use ecs_macros::{Component, Sole};
pub use crate::query::Query;
-#[derive(Debug, Default)]
+#[derive(Debug)]
pub struct World
{
- systems: Vec<TypeErasedSystem>,
data: WorldData,
stop: AtomicBool,
+ is_first_tick: AtomicBool,
}
impl World
@@ -67,21 +77,25 @@ impl World
#[must_use]
pub fn new() -> Self
{
- let mut world = Self::default();
+ let mut world = Self {
+ data: WorldData::default(),
+ stop: AtomicBool::new(false),
+ is_first_tick: AtomicBool::new(false),
+ };
world.add_sole(Stats::default()).ok();
+ for create_static_entity in CREATE_STATIC_ENTITIES {
+ create_static_entity(&mut world);
+ }
+
world
}
/// Creates a new entity with the given components.
- ///
- /// # Panics
- /// Will panic if mutable internal lock cannot be acquired.
pub fn create_entity<Comps>(&mut self, components: Comps) -> Uid
where
- Comps: ComponentSequence + TupleReduce<TypeTransformComponentsToAddedEvents>,
- Comps::Out: EventSequence,
+ Comps: ComponentSequence,
{
let entity_uid = Uid::new_unique(UidKind::Entity);
@@ -90,31 +104,27 @@ impl World
entity_uid
}
- #[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
+ #[tracing::instrument(skip_all)]
#[doc(hidden)]
- pub fn create_entity_with_uid<Comps>(&self, components: Comps, entity_uid: Uid)
+ pub fn create_entity_with_uid<Comps>(&mut self, components: Comps, entity_uid: Uid)
where
- Comps: ComponentSequence + TupleReduce<TypeTransformComponentsToAddedEvents>,
- Comps::Out: EventSequence,
+ Comps: ComponentSequence,
{
debug_assert_eq!(entity_uid.kind(), UidKind::Entity);
- #[allow(unused_variables)]
- if let Err(err) = self
- .data
- .component_storage
- .write_nonblock()
- .expect("Failed to acquire read-write component storage lock")
- .push_entity(entity_uid, components.into_vec())
- {
- #[cfg(feature = "debug")]
- tracing::error!("Failed to create entity: {err}");
-
+ if let Err(err) = self.data.component_storage.create_entity(entity_uid) {
+ tracing::warn!("Failed to create entity: {err}");
return;
- };
+ }
- for component_added_event_id in <Comps::Out as EventSequence>::ids().iter() {
- self.emit_event_by_id(*component_added_event_id);
+ let added_component_ids = Self::add_entity_components(
+ entity_uid,
+ components.into_parts_array(),
+ &mut self.data.component_storage,
+ );
+
+ for comp_id in added_component_ids {
+ self.emit_event_by_id::<ComponentAddedEvent>(comp_id);
}
}
@@ -129,28 +139,31 @@ impl World
self.data.sole_storage.insert(sole)
}
- pub fn register_system<'this, EventT, SystemImpl>(
+ pub fn register_system<'this, SystemImpl>(
&'this mut self,
- event: EventT,
+ phase_euid: Uid,
system: impl System<'this, SystemImpl>,
- ) where
- EventT: Event,
+ )
{
- self.systems.push(system.into_type_erased());
-
- self.data
- .events
- .entry(EventT::id())
- .or_default()
- .push(self.systems.len() - 1);
+ self.create_entity((
+ SystemComponent { system: system.into_type_erased() },
+ Pair::new::<DependsOn>(phase_euid),
+ ));
+ }
- drop(event);
+ pub fn register_observer_system<'this, SystemImpl>(
+ &'this mut self,
+ system: impl System<'this, SystemImpl>,
+ event: Pair<Uid, Uid>,
+ )
+ {
+ self.create_entity((
+ SystemComponent { system: system.into_type_erased() },
+ event,
+ ));
}
/// Adds a extensions.
- ///
- /// # Panics
- /// Will panic if mutable internal lock cannot be acquired.
pub fn add_extension(&mut self, extension: impl Extension)
{
let extension_collector = ExtensionCollector::new(self);
@@ -158,34 +171,177 @@ impl World
extension.collect(extension_collector);
}
- /// Emits a event, running all systems listening to the event for each compatible
- /// entity.
- ///
- /// # Panics
- /// Will panic if a system has dissapeared.
- pub fn emit<EventT>(&self, event: EventT)
+ pub fn query<FieldTerms, FieldlessTerms>(&self) -> Query<FieldTerms, FieldlessTerms>
where
- EventT: Event,
+ FieldTerms: QueryTermWithFieldTuple,
+ FieldlessTerms: QueryTermWithoutFieldTuple,
{
- self.emit_event_by_id(EventT::id());
-
- drop(event);
+ Query::new(self)
}
- pub fn query<Comps, OptionsT>(&self) -> Query<Comps, OptionsT>
- where
- Comps: ComponentSequence,
- OptionsT: QueryOptions,
+ pub fn flexible_query<const MAX_TERM_CNT: usize>(
+ &self,
+ terms: QueryTerms<MAX_TERM_CNT>,
+ ) -> FlexibleQuery<'_, MAX_TERM_CNT>
{
- Query::new(self)
+ FlexibleQuery::new(self, terms)
}
- /// Peforms the actions that have been queued up using [`Actions`].
- ///
+ /// Performs a single tick.
/// # Panics
- /// Will panic if a mutable internal lock cannot be acquired.
- #[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
- pub fn perform_queued_actions(&self)
+ /// Will panic if mutable internal lock cannot be acquired.
+ pub fn step(&mut self) -> StepResult
+ {
+ if self.stop.load(Ordering::Relaxed) {
+ return StepResult::Stop;
+ }
+
+ if self
+ .is_first_tick
+ .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
+ .is_ok()
+ {
+ self.query_and_run_systems(*START_PHASE);
+ }
+
+ self.perform_phases();
+
+ self.data.component_storage.create_imaginary_archetypes();
+
+ let prev_pending_removals = std::mem::take(&mut self.data.pending_removals);
+
+ self.perform_queued_actions();
+
+ self.perform_removals(prev_pending_removals);
+
+ if self.stop.load(Ordering::Relaxed) {
+ return StepResult::Stop;
+ }
+
+ let mut stats_lock = self
+ .data
+ .sole_storage
+ .get::<Stats>()
+ .expect("No stats sole found")
+ .write_nonblock()
+ .expect("Failed to aquire read-write stats sole lock");
+
+ let stats = stats_lock
+ .downcast_mut::<Stats>()
+ .expect("Casting stats sole to Stats type failed");
+
+ stats.current_tick += 1;
+
+ StepResult::Continue
+ }
+
+ /// Starts a loop which calls [`Self::step`] until the world is stopped.
+ pub fn start_loop(&mut self)
+ {
+ while let StepResult::Continue = self.step() {}
+ }
+
+ #[cfg(feature = "vizoxide")]
+ pub fn create_vizoxide_archetype_graph(
+ &self,
+ name: impl AsRef<str>,
+ ) -> Result<vizoxide::Graph, vizoxide::GraphvizError>
+ {
+ use std::borrow::Cow;
+
+ use crate::component::storage::{
+ VizoxideArchetypeGraphEdgeKind,
+ VizoxideArchetypeGraphParams,
+ };
+
+ self.data.component_storage.create_vizoxide_archetype_graph(
+ name,
+ VizoxideArchetypeGraphParams {
+ create_node_name: |archetype, _| {
+ Cow::Owned(format!(
+ "[{}]",
+ archetype
+ .component_ids_sorted()
+ .into_iter()
+ .map(|comp_id| comp_id.to_string())
+ .collect::<Vec<_>>()
+ .join(", ")
+ ))
+ },
+ create_node_cb: |_archetype, archetype_metadata, node_builder| {
+ if archetype_metadata.is_imaginary {
+ return node_builder.attribute("shape", "ellipse");
+ }
+
+ node_builder.attribute("shape", "box")
+ },
+ create_edge_cb: |_, _, edge_kind, edge_builder| {
+ edge_builder.attribute(
+ "color",
+ match edge_kind {
+ VizoxideArchetypeGraphEdgeKind::Add => "green",
+ VizoxideArchetypeGraphEdgeKind::Remove => "red",
+ },
+ )
+ },
+ },
+ )
+ }
+
+ fn query_and_run_systems(&self, phase_euid: Uid)
+ {
+ let system_query = self.flexible_query(
+ QueryTerms::<2>::builder()
+ .with_required([
+ SystemComponent::id(),
+ Pair::new::<DependsOn>(phase_euid).id(),
+ ])
+ .build(),
+ );
+
+ for (system_component,) in
+ QueryIter::<(&SystemComponent,), _>::new(self, system_query.iter())
+ {
+ // SAFETY: The world lives long enough
+ unsafe {
+ system_component.system.run(self);
+ }
+ }
+ }
+
+ fn perform_child_phases(&self, parent_phase_euid: Uid)
+ {
+ let phase_query = self.flexible_query(
+ QueryTerms::<2>::builder()
+ .with_required([
+ Phase::id(),
+ Pair::new::<ChildOf>(parent_phase_euid).id(),
+ ])
+ .build(),
+ );
+
+ for child_phase_entity in &phase_query {
+ self.query_and_run_systems(child_phase_entity.uid());
+ self.perform_child_phases(child_phase_entity.uid());
+ }
+ }
+
+ fn perform_phases(&self)
+ {
+ let phase_query = self.query::<(&Phase,), (Without<Pair<ChildOf, Wildcard>>,)>();
+
+ for (phase_entity_id, _) in phase_query.iter_with_euids() {
+ if phase_entity_id == *START_PHASE {
+ continue;
+ }
+
+ self.query_and_run_systems(phase_entity_id);
+ self.perform_child_phases(phase_entity_id);
+ }
+ }
+
+ #[tracing::instrument(skip_all)]
+ fn perform_queued_actions(&mut self)
{
let mut active_action_queue = match *self.data.action_queue.active_queue.borrow()
{
@@ -202,82 +358,64 @@ impl World
let mut has_swapped_active_queue = false;
+ // TODO: Figure out a good way to handle situations where there are multiple
+ // AddComponents/RemoveComponents actions that affect the same entity.
for action in active_action_queue.drain(..) {
match action {
Action::Spawn(components) => {
- let mut component_storage_lock = self.lock_component_storage_rw();
-
- let component_ids = components
- .iter()
- .map(|component| component.self_id())
- .collect::<Vec<_>>();
+ let new_entity_uid = Uid::new_unique(UidKind::Entity);
- #[allow(unused_variables)]
- if let Err(err) = component_storage_lock
- .push_entity(Uid::new_unique(UidKind::Entity), components)
+ if let Err(err) =
+ self.data.component_storage.create_entity(new_entity_uid)
{
- #[cfg(feature = "debug")]
- tracing::error!("Failed to create entity: {err}");
-
+ tracing::warn!("Failed to create entity: {err}");
continue;
}
- drop(component_storage_lock);
+ let added_component_ids = Self::add_entity_components(
+ new_entity_uid,
+ components,
+ &mut self.data.component_storage,
+ );
if !has_swapped_active_queue {
self.swap_event_queue(&mut has_swapped_active_queue);
}
- for component_id in component_ids {
- self.emit_event_by_id(create_component_added_event_id(
- component_id,
- ));
+ for comp_id in added_component_ids {
+ self.emit_event_by_id::<ComponentAddedEvent>(comp_id);
}
}
+ Action::Despawn(entity_uid) => {
+ Self::schedule_removal(
+ &mut self.data.component_storage,
+ &mut self.data.pending_removals,
+ entity_uid,
+ PendingRemoval::Entity,
+ );
+ }
Action::AddComponents(entity_uid, components) => {
- let mut component_storage_lock = self.lock_component_storage_rw();
-
- let component_ids = components
- .iter()
- .map(|component| component.self_id())
- .collect::<Vec<_>>();
-
- component_storage_lock
- .add_components_to_entity(entity_uid, components);
-
- drop(component_storage_lock);
+ let added_component_ids = Self::add_entity_components(
+ entity_uid,
+ components,
+ &mut self.data.component_storage,
+ );
if !has_swapped_active_queue {
self.swap_event_queue(&mut has_swapped_active_queue);
}
- for component_id in component_ids {
- self.emit_event_by_id(create_component_added_event_id(
- component_id,
- ));
+ for comp_id in added_component_ids {
+ self.emit_event_by_id::<ComponentAddedEvent>(comp_id);
}
}
- Action::RemoveComponents(entity_uid, components_metadata) => {
- let mut component_storage_lock = self.lock_component_storage_rw();
-
- component_storage_lock.remove_components_from_entity(
+ Action::RemoveComponents(entity_uid, component_ids) => {
+ Self::schedule_removal(
+ &mut self.data.component_storage,
+ &mut self.data.pending_removals,
entity_uid,
- components_metadata
- .iter()
- .map(|component_metadata| component_metadata.id),
+ PendingRemoval::Components(component_ids),
);
-
- drop(component_storage_lock);
-
- if !has_swapped_active_queue {
- self.swap_event_queue(&mut has_swapped_active_queue);
- }
-
- for component_metadata in components_metadata {
- self.emit_event_by_id(create_component_removed_event_id(
- component_metadata.id,
- ));
- }
}
Action::Stop => {
self.stop.store(true, Ordering::Relaxed);
@@ -286,60 +424,134 @@ impl World
}
}
- /// A event loop which runs until a stop is issued with [`Flags::stop`]. Before the
- /// loop begins, [`StartEvent`] is emitted.
- ///
- /// # Panics
- /// Will panic if a internal lock cannot be acquired.
- pub fn event_loop<EventSeq: EventSequence>(&self)
+ fn perform_removals(&mut self, removals: Vec<(Uid, PendingRemoval)>)
{
- for create_static_entity in CREATE_STATIC_ENTITIES {
- create_static_entity(self);
+ for (entity_id, removal) in removals {
+ match removal {
+ PendingRemoval::Components(component_ids) => {
+ Self::remove_entity_components(
+ entity_id,
+ component_ids.into_iter().chain([ComponentRemovals::id()]),
+ &mut self.data.component_storage,
+ );
+ }
+ PendingRemoval::Entity => {
+ if let Err(err) = self.data.component_storage.remove_entity(entity_id)
+ {
+ tracing::error!("Failed to remove entity {entity_id}: {err}");
+ }
+ }
+ }
}
+ }
- self.emit(StartEvent);
+ #[tracing::instrument(skip(component_storage, pending_removals))]
+ fn schedule_removal(
+ component_storage: &mut ComponentStorage,
+ pending_removals: &mut Vec<(Uid, PendingRemoval)>,
+ entity_uid: Uid,
+ removal: PendingRemoval,
+ )
+ {
+ let Some(ent_handle) = Self::get_entity(component_storage, entity_uid) else {
+ tracing::warn!("Cannot schedule removal. Entity does not exist");
+ return;
+ };
- let event_seq = EventSeq::ids();
+ let component_ids = match removal {
+ PendingRemoval::Components(ref component_ids) => component_ids,
+ PendingRemoval::Entity => &ent_handle.component_ids().collect::<Vec<_>>(),
+ };
- loop {
- for event_id in event_seq.iter() {
- self.emit_event_by_id(*event_id);
- }
+ let Some(mut component_removals) = ent_handle.get_mut::<ComponentRemovals>()
+ else {
+ Self::add_entity_components(
+ entity_uid,
+ [ComponentRemovals::from_iter(component_ids.iter().copied())
+ .into_parts()],
+ component_storage,
+ );
+
+ pending_removals.push((entity_uid, removal));
+
+ return;
+ };
+
+ component_removals.add_ids(component_ids.iter().copied());
- self.perform_queued_actions();
+ drop(component_removals);
- if self.stop.load(Ordering::Relaxed) {
- break;
+ pending_removals.push((entity_uid, removal));
+ }
+
+ fn add_entity_components(
+ entity_uid: Uid,
+ components: impl IntoIterator<Item = ComponentParts>,
+ component_storage: &mut ComponentStorage,
+ ) -> Vec<Uid>
+ {
+ let component_iter = components.into_iter();
+
+ let mut added_component_ids =
+ Vec::<Uid>::with_capacity(component_iter.size_hint().0);
+
+ for component_parts in component_iter {
+ let comp_id = component_parts.id();
+
+ if let Err(err) = component_storage.add_entity_component(
+ entity_uid,
+ (comp_id, component_parts.name(), component_parts.into_data()),
+ ) {
+ tracing::error!("Failed to add component to entity: {err}");
+ continue;
}
- let mut stats_lock = self
- .data
- .sole_storage
- .get::<Stats>()
- .expect("No stats sole found")
- .write_nonblock()
- .expect("Failed to aquire read-write stats sole lock");
+ added_component_ids.push(comp_id);
+ }
+
+ added_component_ids
+ }
+
+ fn remove_entity_components(
+ entity_uid: Uid,
+ component_ids: impl IntoIterator<Item = Uid>,
+ component_storage: &mut ComponentStorage,
+ ) -> Vec<Uid>
+ {
+ let component_id_iter = component_ids.into_iter();
+
+ let mut removed_component_ids =
+ Vec::<Uid>::with_capacity(component_id_iter.size_hint().0);
- let stats = stats_lock
- .downcast_mut::<Stats>()
- .expect("Casting stats sole to Stats type failed");
+ for component_id in component_id_iter {
+ if let Err(err) =
+ component_storage.remove_entity_component(entity_uid, component_id)
+ {
+ tracing::error!("Failed to remove component to entity: {err}");
+ continue;
+ }
- stats.current_tick += 1;
+ removed_component_ids.push(component_id);
}
+
+ removed_component_ids
}
- fn emit_event_by_id(&self, event_id: EventId)
+ fn emit_event_by_id<Event: Component>(&self, target: Uid)
{
- let Some(system_indices) = self.data.events.get(&event_id) else {
+ if target.kind() == UidKind::Pair {
return;
- };
+ }
- for system_index in system_indices {
- let system = self.systems.get(*system_index).unwrap();
+ let query = self.flexible_query(
+ QueryTerms::<2>::builder()
+ .with_required([SystemComponent::id(), Pair::new::<Event>(target).id()])
+ .build(),
+ );
- // SAFETY: The world lives long enough
+ for (system,) in QueryIter::<(&SystemComponent,), _>::new(self, query.iter()) {
unsafe {
- system.run(self);
+ system.system.run(self);
}
}
}
@@ -356,45 +568,95 @@ impl World
*has_swapped_active_queue = true;
}
- fn lock_component_storage_rw(&self) -> WriteGuard<'_, ComponentStorage>
+ fn get_entity(
+ component_storage: &mut ComponentStorage,
+ entity_uid: Uid,
+ ) -> Option<EntityHandle<'_>>
{
- self.data
- .component_storage
- .write_nonblock()
- .expect("Failed to acquire read-write component storage lock")
+ let archetype = component_storage.get_entity_archetype(entity_uid)?;
+
+ Some(EntityHandle::new(
+ archetype,
+ archetype
+ .get_entity_by_id(entity_uid)
+ .expect("Not possible"),
+ ))
}
}
-#[derive(Debug, Default)]
-pub struct WorldData
+impl Default for World
{
- events: HashMap<EventId, Vec<usize>>,
- component_storage: Arc<Lock<ComponentStorage>>,
- sole_storage: SoleStorage,
- action_queue: Arc<ActionQueue>,
+ fn default() -> Self
+ {
+ Self::new()
+ }
+}
+
+/// The result of calling [`World::step`].
+pub enum StepResult
+{
+ /// Another step can be made.
+ Continue,
+
+ /// The world have been stopped so no step can be made again.
+ Stop,
}
#[derive(Debug)]
-#[non_exhaustive]
-pub struct EntityComponent
+struct WorldData
{
- pub id: Uid,
- pub name: &'static str,
- pub component: Lock<Box<dyn Component>>,
+ component_storage: ComponentStorage,
+ sole_storage: SoleStorage,
+ action_queue: Rc<ActionQueue>,
+ pending_removals: Vec<(Uid, PendingRemoval)>,
}
-impl From<Box<dyn Component>> for EntityComponent
+impl Default for WorldData
{
- fn from(component: Box<dyn Component>) -> Self
+ fn default() -> Self
{
Self {
- id: component.self_id(),
- name: component.type_name(),
- component: Lock::new(component),
+ component_storage: ComponentStorage::default(),
+ sole_storage: SoleStorage::default(),
+ action_queue: Rc::new(ActionQueue::default()),
+ pending_removals: Vec::new(),
}
}
}
+#[derive(Debug)]
+enum PendingRemoval
+{
+ Components(Vec<Uid>),
+ Entity,
+}
+
+#[derive(Debug)]
+pub struct EntityComponentRef<'a>
+{
+ component_id: Uid,
+ component: &'a ArchetypeEntityComponent,
+}
+
+impl<'a> EntityComponentRef<'a>
+{
+ fn component(&self) -> &'a Lock<Box<dyn Any>>
+ {
+ self.component.component()
+ }
+
+ #[must_use]
+ pub fn id(&self) -> Uid
+ {
+ self.component_id
+ }
+
+ fn new(component_id: Uid, comp: &'a ArchetypeEntityComponent) -> Self
+ {
+ Self { component_id, component: comp }
+ }
+}
+
#[derive(Debug, Default, Clone, Copy)]
enum ActiveActionQueue
{
@@ -403,7 +665,7 @@ enum ActiveActionQueue
B,
}
-#[derive(Debug, Default)]
+#[derive(Debug)]
struct ActionQueue
{
queue_a: Lock<Vec<Action>>,
@@ -430,11 +692,15 @@ impl ActionQueue
}
}
-impl TypeName for ActionQueue
+impl Default for ActionQueue
{
- fn type_name(&self) -> &'static str
+ fn default() -> Self
{
- type_name::<Self>()
+ Self {
+ queue_a: Lock::new(Vec::new(), type_name::<Vec<Action>>()),
+ queue_b: Lock::new(Vec::new(), type_name::<Vec<Action>>()),
+ active_queue: RefCell::new(ActiveActionQueue::default()),
+ }
}
}
@@ -479,7 +745,7 @@ impl SoleStorage
self.storage.insert(
sole_type_id,
ManuallyDrop::new(StoredSole {
- sole: Arc::new(Lock::new(Box::new(sole))),
+ sole: Arc::new(Lock::new(Box::new(sole), type_name::<SoleT>())),
drop_last,
}),
);
@@ -496,34 +762,16 @@ impl Drop for SoleStorage
for sole in self.storage.values_mut() {
if sole.drop_last {
- #[cfg(feature = "debug")]
- tracing::debug!(
- "Sole {} pushed to dropping last queue",
- sole.sole.read_nonblock().unwrap().type_name()
- );
-
soles_to_drop_last.push(sole);
continue;
}
- #[cfg(feature = "debug")]
- tracing::debug!(
- "Dropping sole {}",
- sole.sole.read_nonblock().unwrap().type_name()
- );
-
unsafe {
ManuallyDrop::drop(sole);
}
}
for sole in &mut soles_to_drop_last {
- #[cfg(feature = "debug")]
- tracing::debug!(
- "Dropping sole {} last",
- sole.sole.read_nonblock().unwrap().type_name()
- );
-
unsafe {
ManuallyDrop::drop(sole);
}