Created
May 9, 2018 21:58
-
-
Save cgdangelo/57c800cecc64d217aacddaea27c80731 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(dead_code)] | |
fn main() { | |
use simfantasy::*; | |
use std::time::Duration; | |
let a = Box::new(Bard {}); | |
let options = SimulationOptions { | |
combat_length: Duration::from_secs(10), | |
actors: vec![a], | |
}; | |
Simulation::new(options).run() | |
} | |
mod simfantasy { | |
use std::cmp::Ordering; | |
use std::time::{Duration, Instant}; | |
use std::collections::BinaryHeap; | |
pub struct SimulationOptions { | |
pub combat_length: Duration, | |
pub actors: Vec<Box<Actor>>, | |
} | |
pub struct Simulation { | |
options: SimulationOptions, | |
events: BinaryHeap<Event>, | |
start_time: Instant, | |
current_time: Instant, | |
end_time: Instant, | |
} | |
impl Simulation { | |
pub fn new(options: SimulationOptions) -> Simulation { | |
let now = Instant::now(); | |
let combat_length = options.combat_length; | |
Simulation { | |
options, | |
events: BinaryHeap::new(), | |
start_time: now, | |
current_time: now, | |
end_time: now + combat_length, | |
} | |
} | |
pub fn run(&mut self) { | |
println!("{} Running...", self.relative_timestamp()); | |
self.schedule_server_ticks(); | |
while self.current_time < self.end_time { | |
match self.events.pop() { | |
Some(event) => { | |
self.current_time = event.timestamp; | |
event.handler.handle(self); | |
} | |
None => { | |
self.current_time += Duration::from_millis(100); | |
println!("{} Forced Tick!", self.relative_timestamp()); | |
} | |
} | |
} | |
println!("{} Done.", self.relative_timestamp()) | |
} | |
fn schedule_server_ticks(&mut self) { | |
let mut s = 3; | |
while s < self.options.combat_length.as_secs() { | |
self.schedule(Box::new(ServerTick {}), Duration::from_secs(s)); | |
s += 3; | |
} | |
} | |
fn schedule(&mut self, handler: Box<EventHandler>, delay: Duration) { | |
self.events.push(Event { | |
timestamp: self.current_time + delay, | |
unscheduled: false, | |
handler, | |
}) | |
} | |
fn relative_timestamp(&self) -> String { | |
let elapsed = self.current_time.duration_since(self.start_time); | |
let s = elapsed.as_secs(); | |
let ns = elapsed.subsec_nanos() / 1000000; | |
format!("{:02}.{:04}", s, ns) | |
} | |
} | |
struct Event { | |
timestamp: Instant, | |
unscheduled: bool, | |
handler: Box<EventHandler>, | |
} | |
impl Eq for Event {} | |
impl Ord for Event { | |
fn cmp(&self, other: &Event) -> Ordering { | |
self.timestamp.cmp(&other.timestamp).reverse() | |
} | |
} | |
impl PartialOrd for Event { | |
fn partial_cmp(&self, other: &Event) -> Option<Ordering> { | |
Some(self.cmp(&other)) | |
} | |
} | |
impl PartialEq for Event { | |
fn eq(&self, other: &Event) -> bool { | |
self.timestamp == other.timestamp | |
} | |
} | |
trait EventHandler { | |
fn handle(&self, sim: &Simulation); | |
} | |
struct ServerTick; | |
impl EventHandler for ServerTick { | |
fn handle(&self, sim: &Simulation) { println!("{} Tick Event!", sim.relative_timestamp()); } | |
} | |
pub trait Actor {} | |
pub struct Bard; | |
impl Actor for Bard {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment