use std::cmp::Ordering;
use downcast_rs::{impl_downcast, Downcast};
use dyn_clone::{clone_trait_object, DynClone};
use serde::ser::Serialize;
use crate::component::Id;
pub type EventId = u64;
pub trait EventData: Downcast + DynClone + erased_serde::Serialize {}
impl_downcast!(EventData);
clone_trait_object!(EventData);
erased_serde::serialize_trait_object!(EventData);
impl<T: Serialize + DynClone + 'static> EventData for T {}
#[derive(Clone)]
pub struct Event {
pub id: EventId,
pub time: f64,
pub src: Id,
pub dst: Id,
pub data: Box<dyn EventData>,
}
impl Eq for Event {}
impl PartialEq for Event {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Ord for Event {
fn cmp(&self, other: &Self) -> Ordering {
other.time.total_cmp(&self.time).then_with(|| other.id.cmp(&self.id))
}
}
impl PartialOrd for Event {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
pub struct TypedEvent<T>
where
T: EventData,
{
pub id: EventId,
pub time: f64,
pub src: Id,
pub dst: Id,
pub data: T,
}
impl Event {
pub fn downcast<T>(e: Event) -> TypedEvent<T>
where
T: EventData,
{
match e.data.downcast::<T>() {
Ok(data) => TypedEvent {
id: e.id,
time: e.time,
src: e.src,
dst: e.dst,
data: *data,
},
Err(_) => {
panic!("Event downcast error");
}
}
}
}