Skip to main content

EngineCell

Struct EngineCell 

Source
pub struct EngineCell<T: ?Sized> { /* private fields */ }
Expand description

A Sync wrapper holding a single value of type T.

§Storage convention

This type aligns with the rest of the engine’s static mut convention used in core::reactive::hook::impl. The companion storage helpers try_get / try_get_mut / get / get_mut return &'static mut T and rely on the caller to honour the single-writer contract. The engine is compiled for wasm32-unknown-unknown which is single-threaded by contract, so overlapping borrows violate the caller contract rather than being trapped at runtime the way RefCell would.

RefCell is intentionally not used as the storage backend: its runtime aliasing panic is unreachable in practice under wasm’s single-threaded model and adds code size and a redundant safety net that the rest of the codebase does not provide.

§?Sized bound and trait-object storage

The T: ?Sized bound is what lets the engine alias Rc<EngineCell<dyn Trait>> directly (see ComponentRc, SceneRc, TickHandlerRc in their respective type.rs). The trait-object fat pointer is stored in-place inside the UnsafeCell<T>; get_mut -> &'static mut dyn Trait lets callers dispatch without an intermediate Box.

§When to choose this vs MaybeEngineCell

The cell has no notion of “uninitialized” - use MaybeEngineCell if the value may legitimately be absent (the typical case for “global installed at mount, torn down at unmount” singletons). For always-present values this is a zero-overhead wrapper around UnsafeCell<T>.

§Field access rule

The inner field is reached through the hand-written get_inner / set_inner accessors declared in cell/impl.rs. All read sites in this module call get_inner().get() and write sites use set_inner(UnsafeCell::new(value)) rather than touching the field directly. Struct literals Self { inner: ... } are permitted only inside the new constructor and the Default impl, per the engine’s “exceptions to no-direct-field-access” convention.

§Note on #[derive(Data)]

Lombok’s Data derive is intentionally not applied here: the derive requires T: Sized, which would defeat the ?Sized bound above and break the engine’s Rc<EngineCell<dyn Trait>> aliases. The accessor pair is hand-written in cell/impl.rs with the same Lombok-style contract.

Implementations§

Source§

impl<T: ?Sized> EngineCell<T>

Accessor implementations for EngineCell.

Source

pub fn get_inner(&self) -> &UnsafeCell<T>

Returns a shared reference to the backing UnsafeCell<T>.

§Returns
  • &UnsafeCell<T> - The backing storage of the cell, borrowed for the lifetime of the cell.
Source§

impl<T: ?Sized> EngineCell<T>

Constructor + read accessors for EngineCell.

Source

pub fn new(value: T) -> Self
where T: Sized,

Creates a new cell with the given initial value.

Construction is the one place where direct field initialisation is permitted (see field-access rule in struct.rs); all other sites must go through the accessors.

Source

pub fn get_mut(&self) -> &'static mut T

Returns a mutable reference to the contained value.

§Safety

The borrow MUST be exclusive - no other get, get_mut, try_get, or try_get_mut on the same cell may be alive when the returned reference is used. Two concurrent mutable borrows on a wasm single-threaded runtime are well-defined in practice only because wasm has no data-race detection; the &'static mut return type tells the borrow checker you promise exclusivity.

Reads via the get_inner accessor; the resulting &UnsafeCell<T> is then turned into a raw pointer by UnsafeCell::get() so we can hand the caller the &'static mut T the rest of the engine expects.

Source

pub fn get(&self) -> &'static T

Returns a shared reference to the contained value.

§Safety

The lifetime of &'static T extends beyond what the borrow checker can prove. Callers MUST NOT use this while a mutable borrow on the same cell is alive. Use Self::get_mut exclusively for write access.

Reads via the get_inner accessor + UnsafeCell::get.

Trait Implementations§

Source§

impl<T: Default> Default for EngineCell<T>

Default impl for EngineCell.

Only available when T: Default + Sized. The ?Sized bound on the cell prevents adding Default blanket-style because trait Default cannot be implemented for unsized types.

Source§

fn default() -> Self

Creates a default cell by installing T::default() as the initial value.

Source§

impl<T: ?Sized> Sync for EngineCell<T>

Marker that EngineCell<T> is safe to share across the wasm main thread under single-threaded access.

Auto Trait Implementations§

§

impl<T> !Freeze for EngineCell<T>

§

impl<T> !RefUnwindSafe for EngineCell<T>

§

impl<T> Send for EngineCell<T>
where T: Send + ?Sized,

§

impl<T> Unpin for EngineCell<T>
where T: Unpin + ?Sized,

§

impl<T> UnsafeUnpin for EngineCell<T>
where T: UnsafeUnpin + ?Sized,

§

impl<T> UnwindSafe for EngineCell<T>
where T: UnwindSafe + ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: Sized + ErasableGeneric<Repr = Self::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more