export_ppp_callback

Macro export_ppp_callback 

Source
macro_rules! export_ppp_callback {
    {
        $(
            $vis:vis fn $cb_name:ident (
                $(
                    $arg:ident : $arg_ty:ty
                ),* $(,)?
            ) $(-> $ret_ty:ty)?;
        )*
    } => { ... };
}
Expand description

Declare and export a plugin-to-plugin (PPP) callback, which allows other plugins to add callbacks for this plugin to run.

ยงExample

For example, if you were writing a Rust plugin that would use a callback that runs every other basic block, you could declare and use two callbacks like so:

use panda::{Callback, export_ppp_callback};
use panda::prelude::*;
 
export_ppp_callback! {
    pub(crate) fn on_every_even_block(cpu: &mut CPUState);
    pub(crate) fn on_every_odd_block(cpu: &mut CPUState);
}
 
#[panda::init]
fn init() {
    let mut i = 0;
    Callback::new().before_block_exec(move |cpu, _| {
        if i % 2 == 0 {
            on_every_even_block::trigger(cpu);
        } else {
            on_every_odd_block::trigger(cpu);
        }

        i += 1;
    });
}

(For further usage see panda-rs/examples/ppp_callback_export.rs)

The return type of each callback can be any which implements CallbackReturn, a trait which describes how to fold all the return values into a single return value to be returned by <callback_name>::trigger(...). For example a callback that returns a bool will return true if any of the callbacks return true, and will only return false if every registered callback returns false.

If you wish to alter this behavior for existing types, use the newtype pattern, which will allow you to provide your own implementation by implementing the trait.

Note: All callback arguments and return values are expected to be FFI safe. If rustc emits a warning for a given type, it is very likely it is not compatible with the C ABI. In order to have your own custom types be FFI-safe, they should be marked either #[repr(transparent)] or #[repr(C)] or should be treated as opaque types (and thus should only be created and accessed within the same plugin and passed as references).