From d692c7dc355ad6942e358f53c855a81968479185 Mon Sep 17 00:00:00 2001 From: Yjn024 Date: Tue, 5 Sep 2023 12:27:38 +0800 Subject: [PATCH] mut only --- core/src/component.rs | 86 ++++++++++++++++++++++++++++++++----------- core/src/util/mod.rs | 30 +++++++++++++++ 2 files changed, 94 insertions(+), 22 deletions(-) diff --git a/core/src/component.rs b/core/src/component.rs index d2fa5f4..70e537f 100644 --- a/core/src/component.rs +++ b/core/src/component.rs @@ -122,14 +122,16 @@ impl NetSync for Components { where B: bytes::Buf, { - let Component(event) = - self.get::) -> anyhow::Result<()>>, + let Component(event) = self + .get_mut::) -> anyhow::Result<()>>, + >, >>(&*NET_RECV_ID) - .expect("net recv event component not found"); + .expect("net recv event component not found"); let mut hashmap = HashMap::::decode(buf)?; - event.invoker()(&mut hashmap) + event.as_mut().invoker()(&mut hashmap) } } @@ -164,16 +166,20 @@ impl crate::nbt::Update for Components { D: serde::Deserializer<'de>, { let Component(event) = self - .get::) -> fastnbt_rc::error::Result<()>, + .get_mut::, + ) -> fastnbt_rc::error::Result<()>, + >, >, >>(&*NBT_READ_ID) .expect("net recv event component not found"); use serde::{de::Error, Deserialize}; let mut hashmap = HashMap::deserialize(deserializer)?; - event.invoker()(&mut hashmap) + event.as_mut().invoker()(&mut hashmap) .map_err(|err| >::Error::custom(err)) } } @@ -189,7 +195,8 @@ impl ComponentsBuilder { self.inner .register(net_send_event_comp_id(), net_event_comp()); self.inner - .register(net_recv_event_comp_id(), net_event_comp()); + .register(net_recv_event_comp_id(), net_event_comp_mut()); + self } @@ -198,7 +205,8 @@ impl ComponentsBuilder { self.inner .register(nbt_save_event_comp_id(), nbt_event_comp()); self.inner - .register(nbt_read_event_comp_id(), nbt_event_comp()); + .register(nbt_read_event_comp_id(), nbt_event_comp_mut()); + self } @@ -342,10 +350,12 @@ where } if let Some(Component(event)) = components.get_mut::) -> anyhow::Result<()>>, + crate::MutOnly< + crate::Event) -> anyhow::Result<()>>, + >, >>(&*NET_RECV_ID) { - event.register(Box::new(move |map| { + event.as_mut().register(Box::new(move |map| { let this = unsafe { &mut *ptr }; let mut bytes = map.remove(&this.1).unwrap(); @@ -428,7 +438,7 @@ where } } -pub fn net_event_comp( +fn net_event_comp( ) -> Component) -> anyhow::Result<()>>> { Component(crate::Event::new(|listeners| { Box::new(move |map| { @@ -441,13 +451,27 @@ pub fn net_event_comp( })) } +fn net_event_comp_mut() -> Component< + crate::MutOnly) -> anyhow::Result<()>>>, +> { + Component(crate::MutOnly::new(crate::Event::new(|listeners| { + Box::new(move |map| { + for listener in listeners { + listener(map)?; + } + + Ok(()) + }) + }))) +} + #[inline] -pub fn net_send_event_comp_id() -> crate::Id { +fn net_send_event_comp_id() -> crate::Id { crate::Id::new("core", "net_send".to_string()) } #[inline] -pub fn net_recv_event_comp_id() -> crate::Id { +fn net_recv_event_comp_id() -> crate::Id { crate::Id::new("core", "net_recv".to_string()) } @@ -502,12 +526,14 @@ where } if let Some(Component(event)) = components.get_mut::) -> fastnbt_rc::error::Result<()>, + crate::MutOnly< + crate::Event< + dyn Fn(&mut HashMap) -> fastnbt_rc::error::Result<()>, + >, >, >>(&*NBT_READ_ID) { - event.register(Box::new(move |map| { + event.as_mut().register(Box::new(move |map| { let this = unsafe { &mut *ptr }; this.0.update(&map.remove(&this.1).unwrap()) })) @@ -588,7 +614,7 @@ where } } -pub fn nbt_event_comp() -> Component< +fn nbt_event_comp() -> Component< crate::Event) -> fastnbt_rc::error::Result<()>>, > { Component(crate::Event::new(|listeners| { @@ -602,13 +628,29 @@ pub fn nbt_event_comp() -> Component< })) } +fn nbt_event_comp_mut() -> Component< + crate::MutOnly< + crate::Event) -> fastnbt_rc::error::Result<()>>, + >, +> { + Component(crate::MutOnly::new(crate::Event::new(|listeners| { + Box::new(move |map| { + for listener in listeners { + listener(map)?; + } + + Ok(()) + }) + }))) +} + #[inline] -pub fn nbt_save_event_comp_id() -> crate::Id { +fn nbt_save_event_comp_id() -> crate::Id { crate::Id::new("core", "nbt_save".to_string()) } #[inline] -pub fn nbt_read_event_comp_id() -> crate::Id { +fn nbt_read_event_comp_id() -> crate::Id { crate::Id::new("core", "nbt_read".to_string()) } diff --git a/core/src/util/mod.rs b/core/src/util/mod.rs index bc4cbbe..0dc383e 100644 --- a/core/src/util/mod.rs +++ b/core/src/util/mod.rs @@ -522,3 +522,33 @@ mod event_tests { } } } + +/// Cell forbids immutable access to the inner value. +pub struct MutOnly { + value: T, +} + +impl MutOnly { + #[inline] + pub fn new(value: T) -> Self { + Self { value } + } + + pub fn as_mut(&mut self) -> &mut T { + &mut self.value + } + + pub fn as_ptr(&self) -> *mut T { + &self.value as *const T as *mut T + } + + pub fn into_inner(self) -> T { + self.value + } +} + +impl From for MutOnly { + fn from(value: T) -> Self { + Self::new(value) + } +}