Macro stakker::call

source ·
macro_rules! call {
    ( $($x:tt)+ ) => { ... };
}
Expand description

Queue an actor call or inline code for execution soon

The call is deferred to the main defer queue, which will execute as soon as possible. The order of execution of calls on an actor is guaranteed to be the same order that the calls were made.

Note that in the examples below, in general there can be any number of arguments, including zero. The number of arguments depends on the signature of the called method. All of these values may be full Rust expressions, which are evaluated at the call-site before queuing the call.

Note that the part in square brackets gives the context of the call, which takes one of these forms:

  • [cx]: This is used for calls to the same actor

  • [actor]: This is used for calls to another actor. The call is made through the actor’s built-in Deferrer.

  • [actor, cx] or [actor, core]: This may also be used instead of [actor]. The call is made via Core, which might be slightly faster if the Deferrer instances are being inlined, but otherwise gives no advantage compared to the plain [actor] form.

// Call a method in this actor or in another actor
call!([cx], method(arg1, arg2...));
call!([actorxx], method(arg1, arg2...));

// Call a method whilst the actor is in the 'Prep' state, before it
// has a `Self` instance.  `Type` here in the first line may be `Self`.
call!([cx], Type::method(arg1, arg2...));
call!([cx], <path::Type>::method(arg1, arg2...));
call!([actoryy], Type::method(arg1, arg2...));
call!([actorzz], <path::Type>::method(arg1, arg2...));

// Defer a call to inline code.  Closure is always treated as a `move` closure
call!([cx], |this, cx| ...code...);   // Inline code which refers to this actor
call!([core], |stakker| ...code...);  // Generic inline code (`&mut Stakker` arg)

// Optionally specifying a `core` or `cx` reference
call!([actorxx, core], method(arg1, arg2...));
call!([actoryy, core], Type::method(arg1, arg2...));
call!([actorzz, core], <path::Type>::method(arg1, arg2...));

Implemented using Core::defer, Actor::defer, Actor::apply and Actor::apply_prep.

Synchronous direct calls to the same actor

When calling a method on the same actor, there is another option, and that’s to make the call directly on self. Since the actor behaviours are normal Rust methods and the actor state is just a normal Rust structure, there is nothing to stop you doing this. The call occurs synchronously instead of being deferred until later as with call!. For example:

self.method(cx, arg1, arg2...);

It is also permissible to directly call Ready methods from Prep methods, since there is no difference between the Cx passed to a Prep method and that passed to a Ready method. You won’t have self in a Prep method, but you can make the call on whatever you’ve called the Self value you’ve constructed. For example:

let mut this = Self {...};
this.method(cx, arg1, arg2...);