diff --git a/crates/byondapi-rs-test/dm_project/dm_project.dme b/crates/byondapi-rs-test/dm_project/dm_project.dme index 8d36135..abbda4b 100644 --- a/crates/byondapi-rs-test/dm_project/dm_project.dme +++ b/crates/byondapi-rs-test/dm_project/dm_project.dme @@ -27,10 +27,6 @@ if (ret.name != O.name) throw EXCEPTION("Object did not make it through FFI") -/test/proc/send_test() - call_ext("byondapi_test.dll", "byond:send_test")() - - /test/proc/test_ref() var/turf/T = locate(1,1,1) var/ret = call_ext("byondapi_test.dll", "byond:test_ref")(T) @@ -87,7 +83,7 @@ var/ret = call_ext("byondapi_test.dll", "byond:test_list_index")(L) - if(ret != 4) + if(ret != 3) throw EXCEPTION("List index access failed [json_encode(ret)]") /test/proc/test_list_pop() diff --git a/crates/byondapi-rs-test/src/lib.rs b/crates/byondapi-rs-test/src/lib.rs index 4ea0280..faefdf3 100644 --- a/crates/byondapi-rs-test/src/lib.rs +++ b/crates/byondapi-rs-test/src/lib.rs @@ -93,7 +93,6 @@ pub unsafe extern "C" fn test_readwrite_var( Err(e) => format!("{:#?}", e).try_into().unwrap(), } } -/* #[no_mangle] pub unsafe extern "C" fn test_list_push( argc: byondapi_sys::u4c, @@ -102,12 +101,9 @@ pub unsafe extern "C" fn test_list_push( setup_panic_handler(); let args = parse_args(argc, argv); - let mut list: ByondValueList = match (&args[0]).try_into() { - Ok(list) => list, - Err(e) => return format!("{:#?}", e).try_into().unwrap(), - }; + let mut list = args[0]; - match list.push(&ByondValue::new_num(8.0)) { + match list.push_list(ByondValue::new_num(8.0)) { Ok(_) => {} Err(e) => return format!("{:#?}", e).try_into().unwrap(), }; @@ -123,19 +119,15 @@ pub unsafe extern "C" fn test_list_double( setup_panic_handler(); let args = parse_args(argc, argv); - let list: ByondValueList = match (&args[0]).try_into() { - Ok(list) => list, - Err(e) => return format!("{:#?}", e).try_into().unwrap(), - }; + let list = args[0]; let collection: Vec = list .iter() - .map(|f| (f.get_number().unwrap() * 2.).try_into().unwrap()) + .unwrap() + .map(|(v, _)| (v.get_number().unwrap() * 2.).try_into().unwrap()) .collect(); - let list: ByondValueList = collection.as_slice().try_into().unwrap(); - - list.try_into().unwrap() + collection.as_slice().try_into().unwrap() } #[no_mangle] @@ -146,12 +138,9 @@ pub unsafe extern "C" fn test_list_index( setup_panic_handler(); let args = parse_args(argc, argv); - let list: ByondValueList = match (&args[0]).try_into() { - Ok(list) => list, - Err(e) => return format!("{:#?}", e).try_into().unwrap(), - }; + let list = args[0]; - list[3].clone() + list.read_list_index(3.0).unwrap() } #[no_mangle] @@ -162,23 +151,20 @@ pub unsafe extern "C" fn test_list_pop( setup_panic_handler(); let args = parse_args(argc, argv); - let mut list: ByondValueList = match (&args[0]).try_into() { - Ok(list) => list, - Err(e) => return format!("{:#?}", e).try_into().unwrap(), - }; + let mut list = args[0]; - let element = match list.pop() { + let element = match list.pop_list() { Ok(x) => x, Err(e) => return format!("{:#?}", e).try_into().unwrap(), }; - if list.0.count != 4 { + if list.builtin_length().unwrap().get_number().unwrap() as u32 != 4 { return "pop did not actually remove item from list" .try_into() .unwrap(); } - element + element.unwrap() } #[no_mangle] @@ -189,22 +175,13 @@ pub unsafe extern "C" fn test_length_with_list( setup_panic_handler(); let args = parse_args(argc, argv); - let list: ByondValueList = match (&args[0]).try_into() { - Ok(list) => list, - Err(e) => return format!("{:#?}", e).try_into().unwrap(), - }; - - let value: ByondValue = match list.try_into() { - Ok(x) => x, - Err(e) => return format!("{:#?}", e).try_into().unwrap(), - }; + let list = args[0]; - match byond_length(&value) { + match list.builtin_length() { Ok(x) => x, Err(e) => format!("{:#?}", e).try_into().unwrap(), } } -*/ #[no_mangle] pub unsafe extern "C" fn test_block(argc: byondapi_sys::u4c, argv: *mut ByondValue) -> ByondValue { setup_panic_handler(); diff --git a/crates/byondapi-rs/src/list.rs b/crates/byondapi-rs/src/list.rs index 10c0d88..866bbc6 100644 --- a/crates/byondapi-rs/src/list.rs +++ b/crates/byondapi-rs/src/list.rs @@ -1,5 +1,5 @@ use crate::{static_global::byond, typecheck_trait::ByondTypeCheck, value::ByondValue, Error}; - +/// List stuff goes here, Keep in mind that all indexing method starts at zero instead of one like byondland impl ByondValue { /// Gets an array of all the list elements, this includes both keys and values for assoc lists, in an arbitrary order pub fn get_list(&self) -> Result, Error> { @@ -42,6 +42,7 @@ impl ByondValue { } }) } + /// Writes an array to the list pub fn write_list(&self, list: &[ByondValue]) -> Result<(), Error> { unsafe { @@ -102,9 +103,20 @@ impl ByondValue { if !self.is_list() { return Err(Error::NotAList); } - let len = self.builtin_length()?.get_number()?; - - self.write_list_index_internal(&(len + 1.0).into(), &value)?; + let mut list_copy = self.get_list()?; + list_copy.push(value); + self.write_list(&list_copy)?; Ok(()) } + + /// Pops a value from a list + pub fn pop_list(&mut self) -> Result, Error> { + if !self.is_list() { + return Err(Error::NotAList); + } + let mut list_copy = self.get_list()?; + let value = list_copy.pop(); + self.write_list(&list_copy)?; + Ok(value) + } } diff --git a/crates/byondapi-rs/src/value/conversion.rs b/crates/byondapi-rs/src/value/conversion.rs index 9adf6c1..7ccd705 100644 --- a/crates/byondapi-rs/src/value/conversion.rs +++ b/crates/byondapi-rs/src/value/conversion.rs @@ -100,3 +100,12 @@ impl TryFrom<&ByondValue> for String { value.get_string() } } + +impl TryFrom<&[ByondValue]> for ByondValue { + type Error = Error; + fn try_from(value: &[ByondValue]) -> Result { + let res = ByondValue::new_list()?; + res.write_list(value)?; + Ok(res) + } +} diff --git a/crates/byondapi-rs/src/value/functions.rs b/crates/byondapi-rs/src/value/functions.rs index 152b9a1..d9eae89 100644 --- a/crates/byondapi-rs/src/value/functions.rs +++ b/crates/byondapi-rs/src/value/functions.rs @@ -35,7 +35,8 @@ impl ByondValue { if !self.is_str() { return Err(Error::NotAString); } - let len = self.builtin_length()?.get_number()? as u32; + // add one for le null terminator + let len = self.builtin_length()?.get_number()? as u32 + 1; let mut buff: Vec = Vec::with_capacity(len as usize); let mut capacity = buff.capacity() as u32; // Safety: buffer capacity is passed to byond, which makes sure it writes in-bound @@ -46,8 +47,8 @@ impl ByondValue { &mut capacity ))? } - // Safety: buffer should be written to at this point - unsafe { buff.set_len(len as usize) }; + // Safety: buffer should be written to at this point, ignoring null terminator + unsafe { buff.set_len(len as usize - 1) }; CString::new(buff).map_err(|_| Error::NonUtf8String) diff --git a/crates/byondapi-sys/src/lib.rs b/crates/byondapi-sys/src/lib.rs index 52652e6..8a9d1a2 100644 --- a/crates/byondapi-sys/src/lib.rs +++ b/crates/byondapi-sys/src/lib.rs @@ -117,9 +117,9 @@ impl ByondApi { pub unsafe fn ByondValue_IsList(&self, v: *const CByondValue) -> bool { self.internal.ByondValue_IsList(v) } - pub unsafe fn ByondValue_IsTrue(&self, v: *const CByondValue) -> bool { - self.internal.ByondValue_IsTrue(v) - } + //pub unsafe fn ByondValue_IsTrue(&self, v: *const CByondValue) -> bool { + // self.internal.ByondValue_IsTrue(v) + //} pub unsafe fn ByondValue_GetNum(&self, v: *const CByondValue) -> f32 { self.internal.ByondValue_GetNum(v) }