Skip to content

Instantly share code, notes, and snippets.

@cgdangelo
Created May 9, 2018 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cgdangelo/57c800cecc64d217aacddaea27c80731 to your computer and use it in GitHub Desktop.
Save cgdangelo/57c800cecc64d217aacddaea27c80731 to your computer and use it in GitHub Desktop.
#![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