Skip to main content

extension

Macro extension 

Source
macro_rules! extension {
    {// #0
        extern $symbol_initializer:ident $(, $symbol_finalizer:ident;
        move $initializer:path, final $($finalizer:path)?)?;
        gen $context_initializer:path, final $($context_finalizer:path)?;
    } => { ... };
    {// #1
        @Extern [$symbol_initializer:ident, $symbol_finalizer:ident, $initializer:path $(, $finalizer:path)?]
    } => { ... };
    {// #2
        @Extern [$symbol_initializer:ident]
    } => { ... };
}
Expand description

Generates and links the required Flash Runtime Extension entry points and lifecycle hooks, bridging the C ABI with safe Rust abstractions.

This macro accepts two external symbols to be exported as part of the public ABI, and four functions: Initializer, Finalizer, ContextInitializer, ContextFinalizer. Some of these arguments are optional.

§Full Examples

mod lib {
    use fre_rs::prelude::*;
    fre_rs::extension! {
        extern symbol_initializer, symbol_finalizer;
        move initializer, final finalizer;
        gen context_initializer, final context_finalizer;
    }
    struct NativeData (i32);
    impl Data for NativeData {}
    fn initializer() -> Option<Box<dyn Any>> {
        let extension_data = NativeData(-3).into_boxed();
        return Some(extension_data);
    }
    fn finalizer(ext_data: Option<Box<dyn Any>>) {
        assert_eq!(NativeData::from_boxed(ext_data.unwrap()).unwrap().0, -3);
    }
    fn context_initializer(ctx: &mut CurrentContext) -> (Option<Box<dyn Any>>, FunctionSet) {
        let context_data = NativeData(-2).into_boxed();
        let mut funcs = FunctionSet::with_capacity(1);
        let function_data = NativeData(-1).into_boxed();
        if ctx.ty().is_some() {
            funcs.add(None, Some(function_data), method_name);
        } else {
            funcs.add(None, Some(function_data), method_name2);
        }
        return (Some(context_data), funcs);
    }
    fn context_finalizer(ctx: &mut CurrentContext) {
        let context_data: &NativeData = ctx.data().unwrap().downcast_ref().unwrap();
        assert_eq!(context_data.0, -2);
        ctx.set_actionscript_data(as3::null)
    }
    fn method_implementation <'a> (ctx: &mut CurrentContext<'a>, data: Option<&mut dyn Any>, args: &[Object<'a>]) -> Object<'a> {as3::null}
    fre_rs::function! (method_name use method_implementation);
    fre_rs::function! {
        method_name2 (ctx, data, args) -> Option<as3::Array> {
            let function_data: &mut NativeData = data.unwrap().downcast_mut().unwrap();
            assert_eq!(function_data.0, -1);
            return None;
        }
    }
}

§Minimal Examples

mod lib {
    use fre_rs::prelude::*;
    fre_rs::extension! {
        extern symbol_initializer;
        gen context_initializer, final;
    }
    fn context_initializer(_: &mut CurrentContext) -> (Option<Box<dyn Any>>, FunctionSet) {
        let mut funcs = FunctionSet::new();
        funcs.add(None, None, method_name);
        (None, funcs)
    }
    fre_rs::function! {
        method_name (ctx, _, args) -> as3::String {
            trace(args);
            as3::String::new(ctx, "Hello, Flash runtime!")
        }
    }
}