You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When adding messages to an actor, I noticed that it very often follows some specific pattern, that involves a bit of boilerplate code:
Create the method that does something on the impl MyActor
Create a struct that represents the arguments of that method and derive actix::Message for it
Implement actix::Handler<SomeMessage> for MyActor by having the handle method delegate to the associated method
I have the idea of reducing the boilerplate (and the number of structs) involved by having a proc-macro generate most of it. A first step towards this, which only automates the impl Handler, could look like this:
implMyActor{/* Simple case */#[handler(SomeMessage)]fnupdate_content(&mutself,event:SomeMessage,ctx:&mutSelf::Context){todo!()}/* The macro needs to parse the return type from the method for the trait implementation */#[handler(SomeMessage)]fnupdate_content(&mutself,event:SomeMessage,ctx:&mutSelf::Context) -> SomeResponse{todo!()}/* Optional: if the function is `async`, automatically wrap `<MyActor as Handler<SomeMessage>>::Result` in a future */#[handler(SomeMessage)]asyncfnupdate_content(&mutself,event:SomeMessage,ctx:&mutSelf::Context) -> SomeResponse{todo!()}}
A second step then would be to somehow extract the function arguments into their own struct. I am sorry that I cannot prototype this myself, as I don't have enough proc macro skills.
Motivation: I am working on a GTK application using woab. GTK uses a lot of signals and handlers, resulting in a lot of boilerplate code. Therefore, woab currently exposes all signals as variants of one message enum. But I think that having a proper message per signal type would be more idiomatic.
The text was updated successfully, but these errors were encountered:
I find derive or proc macro offer almost nothing in actix's case. You seem to write less code(Arguably a couple of lines) with them but it's just pushing the cost to code generation at compile time which would be obvious if you have many of them.
With your macro you also likely to lose type infer in IDEs where your SomeMessage attribute can not figure out if SomeResponse is have the right Message::Result type map to Handler::Result as MessageResponse.
The async fn is also a bad idea. Doing that would force everything wrap inside a future. Making you can not practice the general pattern of sync code first, return a future after.
When adding messages to an actor, I noticed that it very often follows some specific pattern, that involves a bit of boilerplate code:
impl MyActor
actix::Message
for itactix::Handler<SomeMessage> for MyActor
by having thehandle
method delegate to the associated methodI have the idea of reducing the boilerplate (and the number of structs) involved by having a proc-macro generate most of it. A first step towards this, which only automates the
impl Handler
, could look like this:A second step then would be to somehow extract the function arguments into their own struct. I am sorry that I cannot prototype this myself, as I don't have enough proc macro skills.
Motivation: I am working on a GTK application using woab. GTK uses a lot of signals and handlers, resulting in a lot of boilerplate code. Therefore, woab currently exposes all signals as variants of one message enum. But I think that having a proper message per signal type would be more idiomatic.
The text was updated successfully, but these errors were encountered: