Skip to content

Commit

Permalink
Merge pull request 'Non-static type support for component crate' (#…
Browse files Browse the repository at this point in the history
…45) from non-static-component into main

Reviewed-on: https://codeberg.org/DM-Earth/rimecraft/pulls/45
Reviewed-by: C191239 <[email protected]>
  • Loading branch information
JieningYu committed Aug 12, 2024
2 parents 19b0ed9 + 5ef8dfe commit 7091347
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 153 deletions.
1 change: 1 addition & 0 deletions crates/core/component/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ edcode2 = { path = "../../util/edcode2", package = "rimecraft-edcode2" }
rimecraft-registry = { path = "../registry", features = ["serde"] }
rimecraft-global-cx = { path = "../global-cx", features = ["nbt", "std"] }
rimecraft-maybe = { path = "../../util/maybe" }
typeid = "1.0"

[features]

Expand Down
14 changes: 8 additions & 6 deletions crates/core/component/src/changes.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
//! `ComponentChanges` implementation.

use std::{fmt::Debug, marker::PhantomData, str::FromStr};
use std::{cell::UnsafeCell, fmt::Debug, marker::PhantomData, str::FromStr};

use ahash::AHashMap;
use rimecraft_global_cx::ProvideIdTy;
use rimecraft_maybe::Maybe;
use rimecraft_registry::{ProvideRegistry, Reg};
use serde::{Deserialize, Serialize};

use crate::{map::CompTyCell, ErasedComponentType, Object, RawErasedComponentType};
use crate::{
map::CompTyCell, ErasedComponentType, Object, RawErasedComponentType, UnsafeDebugIter,
};

/// Changes of components.
pub struct ComponentChanges<'a, 'cow, Cx>
where
Cx: ProvideIdTy,
{
pub(crate) changes: Maybe<'cow, AHashMap<CompTyCell<'a, Cx>, Option<Box<Object>>>>,
pub(crate) changes: Maybe<'cow, AHashMap<CompTyCell<'a, Cx>, Option<Box<Object<'a>>>>>,
}

const REMOVED_PREFIX: char = '!';
Expand Down Expand Up @@ -47,7 +49,7 @@ where

impl<'a, 'de, Cx> Deserialize<'de> for Type<'a, Cx>
where
Cx: ProvideIdTy + ProvideRegistry<'a, Cx::Id, RawErasedComponentType<Cx>>,
Cx: ProvideIdTy + ProvideRegistry<'a, Cx::Id, RawErasedComponentType<'a, Cx>>,
Cx::Id: FromStr,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
Expand All @@ -63,7 +65,7 @@ where

impl<'a, Cx> serde::de::Visitor<'_> for Visitor<'a, Cx>
where
Cx: ProvideIdTy + ProvideRegistry<'a, Cx::Id, RawErasedComponentType<Cx>>,
Cx: ProvideIdTy + ProvideRegistry<'a, Cx::Id, RawErasedComponentType<'a, Cx>>,
Cx::Id: FromStr,
{
type Value = Type<'a, Cx>;
Expand Down Expand Up @@ -104,6 +106,6 @@ where
Cx::Id: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(&self.changes, f)
Debug::fmt(&UnsafeDebugIter(UnsafeCell::new(self.changes.keys())), f)
}
}
38 changes: 38 additions & 0 deletions crates/core/component/src/dyn_any.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use std::any::TypeId;

pub trait Any {
#[inline(always)]
fn type_id(&self) -> TypeId {
typeid::of::<Self>()
}
}

impl<T: ?Sized> Any for T {}

impl dyn Any + Send + Sync + '_ {
pub unsafe fn downcast_ref<T>(&self) -> Option<&T> {
if (*self).type_id() == typeid::of::<T>() {
unsafe { Some(&*(self as *const dyn Any as *const T)) }
} else {
None
}
}

pub unsafe fn downcast_mut<T>(&mut self) -> Option<&mut T> {
if (*self).type_id() == typeid::of::<T>() {
unsafe { Some(&mut *(self as *mut dyn Any as *mut T)) }
} else {
None
}
}
}

pub unsafe fn downcast<'a, T>(
any: Box<dyn Any + Send + Sync + 'a>,
) -> Result<Box<T>, Box<dyn Any + Send + Sync + 'a>> {
if (*any).type_id() == typeid::of::<T>() {
unsafe { Ok(Box::from_raw(Box::into_raw(any) as *mut T)) }
} else {
Err(any)
}
}
Loading

0 comments on commit 7091347

Please sign in to comment.