use crate::{
any_props::BoxedAnyProps, nodes::RenderReturn, runtime::Runtime, scope_context::Scope,
};
use std::{cell::Ref, rc::Rc};
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ScopeId(pub usize);
impl std::fmt::Debug for ScopeId {
#[allow(unused_mut)]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut builder = f.debug_tuple("ScopeId");
let mut builder = builder.field(&self.0);
#[cfg(debug_assertions)]
{
if let Some(name) = Runtime::current()
.as_ref()
.and_then(|rt| rt.get_state(*self))
{
builder = builder.field(&name.name);
}
}
builder.finish()
}
}
impl ScopeId {
pub const ROOT: ScopeId = ScopeId(0);
}
pub struct ScopeState {
pub(crate) runtime: Rc<Runtime>,
pub(crate) context_id: ScopeId,
pub(crate) last_rendered_node: Option<RenderReturn>,
pub(crate) props: BoxedAnyProps,
}
impl Drop for ScopeState {
fn drop(&mut self) {
self.runtime.remove_scope(self.context_id);
}
}
impl ScopeState {
pub fn root_node(&self) -> &RenderReturn {
self.try_root_node()
.expect("The tree has not been built yet. Make sure to call rebuild on the tree before accessing its nodes.")
}
pub fn try_root_node(&self) -> Option<&RenderReturn> {
self.last_rendered_node.as_ref()
}
pub(crate) fn state(&self) -> Ref<'_, Scope> {
self.runtime.get_state(self.context_id).unwrap()
}
}