Closed Christina2333 closed 2 years ago
So you want some Timer
-specific data, rather than using the global dispatching data mechanism of calloop?
Thanks for your reply. I'm not sure if I'm using calloop in a wrong way. I'll show how I want to use it.
pub struct Aa {
// something
}
pub fn foo(tmp: Aa) {
// do something
}
fn main() {
let mut event_loop: EventLoop<LoopSignal> = EventLoop::try_new()
.expect("Failed to initialize the event loop");
let handle = event_loop.handle();
// pass a generic?maybe actualy a `PhantomData` type?
let timer = Timer<Aa>::from_duration(std::time::Duration::from_secs(10));
let res = handle
.insert_source(
timer,
|event, _metadata, shared_data| {
// pass _metadata to a function
foo(_metadata);
shared_data.stop();
TimeoutAction::Drop
},
)
.expect("Failed to insert event source!");
}
So you want some
Timer
-specific data, rather than using the global dispatching data mechanism of calloop?
I'm starting to suspect we have a confusing example. 🤔
The LoopSignal
type parameter of the event loop can be any type you want, and the &mut T
you pass as argument to dispatch()
is forwarded to all callbacks as the shared_data
argument to the closure.
Using your Aa
struct as the shared data does not fit your need?
I'm starting to suspect we have a confusing example. 🤔
The
LoopSignal
type parameter of the event loop can be any type you want, and the&mut T
you pass as argument todispatch()
is forwarded to all callbacks as theshared_data
argument to the closure.Using your
Aa
struct as the shared data does not fit your need?
How can I stop the event loop if the shared_data
is not type of LoopSignal
? LoopSignal
cannot be a field of Aa
as it has no constructor
What do you mean it has no constructor?
The way calloop is designed is that you're supposed to construct youself an instance of the shared data type you pass to the event loop when invoking dispatch()
or run()
, so the classic structure of a calloop-based app would be something like this:
EventLoop
and get the LoopHandle
and LoopSignal
from it if you need themLoopHandle
/ LoopSignal
as fields if you needEventLoop::run()
, passing it a &mut
reference to the shared data struct you created earlierThis way, all the state you've put in the shared data struct (including any LoopHandle
/ LoopSignal
) can be accessed from all you callbacks.
My following question is how to assign value to LoopSignal
in Aa
. I probably know it now.
pub struct Aa {
fd: i32,
tmp: String,
signal: LoopSignal
}
impl Aa {
pub fn new(fd: i32, tmp: String, event: &EventLoop<Aa>) -> Aa {
Aa {
fd,
tmp,
// pass EventLoop to get the LoopSignal
signal: event.get_signal()
}
}
}
pub fn foo(tmp: &mut Aa) {
}
fn main() {
let mut event_loop: EventLoop<Aa> = EventLoop::try_new()
.expect("Failed to initialize the event loop");
let mut aa = Aa::new(6, String::from("test"), &event_loop);
let handle = event_loop.handle();
let timer = Timer::from_duration(std::time::Duration::from_secs(2));
let res = handle
.insert_source(
timer,
|event, _metadata, shared_data| {
println!("Timeout for {:?} expired", event);
foo(shared_data);
// stop the event loop
shared_data.signal.stop();
TimeoutAction::Drop
},
)
.expect("Failed to insert event source!");
}
Thanks!
impl EventSource for Timer { type Event = Instant; type Metadata = (); type Ret = TimeoutAction; type Error = std::io::Error;
... ... }
Because
Metadata
ofTimer
is()
, specific data cannot be passed in the callback function ofTimer
. Why not add a generic toTimer
to support specific Metadata? Thanks.