Skip to content

Commit

Permalink
Fix lifetimes
Browse files Browse the repository at this point in the history
Init macro crate

Signed-off-by: Tin Svagelj <tin.svagelj@live.com>
  • Loading branch information
Caellian committed Aug 21, 2023
1 parent 6d54ebd commit a09bcd2
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 73 deletions.
50 changes: 16 additions & 34 deletions examples/ping_pong.rs
Original file line number Diff line number Diff line change
@@ -1,50 +1,32 @@
use std::rc::Rc;

use litesim::prelude::*;

pub struct PingPongEvent;

pub struct Player;

impl Model for Player {
/*
declare_connectors! {
input: ["recieve"],
output: ["send"]
}
fn recieve_handler(_: PingPongEvent, ctx: SimulationCtx) -> Result<(), SimulationError> {
ctx.schedule_change(In(ctx.rand_range(0.0..1.0)));
Ok(())
}

fn handle_input<'s>(
&mut self,
_event: PingPongEvent,
connector: litesim::util::CowStr<'s>,
sim: SimulationCtx,
source: EventSource<'s>,
) -> InputEffect<'s, PingPongEvent> {
log::info!(
"Player {} received ball on connector: {}, from {:?}, at: {}",
sim.current,
connector,
source,
sim.time,
);
InputEffect::ScheduleInternal(sim.time + sim.rand_range(0.0..1.0))
}
impl<'s> Model<'s> for Player {
type I = ((&'static str, Rc<dyn ErasedInputHandler<'s>>),);

fn handle_update<'s>(&mut self, sim: SimulationCtx<'s>) -> ChangeEffect<'s, PingPongEvent> {
log::info!("Player {} bounced at: {}", sim.current, sim.time);
ChangeEffect::Produce(ProducedEvent::new_instant(PingPongEvent, "send", None))
} */
type O = ();

fn input_connectors<'s>(&self) -> Self::I {
(("", |e: PingPongEvent, ctx: SimulationCtx| {
ctx.push_event_with_source(event, target, source_connector)
}),)
fn input_connectors(&self) -> Self::I {
(("recieve", Rc::new(recieve_handler)),)
}

fn output_connectors<'s>(&self) -> Self::O {
fn output_connectors(&self) -> Self::O {
()
}

fn handle_update<'s>(&mut self, ctx: SimulationCtx<'s>) {
push!(ctx, "send", PingPongEvent)
fn handle_update(&mut self, ctx: SimulationCtx<'s>) -> Result<(), SimulationError> {
// TODO: output connector should be strongly typed here assuming we've provided the names and types in output_connectors
push_event!(ctx, "send", PingPongEvent)
}
}

Expand All @@ -66,7 +48,7 @@ fn main() {
sim.scheduler_mut()
.schedule_event(
0.5,
RoutedEvent::new_external(PingPongEvent, connection!(p1::recieve)),
RoutedEvent::new_external(Event::new(PingPongEvent), connection!(p1::recieve)),
)
.expect("unable to schedule initial event");

Expand Down
13 changes: 13 additions & 0 deletions litesim_impl/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "litesim_impl"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
proc_macro = true

[dependencies]
syn = "2.0"
quote = "1.0"
6 changes: 6 additions & 0 deletions litesim_impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extern crate proc_macro;

#[proc_macro_derive(Model)]
pub fn model_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {

}
4 changes: 2 additions & 2 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl<'a> ProducedEvent<'a> {
event: self.event,
source_connector: self.source_connector,
target: self.target,
scheduling: TimeTrigger::At { time },
scheduling: TimeTrigger::At(time),
}
}

Expand All @@ -125,7 +125,7 @@ impl<'a> ProducedEvent<'a> {
event: self.event,
source_connector: self.source_connector,
target: self.target,
scheduling: TimeTrigger::In { delay },
scheduling: TimeTrigger::In(delay),
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ pub mod time;
pub(crate) mod util;

pub mod prelude {
pub use crate::error::*;
pub use crate::event::*;
pub use crate::model::*;
pub use crate::simulation::*;
pub use crate::system::*;
pub use crate::time::TimeTrigger::*;
pub use crate::time::*;

pub use crate::connection;
pub use crate::push;
pub use crate::push_event;
pub use crate::route;
}
45 changes: 19 additions & 26 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,6 @@ impl<'s> From<(&ConnectorPath<'s>, &ConnectorPath<'s>)> for Route<'s> {
}
}

// FIXME: Lifetimes are all over the place.
// Handlers assume connector lives as long as the simulation which isn't true

trait EventConsumer<Ctx>: Fn(Event<Self::Msg>, Ctx) -> Result<Self::Ok, SimulationError> {
type Msg: Message;
type Ok;
Expand Down Expand Up @@ -181,7 +178,7 @@ pub struct InputConnectorIter<'a, 's: 'a, L: InputConnectorList<'s> + Heterogene
_phantom: PhantomData<&'s ()>,
}

impl<'s, 'a: 's, L: InputConnectorList<'s> + HeterogeneousTuple> Iterator
impl<'a, 's: 'a, L: InputConnectorList<'s> + HeterogeneousTuple> Iterator
for InputConnectorIter<'a, 's, L>
{
type Item = InputConnector<'s>;
Expand All @@ -208,7 +205,7 @@ pub trait ErasedOutputHandler<'s> {
&'c mut self,
event: ErasedEvent,
ctx: ConnectorCtx<'c, 's>,
) -> Result<(), RoutingError>;
) -> Result<(), SimulationError>;
fn out_type_id(&self) -> TypeId;
}

Expand All @@ -217,15 +214,15 @@ impl<'c, 's: 'c, C: OutputHandler<'c, 's>> ErasedOutputHandler<'s> for C {
&'a mut self,
event: ErasedEvent,
ctx: ConnectorCtx<'a, 's>,
) -> Result<(), RoutingError> {
) -> Result<(), SimulationError> {
let casted = event
.try_restore_type()
.map_err(|got| RoutingError::InvalidEventType {
connector: std::any::type_name::<Self>(),
event_type: got.type_name,
expected: std::any::type_name::<C::Out>(),
})?;
self(casted, ctx);
self(casted, ctx)?;
Ok(())
}

Expand Down Expand Up @@ -338,31 +335,31 @@ connector_tuple![
];

#[macro_export]
macro_rules! push {
macro_rules! push_event {
($ctx: ident, $id: literal, $msg: expr) => {{
let connector_ctx = ctx.on_connector($id);
let connector_ctx = $ctx.on_connector(std::borrow::Cow::Borrowed($id));
connector_ctx.push_event(::litesim::event::Event::new($msg), None)?;
Ok(())
}};
($ctx: ident, $id: literal, $msg: expr, $time: expr) => {{
let connector_ctx = ctx.on_connector($id);
let connector_ctx = ctx.on_connector(std::borrow::Cow::Borrowed($id));
connector_ctx.push_event_with_time(::litesim::event::Event::new($msg), $time, None)?;
Ok(())
}};
($ctx: ident, $id: literal, $msg: expr, Now, $target: literal) => {{
let connector_ctx = ctx.on_connector($id);
let connector_ctx = ctx.on_connector(std::borrow::Cow::Borrowed($id));
connector_ctx.push_event(
::litesim::event::Event::new($msg),
Some(::litesim::prelude::CowStr::Borrowed($target)),
Some(std::borrow::Cow::Borrowed($target)),
)?;
Ok(())
}};
($ctx: ident, $id: literal, $msg: expr, $time: expr, $target: literal) => {{
let connector_ctx = ctx.on_connector($id);
let connector_ctx = ctx.on_connector(std::borrow::Cow::Borrowed($id));
connector_ctx.push_event_with_time(
::litesim::event::Event::new($msg),
$time,
Some(::litesim::prelude::CowStr::Borrowed($target)),
Some(std::borrow::Cow::Borrowed($target)),
)?;
Ok(())
}};
Expand All @@ -373,9 +370,9 @@ pub trait Model<'s>: 'static {
type O: OutputConnectorList<'s> + HeterogeneousTuple + 'static;

/// Lists all model input connectors
fn input_connectors(&'s self) -> Self::I;
fn input_connectors(&self) -> Self::I;
/// Lists all model output connectors
fn output_connectors(&'s self) -> Self::O;
fn output_connectors(&self) -> Self::O;

/// Called during initalization.
///
Expand All @@ -394,10 +391,7 @@ pub trait ErasedModel<'s> {
fn get_erased_input_handler<'a>(&'a self, id: &str) -> Option<Rc<dyn ErasedInputHandler<'s>>>
where
's: 'a;
fn get_erased_output_handler<'a, 'c: 'a>(
&'a self,
id: &str,
) -> Option<Rc<dyn ErasedOutputHandler<'s>>>
fn get_erased_output_handler<'a>(&'a self, id: &str) -> Option<Rc<dyn ErasedOutputHandler<'s>>>
where
's: 'a;

Expand All @@ -416,17 +410,16 @@ impl<'s, M: Model<'s>> ErasedModel<'s> for M {
.map(|it| it.1.clone())
}

fn get_erased_output_handler<'a, 'c: 'a>(
&'a self,
id: &str,
) -> Option<Rc<dyn ErasedOutputHandler<'s>>>
fn get_erased_output_handler<'a>(&'a self, id: &str) -> Option<Rc<dyn ErasedOutputHandler<'s>>>
where
's: 'a,
{
self.output_connectors()
let result = self
.output_connectors()
.iter()
.find(|it| it.0 == id)
.map(|it| it.1.clone())
.map(|it| it.1.clone());
result
}

fn erased_init(&mut self, ctx: SimulationCtx<'s>) -> Result<(), SimulationError> {
Expand Down
8 changes: 4 additions & 4 deletions src/simulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,17 +313,17 @@ impl<'s> SimulationCtx<'s> {
}
}

pub struct ConnectorCtx<'c, 's> {
pub struct ConnectorCtx<'c, 's: 'c> {
sim: &'c SimulationCtx<'s>,
pub on_connector: CowStr<'c>,
pub on_connector: CowStr<'s>,
}

impl<'c, 's: 'c> ConnectorCtx<'c, 's> {
#[inline(always)]
pub fn push_event_with_time<M: Message>(
&self,
event: Event<M>,
target: Option<ConnectorPath<'c>>,
target: Option<ConnectorPath<'s>>,
time: impl Into<SimulationTime>,
) -> Result<(), SimulationError> {
self.sim
Expand All @@ -334,7 +334,7 @@ impl<'c, 's: 'c> ConnectorCtx<'c, 's> {
pub fn push_event<M: Message>(
&self,
event: Event<M>,
target: Option<ConnectorPath<'c>>,
target: Option<ConnectorPath<'s>>,
) -> Result<(), SimulationError> {
self.sim
.push_event_with_source(event, target, self.on_connector.clone())
Expand Down
12 changes: 6 additions & 6 deletions src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ impl Display for SimulationTime {
#[derive(Clone)]
pub enum TimeTrigger {
Now,
At { time: SimTimeValue },
In { delay: SimDuration },
At(SimTimeValue),
In(SimDuration),
}

impl TimeTrigger {
Expand All @@ -94,18 +94,18 @@ impl TimeTrigger {
}

pub fn specific(time: SimTimeValue) -> TimeTrigger {
TimeTrigger::At { time }
TimeTrigger::At(time)
}

pub fn relative(delay: SimDuration) -> TimeTrigger {
TimeTrigger::In { delay }
TimeTrigger::In(delay)
}

pub fn to_discrete(self, current: SimulationTime) -> SimulationTime {
match self {
TimeTrigger::Now => current,
TimeTrigger::At { time } => SimulationTime::new(time.clone()),
TimeTrigger::In { delay } => current + delay.clone(),
TimeTrigger::At(time) => SimulationTime::new(time.clone()),
TimeTrigger::In(delay) => current + delay.clone(),
}
}
}
10 changes: 10 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,13 @@ impl_heterogeneous_tuple![
pub trait EraseTyping<Erased> {
fn erase_typing(self) -> Erased;
}

/*
MAPT<Vararg, (ABC) => ((X, A), (X, B))>
- happens at compile time, not codegen time
- We need to know that I is in fact a tuple, and iterate over its types which isn't something we can do with macros
- I needs to be partially evaluated by rustc
fn derp<>
*/

0 comments on commit a09bcd2

Please sign in to comment.