DelSkayn / rquickjs

High level bindings to the quickjs javascript engine
MIT License
434 stars 59 forks source link

How to define global functions? #211

Closed stevefan1999-personal closed 7 months ago

stevefan1999-personal commented 9 months ago

Given something like this


#[derive(Trace)]
#[rquickjs::class]
pub struct Timer {}

#[rquickjs::methods(rename_all = "camelCase")]
impl Timer {
    pub fn set_interval<'js>(
        func: Function<'js>,
        delay: Option<usize>,
        ctx: Ctx<'js>,
    ) -> CancellationTokenWrapper {
        todo!()
    }

    pub fn clear_interval(token: CancellationTokenWrapper) {
        token.cancel();
    }

    pub fn set_timeout<'js>(
        func: Function<'js>,
        delay: Option<usize>,
        ctx: Ctx<'js>,
    ) -> CancellationTokenWrapper {
        todo!()
    }

    pub fn clear_timeout(token: CancellationTokenWrapper) {
        token.cancel();
    }
}

How do I directly import all the functions into global context?

One way to solve it is by making this a module I think

stevefan1999-personal commented 9 months ago

Well, there is a workaround for this:

    #[qjs(evaluate)]
    pub fn evaluate<'js>(ctx: &Ctx<'js>, exports: &mut Exports<'js>) -> rquickjs::Result<()> {
        for (k, v) in exports.iter() {
            ctx.globals().set(k.to_str()?, v)?;
        }

        Ok(())
    }

Not bad.

DelSkayn commented 9 months ago

Rquickjs 0.4 does not have a macro for defining objects like the one described in the issue. The above works, but creates a module unnecessarily. The preferred approach would be to just define the functions and then manually create the object and set the methods like the following:

#[rquickjs::function]
pub fn set_interval<'js>(
    func: Function<'js>,
    delay: Option<usize>,
    ctx: Ctx<'js>,
) -> CancellationTokenWrapper {
    todo!()
}

#[rquickjs::function]
pub fn clear_interval(token: CancellationTokenWrapper) {
    token.cancel();
}

#[rquickjs::function]
pub fn set_timeout<'js>(
    func: Function<'js>,
    delay: Option<usize>,
    ctx: Ctx<'js>,
) -> CancellationTokenWrapper {
    todo!()
}

#[rquickjs::function]
pub fn clear_timeout(token: CancellationTokenWrapper) {
    token.cancel();
}

fn timer(ctx: &Ctx) -> Result<Object>{
    let object = Object::new(ctx.clone())?;
    object.set("setInterval",js_set_interval)?;
    object.set("clearInterval",js_clear_interval)?;
    object.set("setTimeout",js_set_timeout)?;
    object.set("clearTimeout",js_set_timeout)?;
    Ok(object)
}

fn init(ctx: &Ctx) -> Result<()>{
    ctx.globals().set("Timer",timer(ctx)?)?;
    Ok(())
}
DelSkayn commented 7 months ago

I think this is resolved.