I think it's not a rare problem but sorry I cant figure out how to solve it or what keyword to search.
I'm writing a mio tcp server actually but I think my problem is fundamentally a callback object want a mutable reference to a looper. So I make an example with a simple timer queue. So the question is, timer or something can be very flexable and may call some fn of the timer queue but I don't want to pass the same timer queue all around and mass up the logic of every timer. I've tried Rc, RefCell and found the evil is in the very first 'tq.run();', tq is mut so there can be no other &mut to it, no matter what boxing struct I use. Am I right? And what's the best way (or if there are any) to implement such structures?
use std::boxed::Box;
use std::thread::sleep;
use std::time::Duration;
trait Timer {
fn fire(&mut self);
}
struct TimerQueue {
timers : Vec<Box<Timer>>,
new_timers : Vec<Box<Timer>>,
}
impl TimerQueue {
fn new() -> TimerQueue {
TimerQueue {
timers : Vec::new(),
new_timers : Vec::new(),
}
}
fn insert(&mut self, timer : Box<Timer>) {
self.new_timers.push(timer);
}
fn run(&mut self) {
loop {
self.timers.append(&mut self.new_timers);
sleep(Duration::new(1,0));
for t in self.timers.iter_mut() {
t.fire();
}
}
}
}
struct ATimer;
impl Timer for ATimer {
fn fire(&mut self) {
//do something
//problem: I want to insert another timer into the same queue, but how?
}
}
fn main() {
let mut tq = TimerQueue::new();
tq.insert(Box::new(ATimer));
tq.run();
}