|
| 1 | +/* This comment bypasses grep checks */ /var/__dreamluau |
| 2 | + |
| 3 | +/* This comment also bypasses grep checks */ /var/__dreamluau_exists |
| 4 | + |
| 5 | +#define DREAMLUAU_EXISTS (__dreamluau_exists ||= fexists(DREAMLUAU)) |
| 6 | + |
| 7 | +#define DREAMLUAU (world.system_type == MS_WINDOWS ? "dreamluau.dll" : (__dreamluau ||= __detect_auxtools("dreamluau"))) |
| 8 | + |
| 9 | +#define DREAMLUAU_CALL(func) (!DREAMLUAU_EXISTS) ? null : call_ext(DREAMLUAU, "byond:" + #func) |
| 10 | + |
| 11 | +/** |
| 12 | + * All of the following functions will return a string if the underlying rust code returns an error or a wrapped panic. |
| 13 | + * The return values specified for each function are what they will return if successful. |
| 14 | + */ |
| 15 | + |
| 16 | +/** |
| 17 | + * As of 515.1631, byondapi does not provide direct access to `usr`. |
| 18 | + * Use this function to pass `usr` into the dreamluau binary so that luau scripts can retrieve it. |
| 19 | + * |
| 20 | + * @return null on success |
| 21 | + */ |
| 22 | +#define DREAMLUAU_SET_USR DREAMLUAU_CALL(set_usr)(usr) |
| 23 | + |
| 24 | + |
| 25 | +/** |
| 26 | + * Sets the execution limit, in milliseconds. |
| 27 | + * |
| 28 | + * @param limit the new execution limit |
| 29 | + * |
| 30 | + * @return null on success |
| 31 | + */ |
| 32 | +#define DREAMLUAU_SET_EXECUTION_LIMIT_MILLIS(limit) DREAMLUAU_CALL(set_execution_limit_millis)((limit)) |
| 33 | + |
| 34 | +/** |
| 35 | + * Sets the execution limit, in seconds. |
| 36 | + * |
| 37 | + * @param limit the new execution limit |
| 38 | + * |
| 39 | + * @return null on success |
| 40 | + */ |
| 41 | +#define DREAMLUAU_SET_EXECUTION_LIMIT_SECS(limit) DREAMLUAU_CALL(set_execution_limit_secs)((limit)) |
| 42 | + |
| 43 | +/** |
| 44 | + * Clears the execution limit, allowing scripts to run as long as they need to. |
| 45 | + * |
| 46 | + * WARNING: This allows infinite loops to block Dream Daemon indefinitely, with no safety checks. |
| 47 | + * Do not use this if you have no reason for scripts to run arbitrarily long. |
| 48 | + * |
| 49 | + * @return null on success |
| 50 | + */ |
| 51 | +#define DREAMLUAU_CLEAR_EXECUTION_LIMIT DREAMLUAU_CALL(clear_execution_limit) |
| 52 | + |
| 53 | +//Wrapper setters/clearers |
| 54 | + |
| 55 | +/** |
| 56 | + * Set the wrapper for instancing new datums with `dm.new`. |
| 57 | + * Clears it if the argument is null. |
| 58 | + * If unset, the object will be instantiated using the default `new` instruction. |
| 59 | + * |
| 60 | + * The wrapper must be a proc with the signature `(type as path, list/arguments)`. |
| 61 | + * |
| 62 | + * @param wrapper the path to the proc to use as the new wrapper |
| 63 | + * |
| 64 | + * @return null on success |
| 65 | + */ |
| 66 | +#define DREAMLUAU_SET_NEW_WRAPPER(wrapper) DREAMLUAU_CALL(set_new_wrapper)((wrapper)) |
| 67 | + |
| 68 | +/** |
| 69 | + * Set the wrapper for reading the vars of an object. |
| 70 | + * Clears it if the argument is null. |
| 71 | + * If unset, the var will be read directly, without any safety checks. |
| 72 | + * |
| 73 | + * The wrapper must be a proc with the signature `(target, var)`. |
| 74 | + * |
| 75 | + * @param wrapper the path to the proc to use as the new wrapper |
| 76 | + * |
| 77 | + * @return null on success |
| 78 | + */ |
| 79 | +#define DREAMLUAU_SET_VAR_GET_WRAPPER(wrapper) DREAMLUAU_CALL(set_var_get_wrapper)((wrapper)) |
| 80 | + |
| 81 | +/** |
| 82 | + * Set the wrapper for writing the vars of an object. |
| 83 | + * Clears it if the argument is null. |
| 84 | + * If unset, the var will be modified directly, without any safety checks. |
| 85 | + * |
| 86 | + * The wrapper must be a proc with the signature `(target, var, value)`. |
| 87 | + * |
| 88 | + * @param wrapper the path to the proc to use as the new wrapper |
| 89 | + * |
| 90 | + * @return null on success |
| 91 | + */ |
| 92 | +#define DREAMLUAU_SET_VAR_SET_WRAPPER(wrapper) DREAMLUAU_CALL(set_var_set_wrapper)((wrapper)) |
| 93 | + |
| 94 | +/** |
| 95 | + * Set the wrapper for calling a proc on an object. |
| 96 | + * Clears it if the argument is null. |
| 97 | + * If unset, the proc will be called directly, without any safety checks. |
| 98 | + * |
| 99 | + * The wrapper must be a proc with the signature `(target, procname as text, list/arguments)`. |
| 100 | + * |
| 101 | + * @param wrapper the path to the proc to use as the new wrapper |
| 102 | + * |
| 103 | + * @return null on success |
| 104 | + */ |
| 105 | +#define DREAMLUAU_SET_OBJECT_CALL_WRAPPER(wrapper) DREAMLUAU_CALL(set_object_call_wrapper)((wrapper)) |
| 106 | + |
| 107 | +/** |
| 108 | + * Set the wrapper for calling a global proc. |
| 109 | + * Clears it if the argument is null. |
| 110 | + * If unset, the proc will be called directly, without any safety checks. |
| 111 | + * |
| 112 | + * The wrapper must be a proc with the signature `(procname as text, list/arguments)`. |
| 113 | + * |
| 114 | + * @param wrapper the path to the proc to use as the new wrapper |
| 115 | + * |
| 116 | + * @return null on success |
| 117 | + */ |
| 118 | +#define DREAMLUAU_SET_GLOBAL_CALL_WRAPPER(wrapper) DREAMLUAU_CALL(set_global_call_wrapper)((wrapper)) |
| 119 | + |
| 120 | +/** |
| 121 | + * Set the wrapper for printing with the `print` function. |
| 122 | + * Clears it if the argument is null. |
| 123 | + * If unset, `print` will raise an error. |
| 124 | + * |
| 125 | + * The wrapper must be a proc with the signature `(list/arguments)`. |
| 126 | + * |
| 127 | + * @param wrapper the path to the proc to use as the new wrapper |
| 128 | + * |
| 129 | + * @return null on success |
| 130 | + */ |
| 131 | +#define DREAMLUAU_SET_PRINT_WRAPPER(wrapper) DREAMLUAU_CALL(set_print_wrapper)((wrapper)) |
| 132 | + |
| 133 | + |
| 134 | + |
| 135 | +/** |
| 136 | + * Create a new luau state. |
| 137 | + * |
| 138 | + * @return a handle to the created state. |
| 139 | + */ |
| 140 | +#define DREAMLUAU_NEW_STATE DREAMLUAU_CALL(new_state) |
| 141 | + |
| 142 | +/** |
| 143 | + * Some of the following functions return values that cannot be cleanly converted from luau to DM. |
| 144 | + * To account for this, these functions also return a list of variant specifiers, equivalent to |
| 145 | + * an array of objects of the type described beloe: |
| 146 | + * ``` |
| 147 | + * type Variants = { |
| 148 | + * key?: "error"|Array<Variants?> |
| 149 | + * value?: "error"|Array<Variants?> |
| 150 | + * } |
| 151 | + * ``` |
| 152 | + */ |
| 153 | + |
| 154 | +/** |
| 155 | + * The following 4 functions execute luau code and return |
| 156 | + * an associative list containing information about the result. |
| 157 | + * This list has the following params. |
| 158 | + * |
| 159 | + * - "status": either "finished", "sleep", "yield", or "error" |
| 160 | + * - "return_values": if "status" is "finished" or "yield", contains a list of the return values |
| 161 | + * - "variants": a list of variant specifiers for the "return_values" param |
| 162 | + * - "message": if "status" is "error", contains the error message |
| 163 | + * - "name": the name of the executed code, according to the `what` field of `debug.getinfo` |
| 164 | + */ |
| 165 | + |
| 166 | +/** |
| 167 | + * Load and execute a luau script. |
| 168 | + * |
| 169 | + * @param state the handle to the state |
| 170 | + * @param code the source code of the script to run |
| 171 | + * @param name an optional name to give to the script, for debugging purposes |
| 172 | + * |
| 173 | + * @return an associative list containing result information as specified above |
| 174 | + */ |
| 175 | +#define DREAMLUAU_LOAD DREAMLUAU_CALL(load) |
| 176 | + |
| 177 | +/** |
| 178 | + * Awaken the thread at the front of the specified state's sleeping thread queue. |
| 179 | + * |
| 180 | + * @param state the handle to the state |
| 181 | + * |
| 182 | + * @return an associative list containing result information as specified above |
| 183 | + */ |
| 184 | +#define DREAMLUAU_AWAKEN(state) DREAMLUAU_CALL(awaken)((state)) |
| 185 | + |
| 186 | +/** |
| 187 | + * Resume one of the state's yielded threads. |
| 188 | + * |
| 189 | + * @param state the handle to the state |
| 190 | + * @param index the index of the thread in the state's yielded threads list |
| 191 | + * @param ...arguments arguments that will be returned by the `coroutine.yield` that yielded the thread |
| 192 | + * |
| 193 | + * @return an associative list containing result information as specified above |
| 194 | + */ |
| 195 | +#define DREAMLUAU_RESUME DREAMLUAU_CALL(resume) |
| 196 | + |
| 197 | +/** |
| 198 | + * Call a function accessible from the global table. |
| 199 | + * |
| 200 | + * @param state the handle to the state |
| 201 | + * @param function a list of nested indices from the global table to the specified function |
| 202 | + * @param ...arguments arguments to pass to the function |
| 203 | + * |
| 204 | + * @return an associative list containing result information as specified above |
| 205 | + */ |
| 206 | +#define DREAMLUAU_CALL_FUNCTION DREAMLUAU_CALL(call_function) |
| 207 | + |
| 208 | +// State information collection functions |
| 209 | + |
| 210 | +/** |
| 211 | + * Obtain a copy of the state's global table, converted to DM. |
| 212 | + * |
| 213 | + * @param state the handle to the state |
| 214 | + * |
| 215 | + * @return an associative list with the follwing entries: |
| 216 | + * - "values": The actual values of the global table |
| 217 | + * - "variants": Variant specifiers for "values" |
| 218 | + */ |
| 219 | +#define DREAMLUAU_GET_GLOBALS(state) DREAMLUAU_CALL(get_globals)((state)) |
| 220 | + |
| 221 | +/** |
| 222 | + * List the names of all sleeping or yielded threads for the state. |
| 223 | + * |
| 224 | + * @param state the handle to the state |
| 225 | + * |
| 226 | + * @return an associative list with the following entries: |
| 227 | + * - "sleeps": A list of sleeping threads |
| 228 | + * - "yields": A list of yielded threads |
| 229 | + */ |
| 230 | +#define DREAMLUAU_LIST_THREADS(state) DREAMLUAU_CALL(list_threads)((state)) |
| 231 | + |
| 232 | +// Cleanup functions |
| 233 | + |
| 234 | +/** |
| 235 | + * Run garbage collection on the state. |
| 236 | + * |
| 237 | + * This may be necessary to prevent hanging references, as some |
| 238 | + * hard references may persist in unreachable luau objects that |
| 239 | + * would be collected after a garbage collection cycle or two. |
| 240 | + * |
| 241 | + * @param state the handle to the state |
| 242 | + * |
| 243 | + * @return null on success |
| 244 | + */ |
| 245 | +#define DREAMLUAU_COLLECT_GARBAGE(state) DREAMLUAU_CALL(collect_garbage)((state)) |
| 246 | + |
| 247 | +/** |
| 248 | + * Remove a sleeping thread from the sleep queue, without executing it. |
| 249 | + * |
| 250 | + * @param state the handle to the state |
| 251 | + * @param thread the index in the sleep queue to the target thread |
| 252 | + * |
| 253 | + * @return null on success |
| 254 | + */ |
| 255 | +#define DREAMLUAU_KILL_SLEEPING_THREAD(state, thread) DREAMLUAU_CALL(kill_sleeping_thread)((state), (thread)) |
| 256 | + |
| 257 | +/** |
| 258 | + * Remove a yielded thread from the yield table, without executing it. |
| 259 | + * |
| 260 | + * @param state the handle to the state |
| 261 | + * @param thread the index in the yield table to the target thread |
| 262 | + * |
| 263 | + * @return null on success |
| 264 | + */ |
| 265 | +#define DREAMLUAU_KILL_YIELDED_THREAD(state, thread) DREAMLUAU_CALL(kill_yielded_thread)((state), (thread)) |
| 266 | + |
| 267 | +/** |
| 268 | + * Delete a state. The state's handle will be freed for any new states created afterwards. |
| 269 | + * |
| 270 | + * @param state the handle to the state |
| 271 | + * |
| 272 | + * @return null on success |
| 273 | + */ |
| 274 | +#define DREAMLUAU_KILL_STATE(state) DREAMLUAU_CALL(kill_state)((state)) |
| 275 | + |
| 276 | +/** |
| 277 | + * Retrieve lua traceback info, containing every lua stack frame between the lua entrypoint and the re-entry to dm code. |
| 278 | + * |
| 279 | + * @param level the level of lua execution to get the traceback for, |
| 280 | + * with 1 being the lua code that executed the dm code that called this function, |
| 281 | + * 2 being the lua code that executed the dm code that executed the lua code |
| 282 | + * that executed the dm code that called this function, etc. |
| 283 | + * |
| 284 | + * @return the callstack of the specified lua level if valid, null if invalid |
| 285 | + */ |
| 286 | +#define DREAMLUAU_GET_TRACEBACK(index) DREAMLUAU_CALL(get_traceback)((index)) |
| 287 | + |
| 288 | +/** |
| 289 | + * Luau userdata corresponding to a ref-counted DM type counts as a hard reference for BYOND's garbage collector. |
| 290 | + * If you need to delete a DM object, and you cannot be certain that there are no references to it in any luau state, |
| 291 | + * call this function before deleting that object to disassociate it from any userdata in any luau state. |
| 292 | + * |
| 293 | + * Hard deleting an object without clearing userdata corresponding to it leaves the userdata to become associated with |
| 294 | + * the next DM object to receive the old object's reference ID, which may be undesirable behavior. |
| 295 | + * |
| 296 | + * @param object the object to disassociate from userdata. |
| 297 | + * |
| 298 | + * @return null on success |
| 299 | + */ |
| 300 | +#define DREAMLUAU_CLEAR_REF_USERDATA(object) DREAMLUAU_CALL(clear_ref_userdata)((object)) |
| 301 | + |
0 commit comments