Add data support to import macro

This commit is contained in:
Lachlan Sneff 2019-03-28 11:41:14 -07:00
parent be08154670
commit 0787d001e3
2 changed files with 36 additions and 0 deletions

View File

@ -4,6 +4,7 @@ use std::collections::VecDeque;
use std::{ use std::{
cell::{Ref, RefCell}, cell::{Ref, RefCell},
rc::Rc, rc::Rc,
ffi::c_void,
}; };
pub trait LikeNamespace { pub trait LikeNamespace {
@ -45,6 +46,7 @@ impl IsExport for Export {
/// ``` /// ```
pub struct ImportObject { pub struct ImportObject {
map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>, map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>,
state_creator: Option<Rc<Fn() -> (*mut c_void, fn(*mut c_void))>>,
} }
impl ImportObject { impl ImportObject {
@ -52,6 +54,17 @@ impl ImportObject {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
map: Rc::new(RefCell::new(HashMap::new())), map: Rc::new(RefCell::new(HashMap::new())),
state_creator: None,
}
}
pub fn new_with_data<F>(state_creator: F) -> Self
where
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static,
{
Self {
map: Rc::new(RefCell::new(HashMap::new())),
state_creator: Some(Rc::new(state_creator)),
} }
} }
@ -98,6 +111,7 @@ impl ImportObject {
pub fn clone_ref(&self) -> Self { pub fn clone_ref(&self) -> Self {
Self { Self {
map: Rc::clone(&self.map), map: Rc::clone(&self.map),
state_creator: self.state_creator.clone(),
} }
} }

View File

@ -37,6 +37,13 @@ macro_rules! func {
/// "foo" => func!(foo), /// "foo" => func!(foo),
/// }, /// },
/// }; /// };
///
/// let imports_with_state = imports! {
/// || (0 as _, |_a| {}),
/// "env" => {
/// "foo" => func!(foo),
/// },
/// };
/// ///
/// fn foo(_: &mut Ctx, n: i32) -> i32 { /// fn foo(_: &mut Ctx, n: i32) -> i32 {
/// n /// n
@ -57,6 +64,21 @@ macro_rules! imports {
import_object.register($ns_name, ns); import_object.register($ns_name, ns);
})* })*
import_object
}};
($state_gen:expr, $( $ns_name:expr => $ns:tt, )* ) => {{
use $crate::{
import::{ImportObject, Namespace},
};
let mut import_object = ImportObject::new_with_data($state_gen);
$({
let ns = $crate::__imports_internal!($ns);
import_object.register($ns_name, ns);
})*
import_object import_object
}}; }};
} }