#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(unused_mut)]
use std::marker::PhantomData;
use std::cmp::Ordering;
use std::collections::BinaryHeap;
#[derive(Debug,Clone)]
pub struct Fib {
input : i32,
clock: Clock
}
impl Clocked for Fib {
fn get_clock(&self) -> Clock { self.clock }
fn set_clock(&mut self, t: Clock) { self.clock = t;}
}
impl Fib {
pub fn new(input:i32) -> Self { Fib { input: input, clock: Clock::from(0)} }
pub fn set_input( &mut self, i : i32) {self.input = i;}
}
impl AbstractEvent2 for Fib {
fn execute( &mut self, ctx: &mut Context ){
let n = self.input;
if n == 0 || n == 1 {
let q = ctx.get_queue();
q.insert(ctx, n);
} else {
let events = ctx.get_events();
self.clock = self.clock + Clock::from(1);
let event =Event::new(EventType::FibEvent(n-2), self.get_clock()) ;
events.insert(event);
self.clock = self.clock + Clock::from(1);
let event =Event::new(EventType::FibEvent(n-1), self.get_clock()) ;
events.insert(event);
self.clock = self.clock + Clock::from(1);
let event =Event::new(EventType::FibEvent(n-2), self.get_clock()) ;
events.insert(event);
}
}
}
#[derive(Debug,Clone)]
pub struct Adder {
clock: Clock,
pub result: i32
}
impl Clocked for Adder {
fn get_clock(&self) -> Clock { self.clock }
fn set_clock(&mut self, t: Clock) { self.clock = t;}
}
impl Adder {
pub fn new() -> Self { Adder { clock: Clock::from(0), result: 0 } }
}
impl AbstractEvent2 for Adder {
fn execute( &mut self, ctx: &mut Context ){
let q = ctx.get_queue();
if q.size() >= 2 {
let a = q.remove().unwrap();
let b = q.remove().unwrap();
self.result = a + b;
q.insert(ctx, self.result);
self.clock = self.clock + Clock::from(1);
} else {
}
}
}
use std::env;
pub fn main() {
let args: Vec<String> = env::args().collect();
let n :i32 = args[1].parse().unwrap();
let max_sim_time = Clock::from(500000);
let capacity = 1000;
let simulator = &mut Simulator::new();
let queue = &mut Queue::new();
let adder = &mut Adder::new();
let fib = &mut Fib::new ( n);
let events = &mut EventQueue::new();
let mut ctx = Context {simulator, fib, adder,events,queue, _marker: PhantomData };
ctx.get_queue().capacity = capacity;
let initial_event= Event::new(EventType::FibEvent(n),Clock::from(0));
ctx.get_events().insert(initial_event);
let stats = run(&mut ctx);
drop(ctx);
println!("Send {}, processed {}, tick {} ", stats.0, stats.1, stats.2 );
}
pub fn run(ctx: &mut Context) -> (i64,i64,i64) {
loop {
let event = ctx.get_events().remove_first();
match event {
Some(mut e) => {
let t = e.get_clock() ;
ctx.get_simulator().set_clock(t);
println!("{:?} queue = {:?} ",ctx.get_simulator().get_clock() ,
ctx.get_queue());
e.execute( ctx);
}
_ => {
println!("{:?} Finished All Events",ctx.get_simulator().get_clock());
println!("Result {}", ctx.get_adder().result);
break;
}
}
}
(ctx.get_fib().input as i64,
ctx.get_adder().result as i64,
ctx.get_simulator().get_clock().get_raw())
}
pub trait AbstractEvent2 : Clocked{
fn execute(&mut self, ctx: &mut Context);
}
type EventId = u64;
#[derive(Debug,Clone,Copy )]
pub enum EventType {
FibEvent(i32),
AdderEvent
}
#[derive(Debug,Clone,Copy )]
pub struct Event {
id: EventId,
clock: Clock,
etype: EventType
}
impl Ord for Event {
fn cmp(&self, other: &Self) -> Ordering {
other.clock.cmp(&self.clock)
}
}
impl PartialOrd for Event {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(other.get_clock().cmp(&self.get_clock()))
}
}
impl PartialEq for Event {
fn eq(&self, other: &Self) -> bool {
self.get_clock() == other.get_clock()
}
}
impl Eq for Event {
}
impl AbstractEvent2 for Event {
fn execute(&mut self, ctx : &mut Context) {
match self.etype {
EventType::AdderEvent => {
let mut adder = ctx.get_adder();
adder.execute(ctx);
},
EventType::FibEvent(x) =>{
let mut fib = ctx.get_fib();
fib.set_input(x);
fib.execute(ctx);
}
}
}
}
impl Clocked for Event{
fn get_clock(&self) -> Clock {
self.clock
}
fn set_clock(&mut self, t: Clock) {
self.clock = t;
}
}
impl Event{
pub fn new( etype: EventType, clock: Clock) -> Self{
let id = 0;
Event {id, clock, etype}
}
}
#[derive(Debug)]
pub struct EventQueue {
pub elements: BinaryHeap<Event>
}
impl EventQueue {
pub fn insert(&mut self, t: Event) {
self.elements.push(t);
}
pub fn size(&self) -> usize {
self.elements.len()
}
pub fn remove_first(&mut self) -> Option<Event> {
self.elements.pop()
}
pub fn new() -> Self {
EventQueue { elements: Default::default() }
}
}
pub struct Context<'a , T = i32>{
pub simulator: *mut Simulator,
pub fib : *mut Fib,
pub adder: *mut Adder,
pub events: *mut EventQueue,
pub queue: *mut Queue,
pub _marker: PhantomData<&'a T>,
}
impl <'a, T> Context<'a, T>{
pub fn get_simulator(&self) -> &'a mut Simulator {
let ptr = unsafe { &mut *self.simulator };
ptr
}
pub fn get_fib(&self) -> &'a mut Fib {
let ptr = unsafe { &mut *self.fib };
ptr
}
pub fn get_adder(&self) -> &'a mut Adder {
let ptr = unsafe { &mut *self.adder };
ptr
}
pub fn get_events(&self) -> &'a mut EventQueue {
let ptr = unsafe { &mut *self.events };
ptr
}
pub fn get_queue(&self) -> &'a mut Queue {
let ptr = unsafe { &mut *self.queue };
ptr
}
}
pub trait AbstractSimulator {
fn insert(&mut self, ctx: &mut Context, e: Event);
fn cancel(&mut self, e: Event) {
unimplemented!()
}
}
pub struct Simulator {
clock: Clock,
}
impl AbstractSimulator for Simulator {
fn insert(&mut self, ctx: &mut Context, event: Event) {
let events = ctx.get_events();
events.insert( event);
}
}
impl Clocked for Simulator {
fn get_clock(&self) -> Clock {
self.clock
}
fn set_clock(&mut self, t: Clock) {
self.clock = t;
}
}
impl Simulator {
pub fn new() -> Simulator {
Simulator { clock: Clock::from(0)}
}
}
#[derive(PartialEq, Ord,Eq, PartialOrd, Clone, Copy)]
pub struct Clock(i64);
impl From<i64> for Clock {
fn from(t: i64) -> Self {
Clock(t as i64)
}
}
impl Clock {
pub fn set_raw(&mut self, v: i64) {
self.0 = v;
}
pub fn get_raw(&self) -> i64 {
self.0
}
}
impl std::ops::Add for Clock {
type Output = Self;
fn add(self, other: Self) -> Self {
Self::from(self.0 + other.0)
}
}
impl std::fmt::Debug for Clock {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "@{:010.03}", self.0)
}
}
#[derive(Debug)]
pub struct Queue{
fibs: Vec<i32>,
pub capacity: usize,
}
impl Queue {
pub fn new() -> Self {
return Queue {fibs: Default::default(), capacity: 10};
}
pub fn size(&self) -> usize {
self.fibs.len()
}
pub fn insert( &mut self, ctx: &mut Context, fib: i32) {
let mut sim = ctx.get_simulator();
if self.size() >= 2 {
let events = ctx.get_events();
let clock = sim.get_clock() + Clock::from(1);
let event = Event::new(EventType::AdderEvent, clock);
events.insert(event);
} else {
self.fibs.push(fib);
}
}
pub fn remove(&mut self) -> Option<i32>{
self.fibs.pop()
}
}
pub trait Clocked{
fn now(&self) -> Clock {
self.get_clock()
}
fn get_clock(&self) -> Clock ;
fn set_clock(&mut self, t: Clock);
}