123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- use std::cell::{Ref, RefMut};
- use std::rc::Rc;
- use dioxus_core::prelude::{
- consume_context, consume_context_from_scope, current_scope_id, provide_context_to_scope,
- provide_root_context,
- };
- use dioxus_core::ScopeId;
- use generational_box::{GenerationalBox, Owner, Store};
- fn current_store() -> Store {
- match consume_context() {
- Some(rt) => rt,
- None => {
- let store = Store::default();
- provide_root_context(store).expect("in a virtual dom")
- }
- }
- }
- fn current_owner() -> Rc<Owner> {
- match consume_context() {
- Some(rt) => rt,
- None => {
- let owner = Rc::new(current_store().owner());
- provide_root_context(owner).expect("in a virtual dom")
- }
- }
- }
- fn owner_in_scope(scope: ScopeId) -> Rc<Owner> {
- match consume_context_from_scope(scope) {
- Some(rt) => rt,
- None => {
- let owner = Rc::new(current_store().owner());
- provide_context_to_scope(scope, owner).expect("in a virtual dom")
- }
- }
- }
- /// CopyValue is a wrapper around a value to make the value mutable and Copy.
- ///
- /// It is internally backed by [`generational_box::GenerationalBox`].
- pub struct CopyValue<T: 'static> {
- pub(crate) value: GenerationalBox<T>,
- origin_scope: ScopeId,
- }
- impl<T: 'static> CopyValue<T> {
- /// Create a new CopyValue. The value will be stored in the current component.
- ///
- /// Once the component this value is created in is dropped, the value will be dropped.
- pub fn new(value: T) -> Self {
- let owner = current_owner();
- Self {
- value: owner.insert(value),
- origin_scope: current_scope_id().expect("in a virtual dom"),
- }
- }
- /// Create a new CopyValue. The value will be stored in the given scope. When the specified scope is dropped, the value will be dropped.
- pub fn new_in_scope(value: T, scope: ScopeId) -> Self {
- let owner = owner_in_scope(scope);
- Self {
- value: owner.insert(value),
- origin_scope: scope,
- }
- }
- pub(crate) fn invalid() -> Self {
- let owner = current_owner();
- Self {
- value: owner.invalid(),
- origin_scope: current_scope_id().expect("in a virtual dom"),
- }
- }
- /// Get the scope this value was created in.
- pub fn origin_scope(&self) -> ScopeId {
- self.origin_scope
- }
- /// Try to read the value. If the value has been dropped, this will return None.
- pub fn try_read(&self) -> Option<Ref<'_, T>> {
- self.value.try_read()
- }
- /// Read the value. If the value has been dropped, this will panic.
- pub fn read(&self) -> Ref<'_, T> {
- self.value.read()
- }
- /// Try to write the value. If the value has been dropped, this will return None.
- pub fn try_write(&self) -> Option<RefMut<'_, T>> {
- self.value.try_write()
- }
- /// Write the value. If the value has been dropped, this will panic.
- pub fn write(&self) -> RefMut<'_, T> {
- self.value.write()
- }
- /// Set the value. If the value has been dropped, this will panic.
- pub fn set(&mut self, value: T) {
- *self.write() = value;
- }
- /// Run a function with a reference to the value. If the value has been dropped, this will panic.
- pub fn with<O>(&self, f: impl FnOnce(&T) -> O) -> O {
- let write = self.read();
- f(&*write)
- }
- /// Run a function with a mutable reference to the value. If the value has been dropped, this will panic.
- pub fn with_mut<O>(&self, f: impl FnOnce(&mut T) -> O) -> O {
- let mut write = self.write();
- f(&mut *write)
- }
- }
- impl<T: Clone + 'static> CopyValue<T> {
- /// Get the value. If the value has been dropped, this will panic.
- pub fn value(&self) -> T {
- self.read().clone()
- }
- }
- impl<T: 'static> PartialEq for CopyValue<T> {
- fn eq(&self, other: &Self) -> bool {
- self.value.ptr_eq(&other.value)
- }
- }
|