[Plugin] PawnPlus
#1


What is this about?
PawnPlus is a multi-purpose plugin enhancing the capabilities of Pawn with features like asynchronous programming, dynamic containers and strings, threads, public and native functions hooks, and various other things.

Dynamic strings
Standard strings in Pawn are bound to an array allocated within the AMX. PawnPlus introduces dynamically allocated mutable strings which are not bound to any AMX instance, so they can be shared between scripts without copying, and offers a wide range of functions to manipulate them.

Using PawnPlus strings leads to better memory management (because you don't need to worry about the buffer size) and could increase the efficiency of some functions (because the length of the string is always known). PawnPlus strings can also store the null character without issues.

Moreover, any native function can be adapted to accept a dynamic string instead of a normal one. This transformation is very simple:

pawn Code:
native SendClientMessageStr(playerid, color, AmxString:message) = SendClientMessage;

SendClientMessageStr(playerid, -1, str_new_static("Hello, id ") + str_val(playerid));
PawnPlus strings are garbage-collected, so you don't need to worry about their lifetime much.

Asynchronous programming
The usual way of handling events in Pawn is via a callback, even if the event is directly caused by the script. You may use inline functions from YSI, but the code is still scattered over multiple functions, despite the simple flow of actions.

In PawnPlus, you can represent an action that takes time using a task. In your code, you can call task_await which pauses the execution of the current functions (returning to the caller and not blocking the main thread) and resumes the code in the moment the task is completed.

A task can represent a MySQL query, the selection of an item from a dialog, a time interval or any time-based action you wish. You can create tasks, await them in one part of code and set the result in another, and the code resumes with the original variables preserved.

pawn Code:
SendClientMessage(playerid, -1, "Loading...");
task_await(LoadPlayerAsync(playerid));
SendClientMessage(playerid, -1, "Loaded!");
task_await can be used on any task object, and if the task completes successfully, it returns the result. Tasks can also store AMX errors which you can use to signal exceptional results.

Dynamic containers
PawnPlus offers new efficient container types for use from Pawn: list (vector), linked list, and map. These containers can store values or arrays of any tag, which is stored together with the element as well. This allows for type-safe operations on these collections. You can even use strings as keys in a map.

Variant is another data type introduced in this plugin, which is used as the element type of dynamic collections. In containers, the variant has no identity (only value), but you can extract it from a collection without having to know its tag, and store it in another. Variants are also garbage collected.

All collections can be iterated using iterator objects. Iterators are objects pointing to a specific place in a collection, which can be used to access a single element in it, or to traverse the collection in a simple way. These iterators are safe to use even if the underlying collection is modified or deleted.

All collections are also available to be used as generic containers, restricting the type of values that are stored within. This feature is completely compile-time.

Tags
PawnPlus also extends the Pawn tag system with universally accessible tags, tag operations and tag inheritance. You can create a new dynamic tag, configure its operations, and set it as a tag of a variant, which allows you to call custom code when operations on the variant are performed. You can even override value copy and destruction, allowing you to introduce smart resource management.

Guards
Guards are special objects used to guard other values and destroy them when required. A guarded value will be destroyed when the context in which the guard was created terminates, freeing all resources that were associated with the value. You can set your own destructor via the tag system, and you'll never have to worry about freeing intermediate values ever again.

Threading
PawnPlus allows you to execute any piece of code in a new thread, parallel to the main one. Usually, the new thread will not allow other code to run in the same script (since AMX is not made for parallel execution), but together with forking, it is possible to clone the current script (preserving a specific selection of data) and execute a completely parallel code within it.

This can be combined with tasks to offload a time-consuming action to another thread, and provide a thread-safe method of retrieving the result.

Hooking
PawnPlus offers hooks of callbacks and native functions.

Any callback can be dynamically hooked with a new handler which is called when the original callback is called, and you can even modify the arguments or the return value. Combined with the task system, you can adapt any event-based code to task-based code with this approach.

Any native function can be hooked from your script, even affecting other scripts and plugins. Your code will be called every time when the original function is called, and you are free to modify the arguments or the return value in the same handler. You can even decide to hook a function only to modify some of its arguments and ignore the others, (via input filters), or to modify the return value only (via output filters).

Syntax shortcuts
Several functions can be used from new special pieces of syntax. For example, @ can be used as an alias for str_new_static, @@ can be used for str_val, await instead of task_await or yield instead of task_yield. New for loops are also provided for all collections, and there is special syntax for forked or threaded blocks.

All new syntax features are disabled by default due to possible conflicts with other includes. You can enable them individually, or all of them by defining PP_SYNTAX.

Other stuff
You can obtain the list of all arguments given to the function, dynamically invoke natives or public functions, share variables in your script with other scripts, raise errors, catch errors, allocate memory on the heap, and fork the script (to protect its state from errors, for example, or to wait for a task locally without pausing the other code).


All these features are described in great detail on the GitHub wiki.
Reply
#2

PawnPlus v0.9 released!

Hooking
  • Proper native hooks (pawn_add_hook). The original function can be directly called by calling the native again inside the hook, modifying freely the arguments or return value.
  • Filters reimplemented using the new system.
  • Maximum amount of hooks increased to 1024 (was 256).
Callbacks
  • Changed how dynamic callbacks work, resulting in higher compatibility with other plugins. Hooking amx_FindPublic is no longer necessary.
  • New options for callbacks, specifying the presence of return value or allowing modification of input arguments.
  • The base public function must be provided now in order to register dynamic callbacks (for providing the index and default return value).
Collections
  • Added linked lists. Created by linked_list_new, a linked list is similar to the standard list, but its elements are kept as separate objects in the memory, linked together via references to neighboring links. Iterators to linked lists remain valid even when the list is modified.
Other
  • Task which is currently being completed will not be fully deleted.
  • Caching of callback and hook handler names, resulting in speed increase.
  • pawn_get_args for obtaining all arguments provided to the function.
  • Fixed signed characters conversion in strings.
  • Partial implementation of GCA. Optional arguments are checked at runtime and several cached values are accompanied by validity checks.
  • Generic syntax is now optional (define PP_SYNTAX_GENERIC).
  • amx_public_var fixed.
Reply
#3

PawnPlus v0.10 released!
  • Tags ConstString and ConstVariant have been introduced to better distinguish functions which shall not modify the input object. Their use in code is optional. (Note about tag inheritance: String inherits from ConstString.)
  • Added task_bind to create a task from a public function.
  • All native functions now check for the correct argument count.
  • PP_ALL_TAGS may be defined for compilers which support tag wildcard.
  • Tag instances store their operations with them, so indexing a map is no longer needed when calling operations dynamically. The unknown tag (now with the internal representation of {...}) is the base of all other tags.
  • var_inc and var_dec are finally implemented, together with the operator overloads. Dynamically defining or calling these operations now also works.
  • Dynamically defined tag operations (tag_set_op) cache the public function index, making them a lot faster.
  • Fixed calling pawn_call_public and pawn_call_native with no arguments.
  • Fixed argument offset in pawn_register_callback and pawn_add_filter.
Reply
#4

PawnPlus v0.10.1 released!
  • pp_max_recursion to prevent crashes related to native recursion.
  • task_bind returns the immediate result if it is available.
  • A task scheduled to be completed after 0-length time interval will be still executed in the current tick, but postponed after all other code.
  • task_config to control which sections of the memory should be stored.
  • Finishing a task after a time interval: task_set_result_ms, task_set_result_ticks, task_set_error_ms, task_set_error_ticks.
Reply
#5

This is great, why is no one even responding?

Good job
Reply
#6

I am a PawnPlus user since this spring and I can confirm that this plugin is great.
Reply
#7

Quote:
Originally Posted by kvann
View Post
I am a PawnPlus user since this spring and I can confirm that this plugin is great.
same here. I started using it like 4 months ago and loved it when `hooking natives` feature was added.
This plugin has many good features. wait/sleep functions are some things that SA:MP needed it before this.


EDIT: You must spread some Reputation around before giving it to IllidanS4 again.
Reply
#8

Smexy seeing you unbanned! Ive been in love with this plugin ever since its initial release.
Reply
#9

Very good plugin. It saved me from a life of misery and I am now in a recovery program.
Reply
#10

Quote:
Originally Posted by TommyB
View Post
Very good plugin. It saved me from a life of misery and I am now in a recovery program.
recovery from pawnplus crashes OOooooh roasted xDDDDD
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)