use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
use std::num::NonZeroU64;
use crate::meta::error::{ConvertError, FromGodotError};
use crate::meta::shape::GodotShape;
use crate::meta::{FromGodot, GodotConvert, ToGodot};
use crate::registry::property::SimpleVar;
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct InstanceId {
value: NonZeroU64,
}
impl InstanceId {
pub fn try_from_i64(id: i64) -> Option<Self> {
Self::try_from_u64(id as u64)
}
pub fn from_i64(id: i64) -> Self {
Self::try_from_i64(id).expect("expected non-zero instance ID")
}
pub(crate) fn try_from_u64(id: u64) -> Option<Self> {
NonZeroU64::new(id).map(|value| Self { value })
}
pub fn to_i64(self) -> i64 {
self.to_u64() as i64
}
pub fn is_ref_counted(self) -> bool {
self.to_u64() & (1u64 << 63) != 0
}
#[doc(alias = "is_instance_id_valid")]
pub fn lookup_validity(self) -> bool {
crate::global::is_instance_id_valid(self.to_i64())
}
pub(crate) fn to_u64(self) -> u64 {
self.value.get()
}
}
impl Display for InstanceId {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "{}", self.to_i64())
}
}
impl Debug for InstanceId {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "InstanceId({})", self.to_i64())
}
}
impl GodotConvert for InstanceId {
type Via = i64;
fn godot_shape() -> GodotShape {
GodotShape::of_builtin::<Self::Via>()
}
}
impl ToGodot for InstanceId {
type Pass = crate::meta::ByValue;
fn to_godot(&self) -> Self::Via {
self.to_i64()
}
}
impl FromGodot for InstanceId {
fn try_from_godot(via: Self::Via) -> Result<Self, ConvertError> {
Self::try_from_i64(via).ok_or_else(|| FromGodotError::ZeroInstanceId.into_error(via))
}
}
impl SimpleVar for InstanceId {}