variadic.inc - Variadic functions in PAWN -
kristo - 04.01.2018
Variadic functions in PAWN
Introduction
Variadic functions are a feature in most scripting languages, where a scripter can specify an indefinite amount of arguments towards a function. However, in PAWN, this isn't possible without playing around with the assembly (later versions of PAWN have dealt with this), but this include introduces a brand new way of handling them!
The include was originally created by Emmet_ and is now maintained by me. Most of the credits for the include still go to Emmet_, I have only added support for
mysql_format and done a few other changes.
More information
Have you ever wrote a function like this before?
PHP код:
printex(str[], ...)
{
new output[128];
format(output, sizeof(output), str, ...);
return print(output);
}
And then you figured out that you can't do it this way! The reason being is because variadic parameters don't have a referable location in ordinary PAWN code, so assembly is required, but that can be very complicated and one mistake could corrupt the entire script.
However, this include allows scripters to dynamically push arguments and format them. The pushed arguments are stored within an array by address, so they can be accessed later with the corresponding functions.
Example
An equivalent of the function in the introduction is possible using this include:
PHP код:
#include <a_samp>
#include <variadic>
var printex(str[])
{
new output[128];
format(output, sizeof(output), str, @variadic[1]);
return print(output);
}
You can also use
@variadic[] with
CallLocalFunction and such to call local functions with the corresponding pushed arguments.
Alternatively, you can also use another keyword (or none) instead of
var, but make sure you place
... after the parameters.
String arguments
You can retrieve string arguments easily.
Getting:
PHP код:
MyFunction(a[], b[])
{
new addr = GetVariadicAddress(0); // Address of "a[]".
print(GetVariadicString(addr)); // Print the result.
}
Setting:
PHP код:
MyFunction(a[], b[])
{
new addr = GetVariadicAddress(1); // Address of "b[]".
SetVariadicString(addr, "Hi there.");
print(GetVariadicString(addr)); // Print the result.
}
Functions
PHP код:
// Get the address of a function argument.
native GetVariadicAddress(argument);
// Get the string from the specified argument address. You can return it or store it inside "dest".
native GetVariadicString(address, dest[] = "", size = sizeof(dest));
// Set the string from the specified argument address to the specified string.
native SetVariadicString(address, str[]);
// Checks if an argument is packed.
native IsArgumentPacked(address);
// Gets the length of a variadic string.
native GetVariadicLength(address);
// Delete an argument from the specified argument address.
native DeleteArgument(address);
// Popped the pushed arguments.
native PopArguments();
Installation
Simply install to your project:
Код:
sampctl package install kristoisberg/variadic
Include in your code and begin using the library:
PHP код:
#include <variadic>
Credits
- Emmet_ - The original creator of the include, an absolute legend.
- kvann - Current maintainer.
- Southclaws - Added sampctl support, some minor changes.
Download
https://github.com/kristoisberg/variadic
Re: variadic.inc - Variadic functions in PAWN -
ExTaZZ69 - 04.01.2018
Are there any differences between this include and y_va?
Re: variadic.inc - Variadic functions in PAWN -
kristo - 04.01.2018
Quote:
Originally Posted by ExTaZZ69
Are there any differences between this include and y_va?
|
They generally have the same purpose and mostly offer the same possibilities. Emmet_ said in his original thread that y_va should be the preferred option, but in case you want to keep your scripts YSI-free like many scripters (including me) do these days, then I can guarantee you that this include is completely stable. I've been using it since it originally came out (december 2013) and I've had no issues with it at all.
Re: variadic.inc - Variadic functions in PAWN -
ZiGGi - 04.01.2018
Quote:
Originally Posted by kvann
They generally have the same purpose and mostly offer the same possibilities. Emmet_ said in his original thread that y_va should be the preferred option, but in case you want to keep your scripts YSI-free like many scripters (including me) do these days, then I can guarantee you that this include is completely stable. I've been using it since it originally came out (december 2013) and I've had no issues with it at all.
|
y_va can be easily YSI free. For example I use y_va without YSI in my zlang lib. Look at here:
https://github.com/Open-GTO/zlang/blob/master/zlang.inc
Re: variadic.inc - Variadic functions in PAWN -
RogueDrifter - 04.01.2018
Sorry for butting in but why YSI free?
Re: variadic.inc - Variadic functions in PAWN -
rfr - 05.01.2018
Quote:
Originally Posted by RogueDrifter
Sorry for butting in but why YSI free?
|
when you compile with the YSI libary it adds on a few seconds to the compile time
i'm sure there may be a better reason i do not know
Re: variadic.inc - Variadic functions in PAWN -
ExTaZZ69 - 05.01.2018
Quote:
Originally Posted by rfr
when you compile with the YSI libary it adds on a few seconds to the compile time
i'm sure there may be a better reason i do not know
|
In the most cases people don't use the whole YSI power. It's like an overkill i guess. If i'm wrong i hope someone will correct me.
Re: variadic.inc - Variadic functions in PAWN -
Sasino97 - 12.11.2018
Hello,
I want to do something like the following:
pawn Код:
stock Event_Fire(Event: event, const fmt[], {Float, _}:...)
{
for (new i = 0; i < callbackCount[event]; i++)
{
CallLocalFunction(callbacks[event][i], fmt, /* the rest of the params */);
}
}
Is this library appropriate to solve this problem, or is it better to use y_va?
Re: variadic.inc - Variadic functions in PAWN -
kristo - 15.11.2018
Quote:
Originally Posted by Sasino97
Hello,
I want to do something like the following:
pawn Код:
stock Event_Fire(Event: event, const fmt[], {Float, _}:...) { for (new i = 0; i < callbackCount[event]; i++) { CallLocalFunction(callbacks[event][i], fmt, /* the rest of the params */); } }
|
I haven't taken a look at this include in months since my stance on YSI has changed drastically ever since ****** joined SA-MP Discord. I would definitely recommend you to use y_va, but this this include can also do it if you put
@variadic[2] in the place of the comment.