feat: use arc & clone to remove trait bound from T

This commit is contained in:
Naxdy 2025-03-07 11:18:10 +01:00
parent 5ceb5910dc
commit d764a8d5fb
Signed by: Naxdy
GPG key ID: CC15075846BCE91B
4 changed files with 75 additions and 67 deletions

View file

@ -11,5 +11,5 @@ tokio-macros = { version = "2.5.0", optional = true }
thiserror = { version = "2.0.12" }
[features]
default = [ ]
default = [ "tokio" ]
tokio = [ "dep:tokio", "dep:tokio-macros" ]

View file

@ -10,7 +10,7 @@ Simple Events is a dead simple event library for Rust, providing functionality t
use simple_events::*;
// An event struct can be almost anything that implements `Copy`
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy;
// A handler function must take in exactly 1 argument of type `Event<T>`.
@ -37,7 +37,7 @@ fn main() {
```rust
use simple_events::*;
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy;
fn main() {

View file

@ -18,18 +18,18 @@ type PinnedOutput = Pin<Box<dyn Future<Output = ()> + Send>>;
struct KeyWrapper<T>(PhantomData<T>)
where
T: Sized + Sync + Send + Copy;
T: Sized + Sync + Send;
impl<T> Key for KeyWrapper<T>
where
T: Sized + Send + Sync + Copy + 'static,
T: Sized + Send + Sync + 'static,
{
type Value = Vec<Arc<AsyncEventHandler<T>>>;
}
pub struct AsyncEventHandler<T>
where
T: Sized + Send + Sync + Copy + 'static,
T: Sized + Send + Sync + 'static,
{
handle_func: Box<dyn (Fn(Event<T>) -> PinnedOutput) + Send + Sync>,
fn_id: TypeId,
@ -38,18 +38,18 @@ where
impl<T> PartialEq for AsyncEventHandler<T>
where
T: Sized + Send + Sync + Copy,
T: Sized + Send + Sync,
{
fn eq(&self, other: &Self) -> bool {
self.fn_id == other.fn_id
}
}
impl<T> Eq for AsyncEventHandler<T> where T: Sized + Send + Sync + Copy {}
impl<T> Eq for AsyncEventHandler<T> where T: Sized + Send + Sync {}
impl<T> AsyncEventHandler<T>
where
T: Sized + Send + Sync + Copy,
T: Sized + Send + Sync,
{
fn handle_event(&self, event: Event<T>) -> PinnedOutput {
(self.handle_func)(event)
@ -58,7 +58,7 @@ where
impl<T, F, Fu> From<F> for AsyncEventHandler<T>
where
T: Send + Sync + Sized + Copy,
T: Send + Sync + Sized,
Fu: Future<Output = ()> + Send + 'static,
F: (Fn(Event<T>) -> Fu) + Send + Sync + 'static,
{
@ -76,7 +76,7 @@ where
impl<T> From<&AsyncEventHandler<T>> for EventHandlerRef<T>
where
T: Send + Sync + Sized + Copy,
T: Send + Sync + Sized,
{
fn from(value: &AsyncEventHandler<T>) -> Self {
Self {
@ -106,7 +106,7 @@ impl<F, T> From<AsyncEventHandlerRef<T, F>> for EventHandlerRef<T> {
/// parameter of type `Event<T>` where `T` is the type of event struct that it wants to
/// handle, and returns a `Future<Output = ()>`.
///
pub async fn add_event_handler<T: Send + Sync + Copy + Sized + 'static>(
pub async fn add_event_handler<T: Send + Sync + Sized + 'static>(
handler: impl Into<AsyncEventHandler<T>>,
) -> EventHandlerRef<T> {
let handler = handler.into();
@ -133,7 +133,7 @@ pub async fn add_event_handler<T: Send + Sync + Copy + Sized + 'static>(
/// use simple_events::{Event, EventHandler};
/// use simple_events::r#async::*;
///
/// #[derive(Clone, Copy, Debug)]
/// #[derive(Debug)]
/// struct Dummy;
///
/// async {
@ -152,10 +152,7 @@ pub async fn add_event_handler<T: Send + Sync + Copy + Sized + 'static>(
///
/// ```
///
pub async fn remove_event_handler<
T: Send + Sync + Copy + Sized + 'static,
F: Into<EventHandlerRef<T>>,
>(
pub async fn remove_event_handler<T: Send + Sync + Sized + 'static, F: Into<EventHandlerRef<T>>>(
handler_ref: F,
) {
let mut map = HANDLER_MAP.write().await;
@ -179,7 +176,7 @@ pub async fn remove_event_handler<
}
}
pub(crate) async fn dispatch_async<T: Send + Sync + Copy + Sized + 'static>(
pub(crate) async fn dispatch_async<T: Send + Sync + Sized + 'static>(
event: impl Into<Event<T>>,
) -> Result<(), DispatchError> {
let map = HANDLER_MAP.read().await;
@ -192,7 +189,7 @@ pub(crate) async fn dispatch_async<T: Send + Sync + Copy + Sized + 'static>(
let mut futures = JoinSet::new();
handlers.iter().for_each(|handler| {
futures.spawn(handler.handle_event(event));
futures.spawn(handler.handle_event(event.clone()));
});
while let Some(res) = futures.join_next().await {
@ -203,22 +200,23 @@ pub(crate) async fn dispatch_async<T: Send + Sync + Copy + Sized + 'static>(
Ok(())
}
pub async fn dispatch<T: Send + Sync + Copy + Sized + 'static>(
pub async fn dispatch<T: Send + Sync + Sized + 'static>(
event: impl Into<Event<T>>,
) -> Result<(), DispatchError> {
let event = event.into();
dispatch_async(*event).await?;
dispatch_async::<T>(event.clone()).await?;
let pass_event = *event;
let blocking_result = tokio::task::spawn_blocking(move || crate::dispatch_sync(pass_event));
let pass_event = event.clone();
let blocking_result =
tokio::task::spawn_blocking(move || crate::dispatch_sync::<T>(pass_event));
blocking_result.await.map_err(DispatchError::JoinError)?;
Ok(())
}
pub(crate) async fn dispatch_parallel_async<T: Send + Sync + Copy + Sized + 'static>(
pub(crate) async fn dispatch_parallel_async<T: Send + Sync + Sized + 'static>(
event: impl Into<Event<T>>,
) -> Result<(), DispatchError> {
let map = HANDLER_MAP.read().await;
@ -230,7 +228,7 @@ pub(crate) async fn dispatch_parallel_async<T: Send + Sync + Copy + Sized + 'sta
if let Some(handlers) = handlers {
let tasks = handlers
.iter()
.map(|handler| tokio::spawn(handler.handle_event(event)));
.map(|handler| tokio::spawn(handler.handle_event(event.clone())));
for task in tasks {
task.await.map_err(DispatchError::JoinError)?;
@ -239,16 +237,15 @@ pub(crate) async fn dispatch_parallel_async<T: Send + Sync + Copy + Sized + 'sta
Ok(())
}
pub async fn dispatch_parallel<T: Send + Sync + Copy + Sized + 'static>(
pub async fn dispatch_parallel<T: Send + Sync + Sized + 'static>(
event: impl Into<Event<T>>,
) -> Result<(), DispatchError> {
let event = event.into();
dispatch_parallel_async(*event).await?;
dispatch_parallel_async::<T>(event.clone()).await?;
let pass_event = *event;
let blocking_result =
tokio::task::spawn_blocking(move || crate::dispatch_parallel_sync(pass_event));
tokio::task::spawn_blocking(move || crate::dispatch_parallel_sync::<T>(event.clone()));
blocking_result.await.map_err(DispatchError::JoinError)??;
@ -263,7 +260,7 @@ mod tests {
#[tokio::test]
async fn simple_closure() {
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy {
num: i32,
}
@ -295,7 +292,7 @@ mod tests {
#[tokio::test]
async fn closure_plus_function() {
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy;
let call_count = Arc::new(Mutex::new(0));
@ -336,7 +333,7 @@ mod tests {
#[tokio::test]
async fn two_functions() {
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy;
static CALL_COUNT: LazyLock<Mutex<i32>> = LazyLock::new(|| Mutex::new(0));
@ -361,7 +358,7 @@ mod tests {
#[tokio::test]
async fn separate_closures() {
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy;
static CALL_COUNT: LazyLock<Mutex<i32>> = LazyLock::new(|| Mutex::new(0));

View file

@ -28,11 +28,11 @@ pub enum DispatchError {
struct KeyWrapper<T>(PhantomData<T>)
where
T: Sized + Sync + Send + Copy;
T: Sized + Sync + Send;
impl<T> Key for KeyWrapper<T>
where
T: Send + Sync + Copy + Sized + 'static,
T: Send + Sync + Sized + 'static,
{
type Value = Vec<Arc<EventHandler<T>>>;
}
@ -40,17 +40,28 @@ where
///
/// A struct that wraps another struct so it can be dispatched via the event system.
///
#[derive(Copy, Clone, Debug)]
#[derive(Debug)]
pub struct Event<T>
where
T: Sized + Send + Sync + Copy,
T: Send + Sync + Sized,
{
inner: T,
inner: Arc<T>,
}
impl<T> Clone for Event<T>
where
T: Send + Sync + Sized,
{
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<T> Deref for Event<T>
where
T: Sized + Send + Sync + Copy,
T: Sized + Send + Sync,
{
type Target = T;
@ -61,10 +72,12 @@ where
impl<T> Event<T>
where
T: Sized + Send + Sync + Copy + 'static,
T: Sized + Send + Sync + 'static,
{
pub fn new(inner: T) -> Self {
Self { inner }
Self {
inner: Arc::new(inner),
}
}
///
@ -84,7 +97,7 @@ where
impl<T> From<T> for Event<T>
where
T: Sized + Send + Sync + Copy + 'static,
T: Sized + Send + Sync + 'static,
{
fn from(value: T) -> Self {
Self::new(value)
@ -93,7 +106,7 @@ where
pub struct EventHandler<T>
where
T: Sized + Send + Sync + Copy,
T: Sized + Send + Sync,
{
handle_func: Box<dyn Fn(Event<T>) + Send + Sync>,
fn_id: TypeId,
@ -102,18 +115,18 @@ where
impl<T> PartialEq for EventHandler<T>
where
T: Sized + Send + Sync + Copy,
T: Sized + Send + Sync,
{
fn eq(&self, other: &Self) -> bool {
self.fn_id == other.fn_id
}
}
impl<T> Eq for EventHandler<T> where T: Sized + Send + Sync + Copy {}
impl<T> Eq for EventHandler<T> where T: Sized + Send + Sync {}
impl<T> EventHandler<T>
where
T: Send + Sync + Sized + Copy,
T: Send + Sync + Sized,
{
fn handle_event(&self, event: Event<T>) {
(self.handle_func)(event)
@ -122,7 +135,7 @@ where
impl<T, F> From<F> for EventHandler<T>
where
T: Send + Sync + Sized + Copy,
T: Send + Sync + Sized,
F: (Fn(Event<T>)) + Send + Sync + 'static,
{
fn from(value: F) -> Self {
@ -143,7 +156,7 @@ where
/// ```rust
/// use simple_events::*;
///
/// #[derive(Clone, Copy, Debug)]
/// #[derive(Debug)]
/// struct Dummy;
///
/// let closure = |_: Event<Dummy>| { /*...*/ };
@ -162,7 +175,7 @@ pub struct EventHandlerRef<T> {
impl<T> From<&EventHandler<T>> for EventHandlerRef<T>
where
T: Send + Sync + Sized + Copy,
T: Send + Sync + Sized,
{
fn from(value: &EventHandler<T>) -> Self {
Self {
@ -176,7 +189,7 @@ impl<F, T, R> From<F> for EventHandlerRef<T>
where
R: Any,
F: (Fn(Event<T>) -> R) + Send + Sync + 'static,
T: Send + Sync + Copy + Sized,
T: Send + Sync + Sized,
{
fn from(_: F) -> Self {
Self {
@ -195,7 +208,7 @@ where
/// ```rust
/// use simple_events::*;
///
/// #[derive(Clone, Copy, Debug)]
/// #[derive(Debug)]
/// struct Dummy;
///
/// // Removing a static function
@ -212,10 +225,7 @@ where
///
/// ```
///
pub fn remove_event_handler<
T: Send + Sync + Copy + Sized + 'static,
F: Into<EventHandlerRef<T>>,
>(
pub fn remove_event_handler<T: Send + Sync + Sized + 'static, F: Into<EventHandlerRef<T>>>(
handler_ref: F,
) {
let mut map = HANDLER_MAP.write();
@ -244,7 +254,7 @@ pub fn remove_event_handler<
/// parameter of type `Event<T>` where `T` is the type of event struct that it wants to
/// handle.
///
pub fn add_event_handler<T: Send + Sync + Copy + Sized + 'static>(
pub fn add_event_handler<T: Send + Sync + Sized + 'static>(
handler: impl Into<EventHandler<T>>,
) -> EventHandlerRef<T> {
let handler = handler.into();
@ -271,7 +281,7 @@ pub fn add_event_handler<T: Send + Sync + Copy + Sized + 'static>(
///
/// Although event handlers are called sequentially, the order of execution is _not_ guaranteed.
///
pub(crate) fn dispatch_sync<T: Send + Sync + Copy + Sized + 'static>(event: impl Into<Event<T>>) {
pub(crate) fn dispatch_sync<T: Send + Sync + Sized + 'static>(event: impl Into<Event<T>>) {
let map = HANDLER_MAP.read();
let event = event.into();
@ -281,16 +291,16 @@ pub(crate) fn dispatch_sync<T: Send + Sync + Copy + Sized + 'static>(event: impl
if let Some(handlers) = handlers {
handlers
.iter()
.for_each(|handler| handler.handle_event(event))
.for_each(|handler| handler.handle_event(event.clone()))
}
}
pub fn dispatch<T: Send + Sync + Copy + Sized + 'static>(
pub fn dispatch<T: Send + Sync + Sized + 'static>(
event: impl Into<Event<T>>,
) -> Result<(), DispatchError> {
let event = event.into();
dispatch_sync(*event);
dispatch_sync::<T>(event.clone());
#[cfg(feature = "tokio")]
{
@ -310,7 +320,7 @@ pub fn dispatch<T: Send + Sync + Copy + Sized + 'static>(
///
/// This function will return once all event handlers have finished executing.
///
pub(crate) fn dispatch_parallel_sync<T: Send + Sync + Copy + Sized + 'static>(
pub(crate) fn dispatch_parallel_sync<T: Send + Sync + Sized + 'static>(
event: impl Into<Event<T>>,
) -> Result<(), DispatchError> {
let map = HANDLER_MAP.read();
@ -324,6 +334,7 @@ pub(crate) fn dispatch_parallel_sync<T: Send + Sync + Copy + Sized + 'static>(
.iter()
.map(|handler| {
let handler = handler.clone();
let event = event.clone();
thread::spawn(move || handler.handle_event(event))
})
.find_map(|r| if let Err(e) = r.join() { Some(e) } else { None })
@ -333,12 +344,12 @@ pub(crate) fn dispatch_parallel_sync<T: Send + Sync + Copy + Sized + 'static>(
Ok(())
}
pub fn dispatch_parallel<T: Send + Sync + Copy + Sized + 'static>(
pub fn dispatch_parallel<T: Send + Sync + Sized + 'static>(
event: impl Into<Event<T>>,
) -> Result<(), DispatchError> {
let event = event.into();
dispatch_parallel_sync(*event)?;
dispatch_parallel_sync::<T>(event.clone())?;
#[cfg(feature = "tokio")]
{
@ -362,7 +373,7 @@ mod tests {
#[test]
fn simple_closure() {
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy {
num: i32,
}
@ -389,7 +400,7 @@ mod tests {
#[test]
fn closure_plus_function() {
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy;
let call_count = Arc::new(Mutex::new(0));
@ -424,7 +435,7 @@ mod tests {
#[test]
fn two_functions() {
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy;
static CALL_COUNT: Mutex<i32> = Mutex::new(0);
@ -449,7 +460,7 @@ mod tests {
#[test]
fn separate_closures() {
#[derive(Clone, Copy, Debug)]
#[derive(Debug)]
struct Dummy;
static CALL_COUNT: Mutex<i32> = Mutex::new(0);