Skip to content

Commit

Permalink
feat(main): Update #[main] macro to support an async entrypoint
Browse files Browse the repository at this point in the history
  • Loading branch information
scottbot95 committed Mar 3, 2024
1 parent 46946ad commit adf9fb6
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
50 changes: 33 additions & 17 deletions screeps-async-macros/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,10 @@ pub fn main(_args: TokenStream, item: TokenStream) -> TokenStream {
Err(e) => return token_stream_with_error(item, e),
};

if input.sig.asyncness.is_some() {
async_main(input)
let body = if input.sig.asyncness.is_some() {
async_body(&input)
} else {
sync_main(input)
}
}

fn async_main(_input: ItemFn) -> TokenStream {
todo!("Async main not supported yet")
}

fn sync_main(input: ItemFn) -> TokenStream {
let stmts = &input.block.stmts;

let body = quote! {
#(#stmts)*

::screeps_async::run();
sync_body(&input)
};

let ident = input.sig.ident;
Expand All @@ -39,9 +25,39 @@ fn sync_main(input: ItemFn) -> TokenStream {
let args = input.sig.inputs;

quote! {
static __SCREEPS_ASYNC_INIT: std::sync::Once = std::sync::Once::new();

#(#attrs)*
#vis fn #ident(#args) {
__SCREEPS_ASYNC_INIT.call_once(|| {
screeps_async::initialize();
});

#body
}
}
}

fn async_body(input: &ItemFn) -> TokenStream {
let stmts = &input.block.stmts;

quote! {
let res = ::screeps_async::block_on(async move {
#(#stmts)*
});

::screeps_async::run();

res
}
}

fn sync_body(input: &ItemFn) -> TokenStream {
let stmts = &input.block.stmts;

quote! {
#(#stmts)*

::screeps_async::run();
}
}
5 changes: 2 additions & 3 deletions screeps-async-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ use proc_macro::TokenStream;
/// Helper to wrap your main loop entrypoint in code that will automatically configure
/// the ScreepsRuntime and invoke it at the end of each tick.
///
/// The wrapped function can optionally take a parameter of type `&mut ScreepsRuntime` to allow
/// for invoking the runtime at a different time in the tick
/// (although it should still only be called once per tick)
/// The wrapped function may be `async` in which case the body will be passed to
/// [screeps_async::block_on] before calling [screeps_async::run]
#[proc_macro_attribute]
pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
entry::main(args.into(), item.into()).into()
Expand Down

0 comments on commit adf9fb6

Please sign in to comment.