From 606f4ea5259220adcf44d030a27157c6567c7d12 Mon Sep 17 00:00:00 2001 From: CoffeeKat <56778689+jupyterkat@users.noreply.github.com> Date: Thu, 14 Dec 2023 20:18:31 +1100 Subject: [PATCH] update to 1621 (#9) * export this as well * global_ref * use oncelock to not overflow tls storage * some other changes * update to 1621 --- crates/byondapi-rs/Cargo.toml | 4 +- crates/byondapi-rs/src/lib.rs | 16 +- crates/byondapi-rs/src/map.rs | 1 - crates/byondapi-rs/src/prelude.rs | 1 + crates/byondapi-rs/src/typecheck_trait.rs | 2 +- crates/byondapi-rs/src/value/constructors.rs | 10 + crates/byondapi-rs/src/value/functions.rs | 18 +- crates/byondapi-rs/src/{ => value}/list.rs | 11 +- crates/byondapi-rs/src/value/mod.rs | 9 +- crates/byondapi-sys/Cargo.toml | 4 +- .../byondapi-sys/headers/515-1621/byondapi.h | 609 ++++++++++++++++++ crates/byondapi-sys/src/lib.rs | 10 +- tools/setup_byond_linux.sh | 2 +- tools/setup_byond_windows.sh | 2 +- 14 files changed, 670 insertions(+), 29 deletions(-) rename crates/byondapi-rs/src/{ => value}/list.rs (92%) create mode 100644 crates/byondapi-sys/headers/515-1621/byondapi.h diff --git a/crates/byondapi-rs/Cargo.toml b/crates/byondapi-rs/Cargo.toml index e02950e..c3ef9e0 100644 --- a/crates/byondapi-rs/Cargo.toml +++ b/crates/byondapi-rs/Cargo.toml @@ -20,5 +20,5 @@ walkdir = "2.4.0" inventory = "0.3.13" [features] -default = ["byond-515-1620"] -byond-515-1620 = [] +default = ["byond-515-1621"] +byond-515-1621 = [] diff --git a/crates/byondapi-rs/src/lib.rs b/crates/byondapi-rs/src/lib.rs index 2860032..d8671a2 100644 --- a/crates/byondapi-rs/src/lib.rs +++ b/crates/byondapi-rs/src/lib.rs @@ -10,7 +10,6 @@ pub use error::Error; pub mod byond_string; pub mod global_call; -pub mod list; pub mod prelude; pub mod typecheck_trait; pub mod value; @@ -50,10 +49,15 @@ pub struct InitFunc(pub fn() -> ()); #[macro_export] macro_rules! byond_string { ($s:literal) => {{ - thread_local! { - static STRING_ID: ::std::cell::OnceCell = ::std::cell::OnceCell::new(); - }; - STRING_ID - .with(|cell| *cell.get_or_init(|| ::byondapi::byond_string::str_id_of($s).unwrap())) + static STRING_ID: ::std::sync::OnceLock = ::std::sync::OnceLock::new(); + *STRING_ID.get_or_init(|| ::byondapi::byond_string::str_id_of($s).unwrap()) + }}; +} + +#[macro_export] +macro_rules! byond_string_internal { + ($s:literal) => {{ + static STRING_ID: ::std::sync::OnceLock = ::std::sync::OnceLock::new(); + *STRING_ID.get_or_init(|| crate::byond_string::str_id_of($s).unwrap()) }}; } diff --git a/crates/byondapi-rs/src/map.rs b/crates/byondapi-rs/src/map.rs index c2fd384..d46fdfe 100644 --- a/crates/byondapi-rs/src/map.rs +++ b/crates/byondapi-rs/src/map.rs @@ -56,7 +56,6 @@ pub fn byond_block(corner1: ByondXYZ, corner2: ByondXYZ) -> Result bool; //// Check if this is true-ish. - //fn is_true(&self) -> bool; + fn is_true(&self) -> bool; } diff --git a/crates/byondapi-rs/src/value/constructors.rs b/crates/byondapi-rs/src/value/constructors.rs index 0fd88cd..1460b38 100644 --- a/crates/byondapi-rs/src/value/constructors.rs +++ b/crates/byondapi-rs/src/value/constructors.rs @@ -47,6 +47,16 @@ impl ByondValue { }) } + pub fn new_global_ref() -> Self { + Self(CByondValue { + type_: 0x0E, + junk1: 0, + junk2: 0, + junk3: 0, + data: byondapi_sys::ByondValueData { ref_: 1 }, + }) + } + pub fn new_str>>(s: S) -> Result { let c_str = CString::new(s.into()).unwrap(); let str_id = unsafe { byond().Byond_AddGetStrId(c_str.as_ptr()) }; diff --git a/crates/byondapi-rs/src/value/functions.rs b/crates/byondapi-rs/src/value/functions.rs index 24387f6..0d68523 100644 --- a/crates/byondapi-rs/src/value/functions.rs +++ b/crates/byondapi-rs/src/value/functions.rs @@ -235,8 +235,22 @@ impl ByondValue { } } -/// # List operations by key instead of indices (why are they even here lumlum?????) -impl ByondValue {} +/// # Refcount operations +impl ByondValue { + pub fn increment_ref(&mut self) { + unsafe { byond().ByondValue_IncRef(&self.0) } + } + + pub fn decrement_ref(&mut self) { + unsafe { byond().ByondValue_DecRef(&self.0) } + } + + pub fn get_refcount(&self) -> Result { + let mut result = 0u32; + unsafe { map_byond_error!(byond().Byond_Refcount(&self.0, &mut result))? }; + Ok(result) + } +} /// # Builtins impl ByondValue { diff --git a/crates/byondapi-rs/src/list.rs b/crates/byondapi-rs/src/value/list.rs similarity index 92% rename from crates/byondapi-rs/src/list.rs rename to crates/byondapi-rs/src/value/list.rs index 7f84761..905c095 100644 --- a/crates/byondapi-rs/src/list.rs +++ b/crates/byondapi-rs/src/value/list.rs @@ -1,7 +1,10 @@ -use crate::{static_global::byond, typecheck_trait::ByondTypeCheck, value::ByondValue, Error}; +use crate::{ + byond_string_internal, 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 + /// Gets an array of all the list elements, this means keys for assoc lists and values for regular lists pub fn get_list(&self) -> Result, Error> { use std::cell::RefCell; if !self.is_list() { @@ -103,7 +106,7 @@ impl ByondValue { if !self.is_list() { return Err(Error::NotAList); } - self.call("Add", &[value])?; + self.call_id(byond_string_internal!("Add"), &[value])?; Ok(()) } @@ -117,7 +120,7 @@ impl ByondValue { return Ok(None); } let value = self.read_list_index(len as f32)?; - self.call("Remove", &[value])?; + self.call_id(byond_string_internal!("Remove"), &[value])?; Ok(Some(value)) } } diff --git a/crates/byondapi-rs/src/value/mod.rs b/crates/byondapi-rs/src/value/mod.rs index fadf956..ca0f883 100644 --- a/crates/byondapi-rs/src/value/mod.rs +++ b/crates/byondapi-rs/src/value/mod.rs @@ -15,6 +15,7 @@ unsafe impl Send for ByondValue {} pub mod constructors; pub mod conversion; pub mod functions; +pub mod list; pub mod pointer; pub mod trait_impls; @@ -55,8 +56,8 @@ impl ByondTypeCheck for ByondValue { is_pointer_shim(self) } - // fn is_true(&self) -> bool { - // // Safety: This operation only fails if our CByondValue is invalid, which cannot happen. - // unsafe { byond().ByondValue_IsTrue(&self.0) } - // } + fn is_true(&self) -> bool { + // Safety: This operation only fails if our CByondValue is invalid, which cannot happen. + unsafe { byond().ByondValue_IsTrue(&self.0) } + } } diff --git a/crates/byondapi-sys/Cargo.toml b/crates/byondapi-sys/Cargo.toml index 22e3ef1..b744140 100644 --- a/crates/byondapi-sys/Cargo.toml +++ b/crates/byondapi-sys/Cargo.toml @@ -25,5 +25,5 @@ rustc_version = "0.4.0" walkdir = "2.4.0" [features] -default = ["byond-515-1620"] -byond-515-1620 = [] +default = ["byond-515-1621"] +byond-515-1621 = [] diff --git a/crates/byondapi-sys/headers/515-1621/byondapi.h b/crates/byondapi-sys/headers/515-1621/byondapi.h new file mode 100644 index 0000000..4e76454 --- /dev/null +++ b/crates/byondapi-sys/headers/515-1621/byondapi.h @@ -0,0 +1,609 @@ +#ifndef BYONDAPI_H +#define BYONDAPI_H + +/* + BYOND public API version 515.1621 + + Because for some reason nobody can get their ducks in a row, all of the + exported functions from byondcore.dll/libbyond.so are limited to C + conventions only. A header and source file for C++ wrappers is available + for inclusion in your projects. + */ + +#if defined(WIN32) || defined(WIN64) +#define IS_WINDOWS +#else +#define IS_LINUX +#endif + + +// See https://github.com/cpredef/predef/blob/master/Architectures.md +#if defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__X86__) +#define _X86 +#define _X86ORX64 +#define DM_32BIT +#elif defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(_WIN64) || defined(WIN64) +#define _X64 +#define _X86ORX64 +#define DM_64BIT +#elif defined(__arm__) || defined(_M_ARM) +#define _ARM +#if defined(__LP64__) || defined(_LP64) +#define DM_64BIT +#else +#define DM_32BIT +#endif +#endif + + + +/*types*/ +typedef unsigned char u1c; +typedef signed char s1c; +typedef unsigned short u2c; +typedef signed short s2c; +#ifdef DM_64BIT +typedef unsigned int u4c; +typedef signed int s4c; +#else +typedef unsigned long u4c; +typedef signed long s4c; +#endif + +#if defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 s8c; + typedef unsigned __int64 u8c; +#else + typedef long long int s8c; + typedef unsigned long long int u8c; +#endif + +union u4cOrPointer { + u4c num; + void *ptr; +}; + +#ifdef __GNUC__ +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#else +#define GCC_VERSION 0 +#endif + + +// determine if move-constructor and move-assignment are supported +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#define _SUPPORT_MOVES +#elif defined(__GNUC__) && GCC_VERSION >= 50000 +#define _SUPPORT_MOVES +#endif + + +#define u1cMASK ((u1c)0xff) +#define u2cMASK ((u2c)0xffff) +#define u3cMASK ((u4c)0xffffffL) +#define u4cMASK ((u4c)0xffffffffL) + +#define u1cMAX u1cMASK +#define u2cMAX u2cMASK +#define u3cMAX u3cMASK +#define u4cMAX u4cMASK + +#define s1cMAX 0x7f +#define s1cMIN (-0x7f) +#define s2cMAX 0x7fff +#define s2cMIN (-0x7fff) +#define s4cMAX 0x7fffffffL +#define s4cMIN (-0x7fffffffL) + +#define NONE u2cMAX +#define NOCH u1cMAX + +#ifdef WIN32 +#define THREAD_VAR __declspec(thread) +#else +#define THREAD_VAR __thread +#endif + +/* dll export stuff */ +#ifdef WIN32 +#define DUNGPUB __declspec(dllimport) +#define BYOND_EXPORT __declspec(dllexport) // for functions in user-defined DLLs for use with call_ext() +#else // unix/g++, combine with -fvisibility=hidden to hide non-exported symbols +#define DUNGPUB +#define BYOND_EXPORT __attribute__ ((visibility("default"))) // for functions in user-defined .so libraries for use with call_ext() +#endif + + +// ByondValue + +/* + Many of the routines in this library return a bool value. If true, the + operation succeeded. If false, it failed and calling Byond_LastError() will + return an error string. + + The C++ wrappers change this true/false behavior to raise exceptions instead. + This would be preferable across the board but throwing exceptions across + module boundaries is bad juju. + */ + +extern "C" { + +/** + * Gets the last error from a failed call + * The result is a static string that does not need to be freed. + * @return Error message + */ +DUNGPUB char const *Byond_LastError(); + +/** + * Gets the current BYOND version + * @param version Pointer to the major version number + * @param build Pointer to the build number + */ +DUNGPUB void Byond_GetVersion(u4c *version, u4c *build); + +/** + * Gets the DMB version + * @return Version number the .dmb was built with + */ +DUNGPUB u4c Byond_GetDMBVersion(); + +typedef u1c ByondValueType; +union ByondValueData { + u4c ref; //!< 4-byte reference ID + float num; //!< floating-point number +}; + +struct CByondValue { + ByondValueType type; //!< 1-byte intrinsic data type + u1c junk1, junk2, junk3; //!< padding + ByondValueData data; //!< 4-byte reference ID or floating point number +}; + +/** + * Fills a CByondValue struct with a null value. + * @param v Pointer to CByondValue + */ +DUNGPUB void ByondValue_Clear(CByondValue *v); + +/** + * Reads CByondVale's 1-byte data type + * @param v Pointer to CByondValue + * @return Type of value + */ +DUNGPUB ByondValueType ByondValue_Type(CByondValue const *v); + +/** + * @param v Pointer to CByondValue + * @return True if value is null + */ +DUNGPUB bool ByondValue_IsNull(CByondValue const *v); +/** + * @param v Pointer to CByondValue + * @return True if value is a numeric type + */ +DUNGPUB bool ByondValue_IsNum(CByondValue const *v); +/** + * @param v Pointer to CByondValue + * @return True if value is a string + */ +DUNGPUB bool ByondValue_IsStr(CByondValue const *v); +/** + * @param v Pointer to CByondValue + * @return True if value is a list (any list type, not just user-defined) + */ +DUNGPUB bool ByondValue_IsList(CByondValue const *v); + +/** + * Determines if a value is logically true or false + * + * @param v Pointer to CByondValue + * @return Truthiness of value + */ +DUNGPUB bool ByondValue_IsTrue(CByondValue const *v); + +/** + * @param v Pointer to CByondValue + * @return Floating point number for v, or 0 if not numeric + */ +DUNGPUB float ByondValue_GetNum(CByondValue const *v); +/** + * @param v Pointer to CByondValue + * @return Reference ID if value is a reference type, or 0 otherwise + */ +DUNGPUB u4c ByondValue_GetRef(CByondValue const *v); + +/** + * Fills a CByondValue struct with a floating point number. + * @param v Pointer to CByondValue + * @param f Floating point number + */ +DUNGPUB void ByondValue_SetNum(CByondValue *v, float f); +/** + * Creates a string and sets CByondValue to a temporary reference to that string. + * Blocks if not on the main thread. If string creation fails, the struct is set to null. + * @param v Pointer to CByondValue + * @param str Null-terminated UTF-8 string + * @see Byond_AddGetStrId() + */ +DUNGPUB void ByondValue_SetStr(CByondValue *v, char const *str); +/** + * Fills a CByondValue struct with a reference (object) type. Does not validate. + * @param v Pointer to CByondValue + * @param type 1-byte teference type + * @param ref 4-byte reference ID; for most types, an ID of NONE is invalid + * @see Byond_TestRef() + */ +DUNGPUB void ByondValue_SetRef(CByondValue *v, ByondValueType type, u4c ref); + +/** + * Compares two values for equality + * @param a Pointer to CByondValue + * @param b Pointer to CByondValue + * @return True if values are equal + */ +DUNGPUB bool ByondValue_Equals(CByondValue const *a, CByondValue const *b); + +// Other useful structs + +struct CByondXYZ { + s2c x, y, z; //!< signed 2-byte integer coordinates + s2c junk; //!< padding +}; + +/* + In the following functions, anything that fills a result value (e.g., + ReadVar, CallProc) will create a temporary reference to the value. So if + the result is an object or list or such, it will remain valid until the + end of the current tick unless something explicitly deletes it. You can + also let go of the temporary reference early by calling Byond_DecRef(). + + If the validity of a reference is ever in doubt, call Byond_TestRef(). + + Thread safety: + + Anything called outside of the main thread will block, unless otherwise + noted. + */ + +typedef CByondValue (*ByondCallback)(void *); +/** + * Runs a function as a callback on the main thread (or right away if already there) + * Blocking is optional. If already on the main thread, the block parameter is meaningless. + * @param callback Function pointer to CByondValue function(void*) + * @param data Void pointer (argument to function) + * @param block True if this call should block while waiting for the callback to finish; false if not + * @return CByondValue returned by the function (if it blocked; null if not) + */ +DUNGPUB CByondValue Byond_ThreadSync(ByondCallback callback, void *data, bool block=false); + +/** + * Returns a reference to an existing string ID, but does not create a new string ID. + * Blocks if not on the main thread. + * @param str Null-terminated string + * @return ID of string; NONE if string does not exist + */ +DUNGPUB u4c Byond_GetStrId(char const *str); // does not add a string to the tree if not found; returns NONE if no string match +/** + * Returns a reference to an existing string ID or creates a new string ID with a temporary reference. + * Blocks if not on the main thread. + * @param str Null-terminated string + * @return ID of string; NONE if string creation failed + */ +DUNGPUB u4c Byond_AddGetStrId(char const *str); // adds a string to the tree if not found + +/** + * Reads an object variable by name. + * Blocks if not on the main thread. + * @param loc Object that owns the var + * @param varname Var name as null-terminated string + * @param result Pointer to accept result + * @return True on success + */ +DUNGPUB bool Byond_ReadVar(CByondValue const *loc, char const *varname, CByondValue *result); +/** + * Reads an object variable by the string ID of its var name. + * ID can be cached ahead of time for performance. + * Blocks if not on the main thread. + * @param loc Object that owns the var + * @param varname Var name as string ID + * @param result Pointer to accept result + * @return True on success + * @see Byond_GetStrId() + */ +DUNGPUB bool Byond_ReadVarByStrId(CByondValue const *loc, u4c varname, CByondValue *result); +/** + * Writes an object variable by name. + * Blocks if not on the main thread. + * @param loc Object that owns the var + * @param varname Var name as null-terminated string + * @param val New value + * @return True on success + */ +DUNGPUB bool Byond_WriteVar(CByondValue const *loc, char const *varname, CByondValue const *val); +/** + * Writes an object variable by the string ID of its var name. + * ID can be cached ahead of time for performance. + * Blocks if not on the main thread. + * @param loc Object that owns the var + * @param varname Var name as string ID + * @param val New value + * @return True on success + */ +DUNGPUB bool Byond_WriteVarByStrId(CByondValue const *loc, u4c varname, CByondValue const *val); + +/** + * Creates an empty list with a temporary reference. Equivalent to list(). + * Blocks if not on the main thread. + * @param result Result + * @return True on success + */ +DUNGPUB bool Byond_CreateList(CByondValue *result); + +/** + * Reads items from a list. + * Blocks if not on the main thread. + * @param loc The list to read + * @param list CByondValue array, allocated by caller (can be null if querying length) + * @param len Pointer to length of array (in items); receives the number of items read on success, or required length of array if not big enough + * @return True on success; false with *len=0 for failure; false with *len=required size if array is not big enough + */ +DUNGPUB bool Byond_ReadList(CByondValue const *loc, CByondValue *list, u4c *len); + +/** + * Writes items to a list, in place of old contents. + * Blocks if not on the main thread. + * @param loc The list to fill + * @param list CByondValue array of items to write + * @param len Number of items to write + * @return True on success + */ +DUNGPUB bool Byond_WriteList(CByondValue const *loc, CByondValue const *list, u4c len); + +/** + * Reads items as key,value pairs from an associative list, storing them sequentially as key1, value1, key2, value2, etc. + * Blocks if not on the main thread. + * @param loc The list to read + * @param list CByondValue array, allocated by caller (can be null if querying length) + * @param len Pointer to length of array (in items); receives the number of items read on success, or required length of array if not big enough + * @return True on success; false with *len=0 for failure; false with *len=required size if array is not big enough + */ +DUNGPUB bool Byond_ReadListAssoc(CByondValue const *loc, CByondValue *list, u4c *len); + +/** + * Reads an item from a list. + * Blocks if not on the main thread. + * @param loc The list + * @param idx The index in the list (may be a number, or a non-number if using associative lists) + * @param result Pointer to accept result + * @return True on success + */ +DUNGPUB bool Byond_ReadListIndex(CByondValue const *loc, CByondValue const *idx, CByondValue *result); +/** + * Writes an item to a list. + * Blocks if not on the main thread. + * @param loc The list + * @param idx The index in the list (may be a number, or a non-number if using associative lists) + * @param val New value + * @return True on success + */ +DUNGPUB bool Byond_WriteListIndex(CByondValue const *loc, CByondValue const *idx, CByondValue const *val); + +/** + * Reads from a BYOND pointer + * Blocks if not on the main thread. + * @param ptr The BYOND pointer + * @param result Pointer to accept result + * @return True on success + */ +DUNGPUB bool Byond_ReadPointer(CByondValue const *ptr, CByondValue *result); +/** + * Writes to a BYOND pointer + * Blocks if not on the main thread. + * @param ptr The BYOND pointer + * @param val New value + * @return True on success + */ +DUNGPUB bool Byond_WritePointer(CByondValue const *ptr, CByondValue const *val); + +/* + Proc calls: + + arg is an array of arguments; can be null arg_count is 0. + + The call is implicitly a waitfor=0 call; if the callee sleeps it will return + immediately and finish later. + */ + +/** + * Calls an object proc by name. + * The proc call is treated as waitfor=0 and will return immediately on sleep. + * Blocks if not on the main thread. + * @param src The object that owns the proc + * @param name Proc name as null-terminated string + * @param arg Array of arguments + * @param arg_count Number of arguments + * @param result Pointer to accept result + * @return True on success + */ +DUNGPUB bool Byond_CallProc(CByondValue const *src, char const *name, CByondValue const *arg, u4c arg_count, CByondValue *result); +/** + * Calls an object proc by name, where the name is a string ID. + * The proc call is treated as waitfor=0 and will return immediately on sleep. + * Blocks if not on the main thread. + * @param src The object that owns the proc + * @param name Proc name as string ID + * @param arg Array of arguments + * @param arg_count Number of arguments + * @param result Pointer to accept result + * @return True on success + * @see Byond_GetStrId() + */ +DUNGPUB bool Byond_CallProcByStrId(CByondValue const *src, u4c name, CByondValue const *arg, u4c arg_count, CByondValue *result); + +/** + * Calls a global proc by name. + * The proc call is treated as waitfor=0 and will return immediately on sleep. + * Blocks if not on the main thread. + * @param name Proc name as null-terminated string + * @param arg Array of arguments + * @param arg_count Number of arguments + * @param result Pointer to accept result + * @return True on success + */ +DUNGPUB bool Byond_CallGlobalProc(char const *name, CByondValue const *arg, u4c arg_count, CByondValue *result); // result MUST be initialized first! +/** + * Calls a global proc by name, where the name is a string ID. + * The proc call is treated as waitfor=0 and will return immediately on sleep. + * Blocks if not on the main thread. + * @param name Proc name as string ID + * @param arg Array of arguments + * @param arg_count Number of arguments + * @param result Pointer to accept result + * @return True on success + * @see Byond_GetStrId() + */ +DUNGPUB bool Byond_CallGlobalProcByStrId(u4c name, CByondValue const *arg, u4c arg_count, CByondValue *result); // result MUST be initialized first! + +/** + * Uses BYOND's internals to represent a value as text + * Blocks if not on the main thread. + * @param src The value to convert to text + * @param buf char array, allocated by caller (can be null if querying length) + * @param buflen Pointer to length of array in bytes; receives the string length (including trailing null) on success, or required length of array if not big enough + * @return True on success; false with *buflen=0 for failure; false with *buflen=required size if array is not big enough + */ +DUNGPUB bool Byond_ToString(CByondValue const *src, char *buf, u4c *buflen); + +// Other builtins + +/** + * Equivalent to calling block(x1,y1,z1, x2,y2,z2). + * Blocks if not on the main thread. + * @param corner1 One corner of the block + * @param corner2 Another corner of the block + * @param list CByondValue array, allocated by caller (can be null if querying length) + * @param len Pointer to length of array (in items); receives the number of items read on success, or required length of array if not big enough + * @return True on success; false with *len=0 for failure; false with *len=required size if array is not big enough + */ +DUNGPUB bool Byond_Block(CByondXYZ const *corner1, CByondXYZ const *corner2, CByondValue *list, u4c *len); + +/** + * Equivalent to calling length(value). + * Blocks if not on the main thread. + * @param src The value + * @param result Pointer to accept result as a CByondValue (intended for future possible override of length) + * @return True on success + */ +DUNGPUB bool Byond_Length(CByondValue const *src, CByondValue *result); + +/** + * Equivalent to calling locate(type), or locate(type) in list. + * Blocks if not on the main thread. + * @param type The type to locate + * @param list The list to locate in; can be a null pointer instead of a CByondValue to locate(type) without a list + * @param result Pointer to accept result; can be null if nothing is found + * @return True on success (including if nothing is found); false on error + */ +DUNGPUB bool Byond_LocateIn(CByondValue const *type, CByondValue const *list, CByondValue *result); + +/** + * Equivalent to calling locate(x,y,z) + * Blocks if not on the main thread. + * Result is null if coords are invalid. + * @param xyz The x,y,z coords + * @param result Pointer to accept result + * @return True (always) + */ +DUNGPUB bool Byond_LocateXYZ(CByondXYZ const *xyz, CByondValue *result); + +/** + * Equivalent to calling new type(...) + * Blocks if not on the main thread. + * @param type The type to create (type path or string) + * @param arg Array of arguments + * @param arg_count Number of arguments + * @param result Pointer to accept result + * @return True on success + */ +DUNGPUB bool Byond_New(CByondValue const *type, CByondValue const *arg, u4c arg_count, CByondValue *result); + +/** + * Equivalent to calling new type(arglist) + * Blocks if not on the main thread. + * @param type The type to create (type path or string) + * @param arglist Arguments, as a reference to an arglist + * @param result Pointer to accept result + * @return True on success + */ +DUNGPUB bool Byond_NewArglist(CByondValue const *type, CByondValue const *arglist, CByondValue *result); // result MUST be initialized first! + +/** + * Equivalent to calling refcount(value) + * Blocks if not on the main thread. + * @param src The object to refcount + * @param result Pointer to accept result + * @return True on success + */ +DUNGPUB bool Byond_Refcount(CByondValue const *src, u4c *result); // result MUST be initialized first! + +/** + * Get x,y,z coords of an atom + * Blocks if not on the main thread. + * @param src The object to read + * @param xyz Pointer to accept CByondXYZ result + * @return True on success + */ +DUNGPUB bool Byond_XYZ(CByondValue const *src, CByondXYZ *xyz); // still returns true if the atom is off-map, but xyz will be 0,0,0 + +/* + Generally you don't want to mess with inc/decref calls, except that for + temporary references you can use Byond_DecRef() to let go of the temporary + reference. + + Call ByondValue_IncRef() to create a permanent reference to an object + within Byondapi. It will exist until ByondValue_DecRef() removes it or the + object is hard-deleted. + + ByondValue_DecRef() will remove a permanent reference created by Byondapi. + If there is no permanent reference, it will remove any temporary + reference that was set to expire when the tick ends. If Byondapi has no + references to the object, the call will be ignored. + + These only apply to ref types, not null/num/string. Any runtime errors + caused by decref (if the object is deleted or another object ends up + getting deleted as an indirect result) are ignored. + */ + +/** + * Mark a reference as in use by Byondapi + * This should be done for any temporary references returned from other calls, if they need to be saved awhile. + * Blocks if not on the main thread. + * @param src The object to incref + */ +DUNGPUB void ByondValue_IncRef(CByondValue const *src); + +/** + * Mark a reference as no longer in use by Byondapi + * This can be used for temporary references to let them go immediately. + * Blocks if not on the main thread. + * @param src The object to decref + */ +DUNGPUB void ByondValue_DecRef(CByondValue const *src); + +/** + * Test if a reference-type CByondValue is valid + * Blocks if not on the main thread. + * @param src Pointer to the reference to test; will be filled with null if the reference is invalid + * @return True if ref is valid; false if not + */ +// Returns true if the ref is valid. +// Returns false if the ref was not valid and had to be changed to null. +// This only applies to ref types, not null/num/string which are always valid. +DUNGPUB bool Byond_TestRef(CByondValue *src); + +}; // extern "C" + + + +#endif // BYONDAPI_H diff --git a/crates/byondapi-sys/src/lib.rs b/crates/byondapi-sys/src/lib.rs index 8a9d1a2..1582a52 100644 --- a/crates/byondapi-sys/src/lib.rs +++ b/crates/byondapi-sys/src/lib.rs @@ -17,8 +17,8 @@ compile_error!("BYOND API only supports Windows and Linux"); // Include byondapi-c bindings (generated by build.rs) #[allow(dead_code)] mod byond_rawbind { - #[cfg(feature = "byond-515-1620")] - include!(concat!(env!("OUT_DIR"), "/bindings_515_1620.rs")); + #[cfg(feature = "byond-515-1621")] + include!(concat!(env!("OUT_DIR"), "/bindings_515_1621.rs")); } /// we must simply hope this never changes @@ -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) } diff --git a/tools/setup_byond_linux.sh b/tools/setup_byond_linux.sh index b634912..34c256e 100644 --- a/tools/setup_byond_linux.sh +++ b/tools/setup_byond_linux.sh @@ -2,7 +2,7 @@ set -euo pipefail BYOND_MAJOR=515 -BYOND_MINOR=1620 +BYOND_MINOR=1621 if [ -d "$HOME/BYOND/byond/bin" ] && grep -Fxq "${BYOND_MAJOR}.${BYOND_MINOR}" $HOME/BYOND/version.txt; then diff --git a/tools/setup_byond_windows.sh b/tools/setup_byond_windows.sh index a087016..c12a956 100644 --- a/tools/setup_byond_windows.sh +++ b/tools/setup_byond_windows.sh @@ -2,7 +2,7 @@ set -euo pipefail BYOND_MAJOR=515 -BYOND_MINOR=1620 +BYOND_MINOR=1621 if [ -d "$HOME/BYOND/byond/bin" ] && grep -Fxq "${BYOND_MAJOR}.${BYOND_MINOR}" $HOME/BYOND/version.txt; then