use crate::{
abi::{C_ABI, SYSTEM_ABI},
ArcDpsGen,
};
use proc_macro2::{Span, TokenStream};
use quote::quote;
use std::env;
use syn::LitStr;
impl ArcDpsGen {
pub fn gen_name(&self) -> LitStr {
let (raw_name, span) = if let Some(input_name) = &self.name {
let name = input_name.value();
(name, input_name.span())
} else {
let name = env::var("CARGO_PKG_NAME").expect("CARGO_PKG_NAME is not set");
(name, Span::call_site())
};
LitStr::new(raw_name.as_str(), span)
}
pub fn gen_name_cstr(&self) -> LitStr {
let name = self.gen_name();
LitStr::new((name.value() + "\0").as_str(), name.span())
}
pub fn gen_build(&self) -> LitStr {
let build = env::var("CARGO_PKG_VERSION").expect("CARGO_PKG_VERSION is not set") + "\0";
LitStr::new(build.as_str(), Span::call_site())
}
pub fn build_export(&self) -> TokenStream {
let name = self.gen_name();
let name_c = self.gen_name_cstr();
let build = self.gen_build();
let sig = &self.sig;
let (init_func, init) = self.build_init().into_tuple();
let (release_func, release) = self.build_release().into_tuple();
let update_url = self.build_update_url();
let (combat_func, combat_value) = self.build_combat().into_tuple();
let (combat_local_func, combat_local_value) = self.build_combat_local().into_tuple();
let (imgui_func, imgui_value) = self.build_imgui().into_tuple();
let (options_end_func, options_end_value) = self.build_options_end().into_tuple();
let (options_windows_func, options_windows_value) =
self.build_options_windows().into_tuple();
let (wnd_filter_func, wnd_filter_value) = self.build_wnd_filter().into_tuple();
let (wnd_nofilter_func, wnd_nofilter_value) = self.build_wnd_nofilter().into_tuple();
quote! {
static __EXPORT: ::arcdps::callbacks::ArcDpsExport = ::arcdps::callbacks::ArcDpsExport {
size: ::std::mem::size_of::<::arcdps::callbacks::ArcDpsExport>(),
sig: #sig,
imgui_version: 18000,
out_build: #build.as_ptr() as _,
out_name: #name_c.as_ptr() as _,
combat: #combat_value,
combat_local: #combat_local_value,
imgui: #imgui_value,
options_end: #options_end_value,
options_windows: #options_windows_value,
wnd_filter: #wnd_filter_value,
wnd_nofilter: #wnd_nofilter_value,
};
#init_func
extern #C_ABI fn __load() -> *const ::arcdps::callbacks::ArcDpsExport {
static mut EXPORT_ERROR: ::arcdps::callbacks::ArcDpsExport = ::arcdps::callbacks::ArcDpsExport {
size: 0,
sig: 0,
imgui_version: 18000,
out_build: #build.as_ptr() as _,
out_name: #name_c.as_ptr() as _,
combat: ::std::option::Option::None,
combat_local: ::std::option::Option::None,
imgui: ::std::option::Option::None,
options_end: ::std::option::Option::None,
options_windows: ::std::option::Option::None,
wnd_filter: ::std::option::Option::None,
wnd_nofilter: ::std::option::Option::None,
};
static mut ERROR_STRING: ::std::string::String = ::std::string::String::new();
let result: ::std::result::Result<(), ::std::string::String> = #init;
if let ::std::result::Result::Err(err) = result {
unsafe {
ERROR_STRING = err + "\0";
EXPORT_ERROR.size = ERROR_STRING.as_ptr() as _;
&EXPORT_ERROR
}
} else {
&self::__EXPORT
}
}
#release_func
extern #C_ABI fn __unload() {
#release
}
#[no_mangle]
pub unsafe extern #SYSTEM_ABI fn get_init_addr(
arc_version: *const ::arcdps::__macro::c_char,
imgui_ctx: *mut ::arcdps::imgui::sys::ImGuiContext,
id3d: *mut ::arcdps::__macro::c_void,
arc_dll: ::arcdps::__macro::HMODULE,
malloc: ::std::option::Option<::arcdps::__macro::MallocFn>,
free: ::std::option::Option<::arcdps::__macro::FreeFn>,
d3d_version: ::std::primitive::u32,
) -> *mut ::arcdps::__macro::c_void {
::arcdps::__macro::init(arc_version, arc_dll, imgui_ctx, malloc, free, id3d, d3d_version, #name);
self::__load as _
}
#[no_mangle]
pub extern #SYSTEM_ABI fn get_release_addr() -> *mut ::arcdps::__macro::c_void {
self::__unload as _
}
#update_url
#combat_func
#combat_local_func
#imgui_func
#options_end_func
#options_windows_func
#wnd_filter_func
#wnd_nofilter_func
}
}
}