macro_rules! interface {
    (
        $(
            $vs:vis trait $name:ident$(($($target:ident$(<$($tlf:tt),*>)?),*))? {
                $(
                    $(extern $($cc:literal)?)? fn $fn_id:ident$(<$($gen:tt),*>)?($($arg_id:ident: $arg_ty:ty),*) $(-> $ret_ty:ty)? = $idx:expr;
                )*
            }
        )*
    ) => { ... };
}
Expand description

Creates an trait that emulates virtual table behavior from C++. You can use 'this lifetime for arguments that requires self lifetime.

struct CPlayer;
interface! {
    trait IEntity(CPlayer) {
        // 1 - is an index of this function in the table.
        extern "C" fn print() = 1;
        // Lifetimes works too
        extern "C" fn other<'a>(num: &'a i32) -> &'a i32 = 2;
    }
}
// You can use `IInterface::virt_by_address(obj, "func_name")` to get the address of the function by its name or
// `IInterface::virt_by_index(obj, <function_index>)` to get the address by the function's index.