use std::any::TypeId;
use std::fmt;
use crate::engine::types::{ChunkID, ComponentID, RowID};
use super::attribute::AttributeError;
use super::primitives::{CapacityError, ShardBoundsError, StaleEntityError};
use super::registry::RegistryError;
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SpawnError {
Capacity(CapacityError),
ShardBounds(ShardBoundsError),
InvalidShardCount {
requested: u16,
max: u16,
},
StaleEntity(StaleEntityError),
EmptyArchetype,
ArchetypeNotEmpty,
StorageSwapRemoveFailed(AttributeError),
StoragePushFailedWith(AttributeError),
MissingComponent {
type_id: TypeId,
name: &'static str,
},
MisalignedStorage {
expected: (ChunkID, RowID),
got: (ChunkID, RowID),
},
BatchColumnMismatch {
component_id: ComponentID,
expected: usize,
actual: usize,
},
BatchColumnSet {
component_id: ComponentID,
},
ShardLockPoisoned,
InvalidComponentId,
Registry(RegistryError),
}
impl fmt::Display for SpawnError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SpawnError::Capacity(e) => write!(f, "{e}"),
SpawnError::ShardBounds(e) => write!(f, "{e}"),
SpawnError::InvalidShardCount { requested, max } => write!(
f,
"invalid shard count: requested {}, maximum supported {}",
requested, max
),
SpawnError::StaleEntity(e) => write!(f, "{e}"),
SpawnError::EmptyArchetype => write!(f, "archetype contains no components"),
SpawnError::ArchetypeNotEmpty => {
write!(f, "cannot remove component from non-empty archetype")
}
SpawnError::StorageSwapRemoveFailed(e) => {
write!(f, "failed to swap-remove from storage: {e}")
}
SpawnError::StoragePushFailedWith(e) => write!(f, "failed to push into storage: {e}"),
SpawnError::MissingComponent { name, .. } => write!(f, "missing component: {}", name),
SpawnError::MisalignedStorage { expected, got } => write!(
f,
"component storages became misaligned; expected position {:?}, got {:?}",
expected, got
),
SpawnError::BatchColumnMismatch {
component_id,
expected,
actual,
} => write!(
f,
"batch column for component {component_id} mismatched: expected {expected}, got {actual}"
),
SpawnError::BatchColumnSet { component_id } => write!(
f,
"batch columns do not match the batch signature (component {component_id})"
),
SpawnError::ShardLockPoisoned => write!(f, "shard lock poisoned"),
SpawnError::InvalidComponentId => write!(f, "invalid component id"),
SpawnError::Registry(e) => write!(f, "registry error: {e}"),
}
}
}
impl std::error::Error for SpawnError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
SpawnError::Capacity(e) => Some(e),
SpawnError::ShardBounds(e) => Some(e),
SpawnError::StaleEntity(e) => Some(e),
SpawnError::StorageSwapRemoveFailed(e) => Some(e),
SpawnError::StoragePushFailedWith(e) => Some(e),
SpawnError::Registry(e) => Some(e),
_ => None,
}
}
}
impl From<CapacityError> for SpawnError {
fn from(e: CapacityError) -> Self {
SpawnError::Capacity(e)
}
}
impl From<ShardBoundsError> for SpawnError {
fn from(e: ShardBoundsError) -> Self {
SpawnError::ShardBounds(e)
}
}
impl From<StaleEntityError> for SpawnError {
fn from(e: StaleEntityError) -> Self {
SpawnError::StaleEntity(e)
}
}
impl From<AttributeError> for SpawnError {
fn from(e: AttributeError) -> Self {
SpawnError::StoragePushFailedWith(e)
}
}
impl From<RegistryError> for SpawnError {
fn from(e: RegistryError) -> Self {
SpawnError::Registry(e)
}
}