### Direct Intent Example in Pawn Source: https://github.com/is4code/pawnplus/wiki/Error-handling This snippet illustrates a more concise way to achieve the same intent as the `list_get` example with an asserted success value. It contrasts with the verbosity of explicit success value checking, reinforcing the preference for implicit error handling. ```pawn printf("%d", list_get(l, 0)); ``` -------------------------------- ### Effective Success Value Usage Example in Pawn Source: https://github.com/is4code/pawnplus/wiki/Error-handling This example shows how a success value from `list_get` might be used effectively. However, it highlights that this approach leads to more verbose code compared to direct usage, supporting the argument for the chosen error handling strategy. ```pawn new value; assert list_get(l, 0); printf("%d", value); ``` -------------------------------- ### PawnPlus String Collection Example Source: https://github.com/is4code/pawnplus/wiki/Garbage-collection-and-resource-management Demonstrates how strings created in PawnPlus are automatically collected when they go out of scope from the local pool. Asserts check for string validity before and after collection. ```pawn new String:text; main() { text = str_new_static("String"); // a new string is created in the local pool assert(str_is_valid(text)); // the object still exists } // `text` is collected after this function returns public Callback() { assert(!str_is_valid(text)); // it does no longer exist } ``` -------------------------------- ### PawnPlus Error System State Management Source: https://github.com/is4code/pawnplus/wiki/Error-handling This example shows how to manage the PawnPlus error system's state using `state pp_errors:off` and `state pp_errors:on`. It also provides examples of `pp_on_error` implementations for different states, including disabling errors for specific calls. The `` and `` annotations are used to associate the callback with specific states. ```pawn public pp_on_error(const source[], const message[], error_level:level, &retval) { retval = 0; return true; } public pp_on_error(const source[], const message[], error_level:level, &retval) { return false; } public pp_on_error(const source[], const message[], error_level:level, &retval) <> { return false; } state pp_errors:off; printf("%d", list_delete(List:0)); state pp_errors:on; ``` -------------------------------- ### Pawn Pool Iteration Example Source: https://github.com/is4code/pawnplus/wiki/Pools Illustrates how to iterate through the elements of a PawnPlus pool. This method efficiently skips unused slots, making it more performant than iterating through lists with null placeholders. ```pawn new Pool:p = pool_new(); pool_set(p, 10, 1); pool_set(p, 20, 2); pool_set(p, 30, 3); for_pool(it : p) { print_s(str_val(it)); } ``` -------------------------------- ### Pawn Generic Pool Initialization Source: https://github.com/is4code/pawnplus/wiki/Pools Example of how to initialize and use a generic PawnPlus pool, specifically for floating-point numbers. Generic pools allow the pool to store elements of a specific type. ```pawn new Pool:p = pool_new(); pool_add(p, 1.5); ``` -------------------------------- ### Create and Get Variant Value (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Variants Demonstrates creating a variant with a Float value and asserting its tag. Also shows creating an array variant and accessing its elements. ```pawn new Variant:v = var_new(3.14); assert var_tagof(v) == (tagof(Float:)); new Variant:v_arr = var_new_arr(Float:{1.1, 2.2, 3.3}); assert var_tagof(v_arr) == (tagof(Float:)); assert var_sizeof(v_arr) == 3; assert Float:var_get(v_arr, 0) == 1.1; assert Float:var_get(v_arr, 1) == 2.2; assert Float:var_get(v_arr, 2) == 3.3; ``` -------------------------------- ### Pawn String Formatting Example (Brace Syntax) Source: https://github.com/is4code/pawnplus/wiki/String-formatting Demonstrates the use of brace syntax for string formatting in Pawn, showing how to include integers, floats, and hexadecimal values with specified formats. Escaped braces are also illustrated. ```pawn str_format("{FFFFFF} %{{0:d}%} %{{1:f}%} %{{2:x}%}", 152, 8.63, 0xABCD); ``` -------------------------------- ### Get Symbol Code Scope (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Returns the code range (start and end addresses) within which a symbol is in scope. This helps determine where a symbol is valid and accessible. ```pawn native debug_symbol_range(Symbol:symbol, &codestart, &codeend); ``` -------------------------------- ### PawnPlus Expressions: Runtime Expression Trees Source: https://context7.com/is4code/pawnplus/llms.txt Explains how to build and evaluate expression trees at runtime using PawnPlus. Demonstrates manual construction with `expr_const`, `expr_add`, etc., parsing from strings with `expr_parse`, binding arguments, and obtaining results. ```pawn #include main() { // Build expression tree manually new Expression:arg1 = expr_const(10); new Expression:arg2 = expr_const(5); new Expression:add = expr_add(arg1, arg2); new Expression:result = expr_mul(add, expr_const(2)); new Variant:value = expr_get_var(result); printf("Result: %d", var_get(value)); // (10 + 5) * 2 = 30 // Parse expression from string new Expression:e = expr_parse("$arg0 * 2 + $arg1"); // Bind arguments new Expression:bound = expr_bind(expr_bind(e, expr_const(5)), expr_const(3)); new Variant:res = expr_get_var(bound); printf("5 * 2 + 3 = %d", var_get(res)); // 13 // Complex expression with functions new Expression:complex = expr_parse("sqrt($arg0 * $arg0 + $arg1 * $arg1)"); new Expression:pythag = expr_bind(expr_bind(complex, expr_const(3)), expr_const(4)); new Variant:dist = expr_get_var(pythag); printf("Distance: %f", Float:var_get(dist)); // 5.0 // Parse with custom parser options new Expression:strict = expr_parse("x + y", parser_allow_idents | parser_allow_ops); // Clone expressions new Expression:cloned = expr_clone(e); // Check if expression has free variables if(!expr_is_closed(e)) { print("Expression has unbound arguments"); } } ``` -------------------------------- ### Get Element Tag UID Source: https://github.com/is4code/pawnplus/wiki/Tag-natives Returns the universal identifier (UID) of the element tag for a generic tag. For example, if given the UID for `List`, this function would return the UID for `Float`. ```pawn native tag_uid:tag_element(tag_uid:tag_uid); // Example usage: new listFloatTagUid = tag_find("List"); if (listFloatTagUid != tag_uid_unknown) { new floatTagUid = tag_element(listFloatTagUid); // floatTagUid is the UID for Float tag } ``` -------------------------------- ### Get player name into a dynamic string buffer Source: https://github.com/is4code/pawnplus/wiki/Strings This example shows how to use `AmxStringBuffer` to retrieve player names into a dynamically allocated string. `GetPlayerNameStrImpl` directly writes into the buffer, and a helper function `GetPlayerNameStr` is provided to manage the string creation, resizing, and return. ```pawn native GetPlayerNameStrImpl(playerid, AmxStringBuffer:name, len) = GetPlayerName; stock String:GetPlayerNameStr(playerid) { new String:str = str_new_buf(MAX_PLAYER_NAME); str_resize(str, GetPlayerNameStrImpl(playerid, str, MAX_PLAYER_NAME)); return str; } ``` -------------------------------- ### Creating and Using PawnPlus Handles Source: https://github.com/is4code/pawnplus/wiki/Handles Demonstrates the basic creation of a list and wrapping it in a handle. When the handle is destroyed (e.g., goes out of scope), it automatically releases the list. ```pawn new List:l = list_new(); new Handle:h = handle_new(l); wait_ms(1); assert(!list_valid(l)); ``` -------------------------------- ### Get Symbol Name with Pawn Macro Source: https://github.com/is4code/pawnplus/wiki/Pawn-natives A macro that retrieves the name of a symbol (like a function or variable) and verifies its existence. It handles optional tag names followed by a colon, removing the colon from the resulting string. Example: `pawn_nameof(MyFunction)` results in `"MyFunction"`. ```pawn #define pawn_nameof(%0) ((tagof(%0)),_:_PP@REMOVE_COLON:(#%0)) ``` -------------------------------- ### Dynamic Strings: Create, Manipulate, and Split Strings in PawnPlus Source: https://context7.com/is4code/pawnplus/llms.txt Demonstrates the creation and manipulation of heap-allocated, garbage-collected strings in PawnPlus. Covers string concatenation, length calculation, substring extraction, searching, appending, splitting into lists, and joining list elements. Requires the PawnPlus include. ```pawn #include main() { // Create strings using various methods new String:str1 = str_new("Hello"); new String:str2 = @("World"); // Using @ operator (requires PP_SYNTAX_@) // Concatenate strings new String:result = str_cat(str1, str2); printf("Result: %s", _:result); // Output: HelloWorld // String operations new length = str_len(result); new String:substr = str_sub(result, 0, 5); // Extract "Hello" new pos = str_find(result, @("World")); // Find position // Append to existing string str_append(result, @(" from PawnPlus!")); // Split strings new List:parts = str_split(@("apple,banana,orange"), ","); for_list(it : parts) { new String:fruit = String:iter_get(it); printf("Fruit: %s", _:fruit); } // Join strings new String:joined = str_join(parts, " | "); // Output: "apple | banana | orange" list_delete_deep(parts); } ``` -------------------------------- ### Delete String Characters Source: https://github.com/is4code/pawnplus/wiki/String-natives The `str_del` function removes a portion of the string specified by a start and end index, behaving as `[start, end)`. If `end` is less than `start`, it deletes the characters outside the specified range. This function modifies the string in place and returns the modified string. ```pawn native String:str_del(StringTag:target, start=0, end=cellmax); ``` -------------------------------- ### Pawn Example of Tag-Safe Variant Retrieval Source: https://github.com/is4code/pawnplus/wiki/General-tips-and-recommendations A practical example demonstrating the usage of a Pawn safe variant function to retrieve a float value from a variant, asserting that the tags match before proceeding. ```pawn new Variant:v = var_new(3.14); new Float:value; assert var_get_safe(v, value); ``` -------------------------------- ### Find Substring in String (Pawn) Source: https://github.com/is4code/pawnplus/wiki/String-natives Searches for the first occurrence of a substring within a larger string, starting from an optional offset. Returns the starting position of the substring if found, or -1 otherwise. ```pawn native str_find(ConstStringTag:str, ConstStringTag:value, offset=0); ``` -------------------------------- ### Handling Public Function Returns with Await in Pawn Source: https://github.com/is4code/pawnplus/wiki/Tasks Illustrates how to correctly use 'await' within public functions that have mandatory return values. The example shows the potential issue of desynchronization and introduces the 'yield' pseudo-statement as a solution to store the intended return value before awaiting task completion. ```pawn public OnPlayerUpdate() { await task_ms(1000); // task_ms completes after specified milliseconds //... return true; } ``` ```pawn public OnPlayerUpdate(playerid) { yield true; await task_ms(1000); //... return false; } ``` -------------------------------- ### Manage Dynamic Lists with Heterogeneous Values in PawnPlus Source: https://context7.com/is4code/pawnplus/llms.txt Provides examples for creating, populating, accessing, and manipulating dynamic lists in PawnPlus. These lists support storing heterogeneous values using variants and offer methods for insertion, removal, finding, sorting, and safe type checking. Requires PawnPlus include. Includes memory management functions like `list_delete` and `list_delete_deep`. ```pawn #include main() { // Create and populate list new List:numbers = list_new(); list_add(numbers, 10); list_add(numbers, 20); list_add(numbers, 30); list_add(numbers, 40); // Access elements for(new i = 0; i < list_size(numbers); i++) { printf("numbers[%d] = %d", i, list_get(numbers, i)); } // Insert at specific position list_add(numbers, 15, 1); // Insert at index 1 // Remove element list_remove(numbers, 2); // Find element new idx = list_find(numbers, 30); if(idx != -1) printf("Found 30 at index %d", idx) // Sort list list_sort(numbers); // Ascending order list_sort(numbers, .reverse=true); // Descending // Mixed-type list using variants new List:mixed = list_new(); list_add(mixed, 42); list_add_str(mixed, "Hello"); list_add(mixed, 3.14); // Safe type checking new value; if(list_get_safe(mixed, 0, value)) { printf("First element: %d", value); } // Cleanup list_delete(numbers); list_delete_deep(mixed); // Recursively delete contained objects } ``` -------------------------------- ### Creating and Using Generic PawnPlus Lists Source: https://github.com/is4code/pawnplus/wiki/Lists Demonstrates the creation and usage of generic lists in PawnPlus, specifying the type (e.g., `Float`) during list creation and element addition/retrieval. It also shows type mismatch errors and how values are tagged. ```pawn new List:l = list_new(); list_add(l, 1.0); list_add(l, 1.1); list_add(l, true); //tag mismatch assert list_tagof(List:l, 2) == (tagof(Float:)); new Float:f = list_get(l, 2); ``` -------------------------------- ### Function and Variable Symbols Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Functions to get symbol handles for functions and variables. ```APIDOC ## `debug_func` ### Description Returns the symbol representing the function located at `code`. ### Method Native ### Endpoint N/A ### Parameters - `code` (integer, optional) - The code address. Defaults to `cellmin` (current function). ### Request Example ```pawn new func_symbol = debug_func(); // Get symbol for current function new code_addr = debug_code(1); new caller_func_symbol = debug_func(code_addr); // Get symbol for caller function ``` ### Response #### Success Response (Symbol) - A handle to the function symbol. - `INVALID_SYMBOL_ID`: If no function symbol is found at the given code address. #### Response Example ```pawn // Returns a Symbol handle or INVALID_SYMBOL_ID ``` ## `debug_var` ### Description Returns the symbol representing the variable pointed to by `var`. Only variables in the data section, or on the stack of the AMX can be used. ### Method Native ### Endpoint N/A ### Parameters - `var` (&AnyTag:variable) - A reference to the variable. ### Request Example ```pawn new my_variable; new var_symbol = debug_var(my_variable); ``` ### Response #### Success Response (Symbol) - A handle to the variable symbol. - `INVALID_SYMBOL_ID`: If the variable cannot be symbolized. #### Response Example ```pawn // Returns a Symbol handle or INVALID_SYMBOL_ID ``` ## `debug_var_arr` ### Description Returns the symbol representing the array variable pointed to by `var`. Only variables in the data section, or on the stack of the AMX can be used. This is an alias for `debug_var`. ### Method Native ### Endpoint N/A ### Parameters - `var` (AnyTag:variable[]) - A reference to the array variable. ### Request Example ```pawn new my_array[10]; new array_symbol = debug_var_arr(my_array); ``` ### Response #### Success Response (Symbol) - A handle to the array symbol. - `INVALID_SYMBOL_ID`: If the array variable cannot be symbolized. #### Response Example ```pawn // Returns a Symbol handle or INVALID_SYMBOL_ID ``` ``` -------------------------------- ### PawnPlus Complex Tag Variant Ownership Example Source: https://github.com/is4code/pawnplus/wiki/Tag-system Illustrates how the 'collect' operation manages variant ownership by binding the lifetime of an internal list to the variant. When a variant holding a list with the 'Complex' tag is deleted, its associated list is also automatically deleted, preventing memory leaks. This example verifies that the list is no longer valid after the variant is deleted. ```pawn new List:l = list_new_args(1.0, 1.0); new Variant:v = var_new(l, tag); // v assumes ownership of l var_delete(v); assert !list_valid(l); ``` -------------------------------- ### PawnPlus Expression Creation and Evaluation Source: https://github.com/is4code/pawnplus/wiki/Expressions Demonstrates how to create basic expressions in PawnPlus, such as constants and arithmetic operations. It shows the process of building an expression tree and then evaluating it to retrieve the final result. This is fundamental for understanding dynamic computation within PawnPlus. ```pawn new Expression:arg1 = expr_const(10); // creates a new expression with a constant value of 10 new Expression:arg2 = expr_const(5); // creates a new expression with a constant value of 5 new Expression:add = expr_add(arg1, arg2); // creates a new expression that sums the two expressions print_s(str_val(expr_get_var(add))); // computes the result of the expression and prints it ``` -------------------------------- ### Pawn: Callback Handlers with Parameters Source: https://github.com/is4code/pawnplus/wiki/Tasks Shows how to pass additional parameters to callback handlers, enabling the creation of delegates. This allows for more context to be passed when an event is triggered. ```pawn public OnFilterScriptInit() { pawn_register_callback(#OnPlayerConnect, #MyPlayerConnect, _, "d", 12); } forward MyPlayerConnect(param, playerid); public MyPlayerConnect(param, playerid) { //... } ``` -------------------------------- ### LinkedList Iterator Operation Source: https://github.com/is4code/pawnplus/wiki/Linked-list-natives Create an iterator for traversing a linked list starting from a specified index. ```APIDOC ## LinkedList Iterator Operation ### Description Create an iterator for traversing a linked list starting from a specified index. ### Native Function #### `linked_list_iter` - **Purpose**: Creates a new iterator pointing to an element in the linked list. - **Parameters**: - `LinkedList:linked_list` - The linked list. - `index` (integer, optional, defaults to 0) - The starting index for the iterator. ``` -------------------------------- ### Manual string conversion for variadic functions like `printf` Source: https://github.com/is4code/pawnplus/wiki/Strings This code shows how to handle variadic functions (those with `...`) like `printf`, which do not automatically convert strings. It requires manual conversion using `AmxString` and `str_addr` for string parameters. `pp_hook_check_ref_args(true)` is necessary for `str_addr` results to be recognized. ```pawn native CallLocalFunctionStr(const function[], const format[], {AmxString,Float,_}:...) = CallLocalFunction; public OnFilterScriptInit() { new String:str1 = @("Hello "); new String:str2 = @("world!"); pp_hook_check_ref_args(true); // required for the result of str_addr to be picked CallLocalFunctionStr(#StringReceiver, "s", str_addr(str1+str2)); } forward StringReceiver(str[]); public StringReceiver(str[]) { print(str); } ``` -------------------------------- ### Get String Length (Pawn) Source: https://github.com/is4code/pawnplus/wiki/String-natives Retrieves the length of a string in terms of cells. This is a fundamental operation for string processing. ```pawn native str_len(ConstStringTag:str); ``` -------------------------------- ### Compose PawnPlus Tasks and Handle Errors Source: https://context7.com/is4code/pawnplus/llms.txt Illustrates how to combine multiple tasks for scenarios like race conditions or ensuring all operations complete. It also shows how to check task states and handle errors gracefully using `task_get_state` and `task_get_result`. Requires PawnPlus include. ```pawn #include public TaskCompositionExample() { // Wait for first task to complete (race condition) new Task:t1 = DelayedTask(1000, 42); new Task:t2 = DelayedTask(2000, 100); new Task:first = task_any(t1, t2); new result = await first; printf("First completed with: %d", result); // 42 // Wait for all tasks to complete new Task:t3 = DelayedTask(500, 10); new Task:t4 = DelayedTask(800, 20); new Task:all = task_all(t3, t4); await all; printf("All tasks completed"); // Check task state and handle errors new Task:t5 = RiskyTask(); await t5; if(task_get_state(t5) == task_state_faulted) { new Variant:error = task_get_result(t5); printf("Task failed with error: %d", _:error); } else { new result = task_get_result(t5); printf("Task succeeded: %d", result); } } stock Task:DelayedTask(delay_ms, value) { new Task:t = task_new(); task_detach(); wait_ms(delay_ms); task_set_result(t, value); return t; } stock Task:RiskyTask() { new Task:t = task_new(); task_detach(); if(random(2) == 0) { task_set_error(t, var_new(-1)); // Set error state } else { task_set_result(t, 123); } return t; } ``` -------------------------------- ### Execute Non-Blocking Operations with PawnPlus Tasks Source: https://context7.com/is4code/pawnplus/llms.txt Demonstrates how to use PawnPlus tasks for non-blocking operations like delays and converting callback-based APIs to task-based ones. It illustrates the use of `await` for pausing execution until asynchronous operations complete, avoiding callback hell. Dependencies include the PawnPlus include. ```pawn #include // Non-blocking delay using tasks public OnPlayerCommandText(playerid, cmdtext[]) { if(!strcmp(cmdtext, "/countdown", true)) { Countdown(playerid); return 1; } return 0; } stock Countdown(playerid) { SendClientMessage(playerid, -1, "3"); wait_ms(1000); // Non-blocking wait SendClientMessage(playerid, -1, "2"); wait_ms(1000); SendClientMessage(playerid, -1, "1"); wait_ms(1000); SendClientMessage(playerid, -1, "GO!"); } // Convert callback-based API to task-based stock Task:MoveObjectTask(objectid, Float:X, Float:Y, Float:Z, Float:Speed) { new Task:t = task_new(); pawn_register_callback(#OnObjectMoved, #HandleObjectMoved, _, "edd", t, objectid); MoveObject(objectid, X, Y, Z, Speed); return t; } forward HandleObjectMoved(CallbackHandler:id, Task:task, obj, objectid); public HandleObjectMoved(CallbackHandler:id, Task:task, obj, objectid) { if(obj == objectid) { pawn_unregister_callback(id); task_set_result(task, objectid); } } // Usage with await public ObjectTest() { new obj = CreateObject(19300, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); print("Object created!"); await MoveObjectTask(obj, 0.0, 0.0, 10.0, 5.0); print("First move complete!"); await MoveObjectTask(obj, 10.0, 0.0, 10.0, 5.0); print("Second move complete!"); } ``` -------------------------------- ### Get Public Function Address by Index (Pawn) Source: https://github.com/is4code/pawnplus/wiki/AMX-natives Retrieves the code address of a public function given its index. ```pawn native amx_public_addr(index); ``` -------------------------------- ### Using Universal Tags with Variants in Pawn Source: https://github.com/is4code/pawnplus/wiki/Tag-system Illustrates creating a PawnPlus Variant with a universal tag identifier. It shows how `var_new` can accept a tag UID, specifically for `Float:`, and verifies the string representation of the variant. ```pawn new Variant:v = var_new(0x3F800000, .tag_id=tag_uid_float); //equivalent to tagof(Float:) assert str_val(v) == @("(1.000000)"); ``` -------------------------------- ### Get Symbol Definition Line Number (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Returns the line number in the source file where a particular symbol was defined. ```pawn native debug_symbol_line(Symbol:symbol); ``` -------------------------------- ### Map Creation, Addition, and Retrieval (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Maps Demonstrates how to create a new map, add key-value pairs with various data types (cells, strings, arrays), and retrieve values using their keys. It highlights the importance of matching key and value types and the use of type-specific add/get functions. ```pawn new Map:m = map_new(); map_add(m, false, 12); map_add(m, 0, 13); map_str_add(m, "key1", 14); map_str_add_arr(m, "key2", {1, 2, 3}); assert map_get(m, false) == 12; assert map_get(m, 0) == 13; assert map_str_get(m, "key1") == 14; new buffer[16]; assert map_str_get_arr(m, "key2", buffer) == 3; ``` -------------------------------- ### Get Symbol Visibility Class (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Returns the visibility class of a symbol, indicating whether it is global, local, or static. ```pawn native symbol_class:debug_symbol_class(Symbol:symbol); ``` -------------------------------- ### PawnPlus Regex Caching Examples Source: https://github.com/is4code/pawnplus/wiki/Regular-expressions Demonstrates proper and improper usage of regex caching in PawnPlus, illustrating when to use `regex_cached` and `regex_cached_addr` based on pattern origin and mutability. Improper caching can lead to performance degradation or incorrect behavior. ```pawn // Pattern comes from a literal string str_match(s, "pattern", .options = regex_cached); // imperfect - statically-known string; no need to cache by value str_match(s, "pattern", .options = regex_cached_addr); // optimal - address is constant (in the AMX instance) str_match(s, str_new("pattern"), .options = regex_cached_addr); // bad - temporary string; address is different each time so no cache hits str_match(s, str_new_static("pattern"), .options = regex_cached_addr); // still bad - good use of str_new_static, but it is still a temporary string str_match(s, str_new_static("pattern"), .options = regex_cached); // okay in principle - value is always the same (but why construct the string at all?) str_match(s, str_format("pattern %d", random(100000)), .options = regex_cached); // bad - cache is almost never hit // Pattern comes from the stack new p[] = "pattern"; str_match(s, p, .options = regex_cached_addr); // very bad - string is on the stack, so the address may be different each time and could conflict with another one str_match(s, p, .options = regex_cached); // okay in principle - value is always the same (but do not copy a string literal to a variable when you don't need to modify it!) format(p, sizeof(p), "pattern %d", random(100000)); str_match(s, p, .options = regex_cached); // bad - different pattern each time again str_match(s, p); // okay - just don't use caching when the pattern is different ``` -------------------------------- ### Get Character at Position (Pawn) Source: https://github.com/is4code/pawnplus/wiki/String-natives Retrieves a single cell/character from a string at a specified position. Returns `INVALID_CHAR` if the position is out of bounds. ```pawn native str_getc(ConstStringTag:str, pos); ``` -------------------------------- ### Get Number of Imported Natives (Pawn) Source: https://github.com/is4code/pawnplus/wiki/AMX-natives Returns the total count of native functions that have been imported (used) by the current script. ```pawn native amx_num_natives(); ``` -------------------------------- ### Pawn: AMX Execution Forking and Variable References Source: https://context7.com/is4code/pawnplus/llms.txt Demonstrates forking AMX execution into parallel paths and managing variable references for indirect access. It also shows how to create and execute multiple AMX instances in parallel and manipulate public variables. ```pawn #include // Fork execution into parallel paths main() { new result; new bool:forked = amx_fork(.result=result); if(forked) { // Forked context - runs in copy of AMX printf("Forked context"); amx_yield(42); // Return value to parent } else { // Original context printf("Original context, result: %d", result); // 42 } } // Variable references for indirect access stock ModifyVariable(&var) { new Var:ref = amx_var(var); wait_ms(1000); if(amx_valid(ref)) { amx_set(ref, 100); // Modify original variable } amx_delete(ref); } // Parallel AMX instances public ParallelAMXExample() { new AMX:amx1 = amx_new(@("script1.amx")); new AMX:amx2 = amx_new(@("script2.amx")); // Execute in parallel threaded(sync_explicit) { amx_exec(amx1, #main); } threaded(sync_explicit) { amx_exec(amx2, #main); } wait_ms(5000); amx_delete(amx1); amx_delete(amx2); } // Public variable manipulation stock GetPublicVariable(const name[]) { new Var:ref = amx_public_var(name); if(amx_valid(ref)) { new value = amx_get(ref); amx_delete(ref); return value; } return 0; } stock SetPublicVariable(const name[], value) { new Var:ref = amx_public_var(name); if(amx_valid(ref)) { amx_set(ref, value); amx_delete(ref); return true; } return false; } ``` -------------------------------- ### Get Public Function Name by Index Source: https://github.com/is4code/pawnplus/wiki/AMX-natives Retrieves the name of a public function given its index. This function is the inverse of `amx_public_index`. ```pawn native amx_public_name(index, name[], size=sizeof(name)); ``` ```pawn native String:amx_public_name_s(index); ``` -------------------------------- ### Thread Synchronization Example (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Threading Illustrates how synchronization works within threaded blocks in PawnPlus. The 'sync_auto' mode synchronizes all native calls with the server's process tick, preventing race conditions. 'sync_explicit' is used when native functions have no side effects or when external functions handle their own synchronization. ```pawn forward Work(); public Work() { printf("A"); threaded(sync_explicit) { printf("B"); thread_sleep(500); printf("C"); thread_sleep(500); printf("D"); thread_sleep(500); printf("E"); } printf("F"); } forward Timer(); public Timer() { printf("X"); } public OnFilterScriptInit() { CallLocalFunction(#Work, ""); SetTimer(#Timer, 1000, false); } ``` -------------------------------- ### Get Script Name Source: https://github.com/is4code/pawnplus/wiki/AMX-natives Retrieves the name of the currently executing script. This function is available for use within the script context. ```pawn native amx_name(name[], size=sizeof(name)); ``` ```pawn native String:amx_name_s(); ``` -------------------------------- ### Create New LinkedList (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Linked-list-natives Initializes a new linked list. Supports creation from an array of values (which must be properly tagged), or directly from a list of arguments. The `linked_list_new_arr` function allows for specifying an array and its size, while `linked_list_new_args_str` and `linked_list_new_args_var` handle variadic arguments of strings or variants, respectively. A macro `linked_list_new_args` is provided for convenience with packed tagged arguments. ```pawn native LinkedList:linked_list_new(); native LinkedList:linked_list_new_arr(AnyTag:values[], size=sizeof(values), TagTag:tag_id=tagof(values)); #define linked_list_new_args(%0) linked_list_new_args_packed(_PP@TAGGED_PACK(%0)) native LinkedList:linked_list_new_args_str(arg0[], ...); native LinkedList:linked_list_new_args_var(ConstVariantTag:arg0, ConstVariantTag:...); ``` -------------------------------- ### Get Symbol Kind (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Determines the kind of a given symbol, such as variable, variable reference, array, array reference, or function. ```pawn native symbol_kind:debug_symbol_kind(Symbol:symbol); ``` -------------------------------- ### Task Creation and Awaiting in Pawn Source: https://github.com/is4code/pawnplus/wiki/Tasks Demonstrates the creation of a new task and the use of the 'await' pseudo-statement to pause script execution until the task completes. This is useful for managing asynchronous operations without freezing the server. The task is finalized using 'task_set_result'. ```pawn new Task:end_task; public OnFilterScriptInit() { end_task = task_new(); await end_task; print("Goodbye"); } public OnFilterScriptExit() { task_set_result(end_task, 0); } ``` -------------------------------- ### Get Encoded String Length (Pawn) Source: https://github.com/is4code/pawnplus/wiki/AMX-natives Returns the fixed length of strings generated by amx_encode_public and amx_encode_native, which is currently 6 characters. ```pawn native amx_encoded_length(); ``` -------------------------------- ### Get the Currently Bound Task with task_bound Source: https://github.com/is4code/pawnplus/wiki/Task-natives Returns the `Task` handle that is currently bound to the execution context. If no task is bound, it returns `INVALID_TASK`. ```pawn native Task:task_bound(); ``` -------------------------------- ### Pawn: Registering Additional Callback Handlers Source: https://github.com/is4code/pawnplus/wiki/Tasks Illustrates how to register additional callback handlers for existing Pawn events using `pawn_register_callback`. This is a fundamental step towards creating more sophisticated event handling. ```pawn public OnFilterScriptInit() { pawn_register_callback(#OnPlayerConnect, #MyPlayerConnect); } forward MyPlayerConnect(playerid); public MyPlayerConnect(playerid) { //... } ``` -------------------------------- ### Get Pool Element Size (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Pool-natives The `pool_sizeof` function returns the size of an element located at a given index within a pool. ```pawn native pool_sizeof(Pool:pool, index); ``` -------------------------------- ### Entry Point Information Source: https://github.com/is4code/pawnplus/wiki/Configuration-natives Retrieves the name of the current entry point into the code. Handles special cases like the main function or resumed states. ```APIDOC ## `pp_entry` ### Description Returns the name of the current entry point, as a dynamic string. An entry point is the public function that was used to enter the code that called this native function. Special values are "#main" if the entry point is the main function of the script, or "#cont" if the script was resumed from a paused state but the context was lost. If the context is not present (e.g. in a threaded block), an empty string is returned. ### Method native ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```pawn // No specific request example for this native function ``` ### Response #### Success Response (200) - **name** (String) - The name of the current entry point. #### Response Example ```json { "name": "#main" } ``` ## `pp_entry_s` ### Description Returns the name of the current entry point as a dynamic string. ### Method native ### Endpoint N/A ### Parameters None ### Request Example ```pawn // No specific request example for this native function ``` ### Response #### Success Response (200) - **String:** - A dynamic string representing the entry point name. #### Response Example ```json { "String:": "#cont" } ``` ``` -------------------------------- ### Get Pool Element Tag (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Pool-natives The `pool_tagof` function retrieves the tag associated with an element at a specific index within a pool. ```pawn native pool_tagof(Pool:pool, index); ``` -------------------------------- ### Get Array Symbol Size (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Returns the size of an array symbol in a specified dimension. This is useful for understanding the bounds of array variables. ```pawn native debug_symbol_size(Symbol:symbol, dimension=0); ``` -------------------------------- ### Pawn: Multiple Concurrent Threads with amx_forked Source: https://github.com/is4code/pawnplus/wiki/AMX Illustrates how to start multiple threads executing the same code concurrently using `amx_forked` within a loop. Each thread has an independent copy of memory, and they can be managed for synchronized execution. ```pawn for(new i = 0; i < 5; i++) { amx_forked() threaded(sync_explicit) { thread_sleep(1000+i*100); printf("Thread %d ends", i); } } print("Threads are started"); ``` -------------------------------- ### PawnPlus Initializer and Finalizer Macro Usage Source: https://github.com/is4code/pawnplus/wiki/Initializers-and-finalizers Provides a simplified syntax for defining initializers and finalizers using macros, if PP_SYNTAX_ON_INIT or PP_SYNTAX_ON_EXIT are defined. This approach enhances code readability and reduces boilerplate for initialization and cleanup functions. ```pawn pawn_on_init[module1] { print("Module loaded!"); } pawn_on_exit[module1] { print("Module unloaded!"); } ``` -------------------------------- ### Get Defining Function of a Symbol (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Returns the symbol representing the function that defines the given symbol. This is particularly useful for local symbols. ```pawn native Symbol:debug_symbol_func(Symbol:symbol); ``` -------------------------------- ### Get Symbol Tag ID (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Retrieves the tag ID associated with a symbol. Tags are used for type checking and information in Pawn. ```pawn native debug_symbol_tag(Symbol:symbol); ``` -------------------------------- ### PawnPlus Threading: Parallel Execution with Synchronization Source: https://context7.com/is4code/pawnplus/llms.txt Illustrates PawnPlus's Threading capabilities for running code in parallel. It demonstrates explicit, automatic, and interruptible synchronization modes, along with parallel data processing to avoid blocking the main thread. ```pawn #include public OnPlayerCommandText(playerid, cmdtext[]) { if(!strcmp(cmdtext, "/process", true)) { SendClientMessage(playerid, -1, "Processing started..."); // Heavy computation in separate thread threaded(sync_explicit) { new sum = 0; for(new i = 0; i < 10000000; i++) { sum += i; } // Sync back to main thread for native call sync(); SendClientMessage(playerid, -1, "Processing complete!"); } // This executes immediately without waiting SendClientMessage(playerid, -1, "Main thread continues..."); return 1; } return 0; } // Auto-sync mode - automatically synchronizes native calls public AutoSyncExample(playerid) { threaded(sync_auto) { new Float:x, Float:y, Float:z; GetPlayerPos(playerid, x, y, z); // Auto-syncs with main thread // Heavy computation here new Float:distance = floatsqroot(x*x + y*y + z*z); // Auto-syncs again SendClientMessage(playerid, -1, "Distance calculated!"); } } // Interrupt mode - allows safe thread interruption public InterruptibleTask() { threaded(sync_interrupt) { for(new i = 0; i < 1000; i++) { // Expensive operation wait_ms(10); // Thread can be safely interrupted here } } } // Parallel data processing public ProcessPlayerData() { new List:results = list_new(); pawn_guard(results); foreach(new playerid : Player) { threaded(sync_auto) { new score = CalculatePlayerScore(playerid); sync(); list_add(results, score); } } wait_ms(1000); // Let threads complete // Process results for_list(it : results) { printf("Score: %d", iter_get(it)); } } ``` -------------------------------- ### Get Symbol for Array Variable (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Debug-natives Returns the debug symbol for an array variable. This is an alias for debug_var and is specifically intended for array types. ```pawn native Symbol:debug_var_arr(AnyTag:var[]) = debug_var; ``` -------------------------------- ### PawnPlus Handles: Automatic Lifetime Management Source: https://context7.com/is4code/pawnplus/llms.txt Demonstrates the use of Handles in PawnPlus for automatic reference-counted memory management. It covers binding resources to player lifetimes, weak handles for observation, and manual lifetime control, ensuring objects are correctly deallocated. ```pawn #include // Bind resource to player lifetime stock BindToPlayer(playerid, AnyTag:value, tag_id=tagof(value)) { new Handle:h = handle_new(value, .tag_id=tag_id); handle_acquire(h); // Increment reference count // Auto-release when player disconnects pawn_register_callback(#OnPlayerDisconnect, #HandleCleanup, _, "edd", _:h, playerid); } forward HandleCleanup(CallbackHandler:id, Handle:h, playerid, reason); public HandleCleanup(CallbackHandler:id, Handle:h, playerid, reason) { pawn_unregister_callback(id); handle_release(h); // Decrement reference count } // Usage example public OnPlayerConnect(playerid) { new List:inventory = list_new(); BindToPlayer(playerid, inventory, tagof(List:)); // inventory will be automatically deleted when player disconnects } // Weak handles for observation without ownership stock ObserveObject(AnyTag:obj) { new Handle:weak = handle_new(obj, .weak=true); wait_ms(5000); if(handle_alive(weak)) { print("Object still exists"); new obj_ref = handle_get(weak); // Use object } else { print("Object was deleted"); } } // Manual lifetime control main() { new String:str = str_new("test"); new Handle:h = handle_new(str); handle_acquire(h); // refcount = 1 wait_ms(100); // str stays alive handle_release(h); // refcount = 0 wait_ms(100); // str gets garbage collected assert(!str_valid(str)); } ``` -------------------------------- ### Task Configuration and Continuation Source: https://github.com/is4code/pawnplus/wiki/Task-natives Functions for configuring task state restoration and registering continuation handlers. ```APIDOC ## `task_config` ### Description Configures how the state of the AMX machine is stored when the code is paused to await a task. Possible values are `task_restore_none` (do not store the memory section), `task_restore_frame` (store only the memory associated with the stack frame), `task_restore_context` (store only the memory in the current context), or `task_restore_full` (store everything). ### Method native ### Endpoint N/A (Native Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **heap** (task_restore) - Configuration for heap state restoration. Defaults to `task_restore_full`. - **stack** (task_restore) - Configuration for stack state restoration. Defaults to `task_restore_full`. ### Request Example ```pawn native task_config(task_restore:heap=task_restore_full, task_restore:stack=task_restore_full); ``` ### Response #### Success Response (200) Indicates successful configuration. #### Response Example N/A (Native Function) ``` ```APIDOC ## `task_continue_with` ### Description Registers a public function identified by `handler` to be called when the task is completed. ### Method native ### Endpoint N/A (Native Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **task** (Task) - The task to attach the continuation to. - **handler** (const string) - The name of the public function to call upon task completion. - **additional_format** (const string) - Optional format string for additional arguments. - **...** (AnyTag) - Additional arguments for the handler function. ### Request Example ```pawn native task_continue_with(Task:task, const handler[], const format[]="", AnyTag:...); ``` ### Response #### Success Response (200) Indicates successful registration of the continuation handler. #### Response Example N/A (Native Function) ``` ```APIDOC ## `task_continue_with_bound` ### Description Registers a public function identified by `handler` to be called when the task is completed. The public function can be executed asynchronously, its completion being bound to `bound`. ### Method native ### Endpoint N/A (Native Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **task** (Task) - The task to attach the continuation to. - **bound** (Task) - The task to which the handler's completion will be bound. - **handler** (const string) - The name of the public function to call upon task completion. - **additional_format** (const string) - Optional format string for additional arguments. - **...** (AnyTag) - Additional arguments for the handler function. ### Request Example ```pawn native Task:task_continue_with_bound(Task:task, Task:bound, const handler[], const additional_format[]="", AnyTag:...); ``` ### Response #### Success Response (200) Returns a `Task` handle representing the bound continuation task. #### Response Example N/A (Native Function) ``` -------------------------------- ### Get Variant Size Information (Pawn) Source: https://github.com/is4code/pawnplus/wiki/Variant-natives Returns the size of a variant in cells. For multi-dimensional variants, offsets can be provided to specify the size of a sub-dimension. ```pawn native var_sizeof(ConstVariantTag:var); native var_sizeof_md(ConstVariantTag:var, const offsets[], offsets_size=sizeof(offsets)); ``` -------------------------------- ### Get PawnPlus Plugin Version Source: https://github.com/is4code/pawnplus/wiki/Configuration-natives Retrieves the current version of the PawnPlus plugin as a non-decreasing integer. This is useful for version checking and ensuring compatibility with other systems. ```pawn native pp_version(); ``` -------------------------------- ### Retrieving Elements from PawnPlus Lists Safely Source: https://github.com/is4code/pawnplus/wiki/Lists Shows how to safely retrieve elements from a list by index, checking for success with `assert`. It demonstrates retrieving a boolean, a float array, and a string, as well as attempting to retrieve a null value, which fails. ```pawn new bool:b, Float:f[2], s[5], c; assert list_get_safe(l, 0, b); assert list_get_arr_safe(l, 1, f); assert list_get_arr_safe(l, 2, s); assert !list_get_safe(l, 3, c); //null has no value ```