feat: use arc & clone to remove trait bound from T
This commit is contained in:
parent
5ceb5910dc
commit
d764a8d5fb
4 changed files with 75 additions and 67 deletions
|
@ -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" ]
|
||||
|
|
|
@ -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() {
|
||||
|
|
57
src/async.rs
57
src/async.rs
|
@ -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));
|
||||
|
|
79
src/lib.rs
79
src/lib.rs
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue