impl RawId { /// Zip together an identifier and return its raw underlying representation. pubfn zip(index: Index, epoch: Epoch) -> RawId { let v = (index as u64) | ((epoch as u64) << 32); Self(NonZeroU64::new(v).unwrap())
}
/// Unzip a raw identifier into its components. pubfn unzip(self) -> (Index, Epoch) {
(self.0.get() as Index, (self.0.get() >> 32) as Epoch)
}
}
/// An identifier for a wgpu object. /// /// An `Id<T>` value identifies a value stored in a [`Global`]'s [`Hub`]. /// /// ## Note on `Id` typing /// /// You might assume that an `Id<T>` can only be used to retrieve a resource of /// type `T`, but that is not quite the case. The id types in `wgpu-core`'s /// public API ([`TextureId`], for example) can refer to resources belonging to /// any backend, but the corresponding resource types ([`Texture<A>`], for /// example) are always parameterized by a specific backend `A`. /// /// So the `T` in `Id<T>` is usually a resource type like `Texture<Empty>`, /// where [`Empty`] is the `wgpu_hal` dummy back end. These empty types are /// never actually used, beyond just making sure you access each `Storage` with /// the right kind of identifier. The members of [`Hub<A>`] pair up each /// `X<Empty>` type with the resource type `X<A>`, for some specific backend /// `A`. /// /// [`Global`]: crate::global::Global /// [`Hub`]: crate::hub::Hub /// [`Hub<A>`]: crate::hub::Hub /// [`Texture<A>`]: crate::resource::Texture /// [`Registry`]: crate::hub::Registry /// [`Empty`]: hal::api::Empty #[repr(transparent)] #[cfg_attr(any(feature = "serde", feature = "trace"), derive(serde::Serialize))] #[cfg_attr(any(feature = "serde", feature = "replay"), derive(serde::Deserialize))] #[cfg_attr(
any(feature = "serde", feature = "trace", feature = "replay"),
serde(transparent)
)] pubstruct Id<T: Marker>(RawId, PhantomData<T>);
// This type represents Id in a more readable (and editable) way. #[allow(dead_code)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] enum SerialId { // The only variant forces RON to not ignore "Id"
Id(Index, Epoch),
}
impl From<RawId> for SerialId { fn from(id: RawId) -> Self { let (index, epoch) = id.unzip(); Self::Id(index, epoch)
}
}
impl From<SerialId> for RawId { fn from(id: SerialId) -> Self { match id {
SerialId::Id(index, epoch) => RawId::zip(index, epoch),
}
}
}
impl<T> Id<T> where
T: Marker,
{ /// # Safety /// /// The raw id must be valid for the type. pubunsafefn from_raw(raw: RawId) -> Self { Self(raw, PhantomData)
}
/// Coerce the identifiers into its raw underlying representation. pubfn into_raw(self) -> RawId { self.0
}
impl<T> PartialOrd for Id<T> where
T: Marker,
{ #[inline] fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T> Ord for Id<T> where
T: Marker,
{ #[inline] fn cmp(&self, other: &Self) -> Ordering { self.0.cmp(&other.0)
}
}
/// Marker trait used to determine which types uniquely identify a resource. /// /// For example, `Device<A>` will have the same type of identifier as /// `Device<B>` because `Device<T>` for any `T` defines the same maker type. pubtrait Marker: 'static + WasmNotSendSync {}
// This allows `()` to be used as a marker type for tests. // // We don't want these in production code, since they essentially remove type // safety, like how identifiers across different types can be compared. #[cfg(test)] impl Marker for () {}
/// Define identifiers for each resource.
macro_rules! ids {
($(
$(#[$($meta:meta)*])* pubtype $name:ident $marker:ident;
)*) => { /// Marker types for each resource. pubmod markers {
$( #[derive(Debug)] pubenum $marker {} implsuper::Marker for $marker {}
)*
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.