Skip to content

Commit 60fce40

Browse files
committed
update
1 parent 78b3bb2 commit 60fce40

File tree

4 files changed

+84
-37
lines changed

4 files changed

+84
-37
lines changed

crates/byondapi-macros/src/lib.rs

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,29 @@ pub fn bind(attr: TokenStream, item: TokenStream) -> TokenStream {
4646
let args = &input.sig.inputs;
4747

4848
//Check for returns
49-
match &input.sig.output {
50-
syn::ReturnType::Default => {} //
51-
52-
syn::ReturnType::Type(_, ty) => {
53-
return syn::Error::new(ty.span(), "Do not specify the return value of binds")
54-
.to_compile_error()
55-
.into()
49+
let func_return = match &input.sig.output {
50+
syn::ReturnType::Default => {
51+
return syn::Error::new(
52+
input.span(),
53+
"Empty returns are not allowed, please return a Result",
54+
)
55+
.to_compile_error()
56+
.into()
5657
}
57-
}
58+
59+
syn::ReturnType::Type(_, ty) => match ty.as_ref() {
60+
&syn::Type::Path(_) => &input.sig.output,
61+
_ => {
62+
return syn::Error::new(input.span(), "Invalid return type, please return a Result")
63+
.to_compile_error()
64+
.into()
65+
}
66+
},
67+
};
5868

5969
let signature = quote! {
6070
#[no_mangle]
61-
pub unsafe extern "C" fn #func_name_ffi (
71+
pub unsafe extern "C-unwind" fn #func_name_ffi (
6272
__argc: ::byondapi::sys::u4c,
6373
__argv: *mut ::byondapi::value::ByondValue
6474
) -> ::byondapi::value::ByondValue
@@ -142,7 +152,7 @@ pub fn bind(attr: TokenStream, item: TokenStream) -> TokenStream {
142152
}
143153

144154
}
145-
fn #func_name(#args) -> ::eyre::Result<::byondapi::value::ByondValue>
155+
fn #func_name(#args) #func_return
146156
#body
147157
};
148158
result.into()
@@ -163,15 +173,25 @@ pub fn bind_raw_args(attr: TokenStream, item: TokenStream) -> TokenStream {
163173
let func_name_ffi_disp = quote!(#func_name_ffi).to_string();
164174

165175
//Check for returns
166-
match &input.sig.output {
167-
syn::ReturnType::Default => {} //
168-
169-
syn::ReturnType::Type(_, ty) => {
170-
return syn::Error::new(ty.span(), "Do not specify the return value of binds")
171-
.to_compile_error()
172-
.into()
176+
let func_return = match &input.sig.output {
177+
syn::ReturnType::Default => {
178+
return syn::Error::new(
179+
input.span(),
180+
"Empty returns are not allowed, please return a Result",
181+
)
182+
.to_compile_error()
183+
.into()
173184
}
174-
}
185+
186+
syn::ReturnType::Type(_, ty) => match ty.as_ref() {
187+
&syn::Type::Path(_) => &input.sig.output,
188+
_ => {
189+
return syn::Error::new(input.span(), "Invalid return type, please return a Result")
190+
.to_compile_error()
191+
.into()
192+
}
193+
},
194+
};
175195

176196
if !input.sig.inputs.is_empty() {
177197
return syn::Error::new(
@@ -184,7 +204,7 @@ pub fn bind_raw_args(attr: TokenStream, item: TokenStream) -> TokenStream {
184204

185205
let signature = quote! {
186206
#[no_mangle]
187-
pub unsafe extern "C" fn #func_name_ffi (
207+
pub unsafe extern "C-unwind" fn #func_name_ffi (
188208
__argc: ::byondapi::sys::u4c,
189209
__argv: *mut ::byondapi::value::ByondValue
190210
) -> ::byondapi::value::ByondValue
@@ -249,7 +269,7 @@ pub fn bind_raw_args(attr: TokenStream, item: TokenStream) -> TokenStream {
249269
}
250270
}
251271
}
252-
fn #func_name(args: &mut [::byondapi::value::ByondValue]) -> ::eyre::Result<::byondapi::value::ByondValue>
272+
fn #func_name(args: &mut [::byondapi::value::ByondValue]) #func_return
253273
#body
254274
};
255275
result.into()

crates/byondapi-rs-test/src/lib.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![allow(clippy::missing_safety_doc)]
22

33
use byondapi::{byond_string, map::*, prelude::*};
4+
use eyre::Result;
45

56
#[test]
67
fn generate_binds() {
@@ -18,20 +19,20 @@ fn setup_panic_handler() {
1819
}
1920

2021
#[byondapi::bind]
21-
fn test_connection() {
22+
fn test_connection() -> Result<ByondValue> {
2223
setup_panic_handler();
2324
Ok(ByondValue::new_num(69.0))
2425
}
2526

2627
#[byondapi::bind_raw_args]
27-
fn test_args() {
28+
fn test_args() -> Result<ByondValue> {
2829
setup_panic_handler();
2930
assert_eq!(args.len(), 2);
3031
Ok(args[1])
3132
}
3233

3334
#[byondapi::bind]
34-
fn test_ptr(ptr: ByondValue) {
35+
fn test_ptr(ptr: ByondValue) -> Result<ByondValue> {
3536
setup_panic_handler();
3637
let pointer = ByondValuePointer::new(ptr)?;
3738

@@ -44,20 +45,20 @@ fn test_ptr(ptr: ByondValue) {
4445
}
4546

4647
#[byondapi::bind]
47-
fn test_proc_call(object: ByondValue) {
48+
fn test_proc_call(object: ByondValue) -> Result<ByondValue> {
4849
Ok(object.call("get_name", &[])?)
4950
}
5051

5152
#[byondapi::bind]
52-
fn test_readwrite_var(object: ByondValue) {
53+
fn test_readwrite_var(object: ByondValue) -> Result<ByondValue> {
5354
setup_panic_handler();
5455

5556
object.read_var_id(byond_string!("name"))?.get_string()?;
5657

5758
Ok(object.read_string("name")?.try_into()?)
5859
}
5960
#[byondapi::bind]
60-
fn test_list_push(mut list: ByondValue) {
61+
fn test_list_push(mut list: ByondValue) -> Result<ByondValue> {
6162
setup_panic_handler();
6263

6364
list.push_list(ByondValue::new_num(8.0))?;
@@ -66,7 +67,7 @@ fn test_list_push(mut list: ByondValue) {
6667
}
6768

6869
#[byondapi::bind]
69-
fn test_list_double(list: ByondValue) {
70+
fn test_list_double(list: ByondValue) -> Result<ByondValue> {
7071
setup_panic_handler();
7172

7273
let collection = list
@@ -78,14 +79,14 @@ fn test_list_double(list: ByondValue) {
7879
}
7980

8081
#[byondapi::bind]
81-
fn test_list_index(list: ByondValue) {
82+
fn test_list_index(list: ByondValue) -> Result<ByondValue> {
8283
setup_panic_handler();
8384

8485
Ok(list.read_list_index(3.0)?)
8586
}
8687

8788
#[byondapi::bind]
88-
fn test_list_pop(mut list: ByondValue) {
89+
fn test_list_pop(mut list: ByondValue) -> Result<ByondValue> {
8990
setup_panic_handler();
9091

9192
let element = list.pop_list()?;
@@ -98,13 +99,13 @@ fn test_list_pop(mut list: ByondValue) {
9899
}
99100

100101
#[byondapi::bind]
101-
fn test_length_with_list(list: ByondValue) {
102+
fn test_length_with_list(list: ByondValue) -> Result<ByondValue> {
102103
setup_panic_handler();
103104
Ok(list.builtin_length()?)
104105
}
105106

106107
#[byondapi::bind]
107-
fn test_block() {
108+
fn test_block() -> Result<ByondValue> {
108109
setup_panic_handler();
109110

110111
let block = byond_block(
@@ -123,13 +124,13 @@ fn test_block() {
123124
}
124125

125126
#[byondapi::bind]
126-
fn test_length_with_str(object: ByondValue) {
127+
fn test_length_with_str(object: ByondValue) -> Result<ByondValue> {
127128
setup_panic_handler();
128129

129130
Ok(object.builtin_length()?)
130131
}
131132
#[byondapi::bind]
132-
fn test_list_key_lookup(mut list: ByondValue) {
133+
fn test_list_key_lookup(mut list: ByondValue) -> Result<ByondValue> {
133134
setup_panic_handler();
134135

135136
let num: f32 = list.read_list_index("cat")?.try_into()?;
@@ -165,7 +166,7 @@ fn test_list_key_lookup(mut list: ByondValue) {
165166
}
166167

167168
#[byondapi::bind]
168-
fn test_ref(turf: ByondValue) {
169+
fn test_ref(turf: ByondValue) -> Result<ByondValue> {
169170
setup_panic_handler();
170171

171172
let turf_type = turf.get_type();
@@ -177,7 +178,7 @@ fn test_ref(turf: ByondValue) {
177178
}
178179

179180
#[byondapi::bind]
180-
fn test_non_assoc_list(list: ByondValue) {
181+
fn test_non_assoc_list(list: ByondValue) -> Result<ByondValue> {
181182
setup_panic_handler();
182183

183184
let map = list
@@ -199,7 +200,7 @@ fn test_non_assoc_list(list: ByondValue) {
199200
}
200201

201202
#[byondapi::bind]
202-
fn test_list_read(list: ByondValue) {
203+
fn test_list_read(list: ByondValue) -> Result<ByondValue> {
203204
setup_panic_handler();
204205

205206
let map = list.get_list_values()?;
@@ -217,7 +218,7 @@ fn test_list_read(list: ByondValue) {
217218
}
218219

219220
#[byondapi::bind]
220-
fn test_new_obj() {
221+
fn test_new_obj() -> Result<ByondValue> {
221222
Ok(ByondValue::builtin_new(
222223
ByondValue::try_from("/datum/testobject")?,
223224
&[],

crates/byondapi-rs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub mod binds;
1919
pub mod byond_string;
2020
pub mod global_call;
2121
pub mod prelude;
22+
pub mod threadsync;
2223
pub mod value;
2324

2425
use crate::value::ByondValue;

crates/byondapi-rs/src/threadsync.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use crate::static_global::byond;
2+
use crate::value::ByondValue;
3+
use byondapi_sys::CByondValue;
4+
use std::os::raw::c_void;
5+
6+
struct CallbackData<F: FnOnce() -> ByondValue + Send> {
7+
callback: Option<F>,
8+
}
9+
10+
extern "C" fn trampoline<F: FnOnce() -> ByondValue + Send>(data: *mut c_void) -> CByondValue {
11+
let data = unsafe { Box::from_raw(data as *mut CallbackData<F>) };
12+
(data.callback.unwrap())().into_inner()
13+
}
14+
15+
pub fn thread_sync<F>(callback: F, block: bool) -> ByondValue
16+
where
17+
F: FnOnce() -> ByondValue + Send + 'static,
18+
{
19+
let data = Box::new(CallbackData {
20+
callback: Some(callback),
21+
});
22+
let data_ptr = Box::into_raw(data) as *mut c_void;
23+
24+
ByondValue(unsafe { byond().Byond_ThreadSync(Some(trampoline::<F>), data_ptr, block) })
25+
}

0 commit comments

Comments
 (0)