[Plugin] CSTL - Data container(s) (Currently vector)
#1

CSTL - VECTOR AND MAP FOR PAWN

Implementing std::vector and std::map for PAWN

Natives

VECTOR

VECTORS DONT HAVE TO BE INITIALIZED, SPECIFY AN INTEGER AS VECID PARAMETER.
Vectors are typeless (you can push and set any datatypes without problem). But vector will do type checking when returning values (trying to vector_get_arr on float value will fail, you can use vector_entry_type to get datatype of entry).

Vector size is automatically increased when using push_back to add more data. Its also possible to increase vector size manually with vector_resize. You can NOT use vector_set to set anything into index bigger than vector size (size - 1, indexes are same as in arrays).
Disallowed example:

pawn Code:
// When nothing has been done to vector VECTOR_ID (size is default 0), following wont work
vector_set_arr(VECTOR_ID, 1, "Im going to set this into index 1");

Allowed example

pawn Code:
// When vector size is increased, its possible to change index value with vector_set
vector_push_back(VECTOR_ID, 2); // pushes integer '2' into vector (first element, index 0)
vector_push_back(VECTOR_ID, 5); // pushes integer '5' into vector (second element, index 1)
vector_set_arr(VECTOR_ID, 1, "Im going to set this into index 1"); // this will work
native vector_push_back(vecid, element); // push back integer
native vector_push_back_float(vecid, Float:element); // push back float
native vector_push_back_arr(vecid, element[]); // push back array (string)

native vector_size(vecid); // get vector size

native vector_get(vecid, id); // get integer by index
native Float:vector_get_float(vecid, id); // get floating point number by index
native vector_get_arr(vecid, id, buffer[], buflen); // get array element to buffer by index

native vector_set(vecid, id, element); // set index
native vector_set_float(vecid, id, Float:element); // set float
native vector_set_arr(vecid, id, element[]); // set array

native vector_clear(vecid); // clear vector
native vector_resize(vecid, newsize); // resize vector to new size

native vector_entry_type(vecid, id); // get element type (int, array or float)
native vector_remove(vecid, id); // remove element by index

native vector_find(vecid, element); // find index of int element
native vector_find_float(vecid, Float:element); // find index of float element
native vector_find_arr(vecid, element[]); // find index of array

native vector_globalize(vecid); // makes vector visible to all scripts
native vector_deglobalize(vecid); // deglobalizes vector (vector removed from all scripts except calling script)
native vector_is_globalized(vecid); // is vector ID globalized


MAP

MAPS ALSO DONT HAVE TO BE INITIALIZED

native map_insert(mapid, key[], value); // insert with integer value
native map_insert_float(mapid, key[], Float:value); // insert with float value
native map_insert_arr(mapid, key[], value[]); // insert with array as value

native map_get(mapid, key[]); // get integer
native Float:map_get_float(mapid, key[]); // get float
native map_get_arr(mapid, key[], buffer[], buflen); // get array to buffer

native map_size(mapid); // element count of array
native map_remove(mapid, key[]); // remove specific key
native map_contains(mapid, key[]); // does map contain specific key
native map_entry_type(mapid, key[]); // return value type of key (int, array or float)
native map_clear(mapid); // clear the map

native map_globalize(mapid); // makes map visible to all scripts
native map_deglobalize(mapid); // deglobalizes map (map removed from all scripts except calling script)
native map_is_globalized(mapid); // is map ID globalized

Example

Vector
pawn Code:
new vecid;
vecid = 0;
vector_push_back_arr(vecid, "A");
vector_push_back(vecid, 1);
vector_push_back_arr(vecid, "B");

for (new i = 0 ; i < vector_size(vecid) ; i++)
{
    if (vector_entry_type(vecid, i) == VEC_ENTRY_TYPE_CELL)
    {
        printf("INT: %i", vector_get(vecid, i));
    } else if (vector_entry_type(vecid, i) == VEC_ENTRY_TYPE_FLOAT)
    {
        printf("FLOAT: %f", vector_get_float(vecid, i));
    } else if (vector_entry_type(vecid, i) == VEC_ENTRY_TYPE_ARRAY)
    {
        new buffer[100];
        vector_get_arr(vecid, i, buffer, 100);
        printf("ARRAY: %s", buffer);
    }
}
vector_clear(vecid);
printf("Vector size: %i", vector_size(vecid));
outputs:
Code:
ARRAY: A
CELL: 1
ARRAY: B
Vector size: 0
Map
pawn Code:
#include <a_samp>
#include <cstl>

new const FIRST_MAP = 0;

public OnFilterScriptInit()
{
    map_insert_arr(FIRST_MAP, "key", "This is value");
   
    if (map_contains(FIRST_MAP, "key") == 1)
    {
        new buffer[100];
        map_get_arr(FIRST_MAP, "key", buffer, 100);
        printf("Map key \"key\" has value: %s", buffer);
    }
    printf("Map length is now: %i", map_size(FIRST_MAP));
    map_remove(FIRST_MAP, "key");
    printf("After removal size is: %i", map_size(FIRST_MAP));
    return 1;
}
outputs:
Code:
Map key "key" has value: This is value
Map length is now: 1
After removal size is: 0
Updates
  • 14.6.2011: Added vector_index_exists
  • 15.3.2011: Added support for globalization of specific containers (you can use one container from all scripts)
  • 14.3.2011: Vectors and maps are now specific to one AMX vm (every filterscript, GM can have own, with same ids)
  • 12.3.2011: Added std::map also
License
Copyright © 2011, Teprey
All rights reserved.
By using functions provided by this plugin within your software or otherwise using this software, you agree to comply with following terms and conditions:

You may not change copyright message or credit information in any file of this product.
You may redistribute and/or modify this software only if you preserve credit.

THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



DOWNLOAD WINDOWS DLL + LINUX .SO + SOURCE
Reply
#2

What does this, actually do? I'm confused, how is this somewhat helpful ?
Reply
#3

i agree with Zh3r0
Reply
#4

Its "dynamic array" (you dont have to know maximum size for it, unlike normal arrays in PAWN)

For example you can store all online playerids in it, and the vector size changes according to player count.
Then if you need to loop through all players online, you do not have to loop from 0 to MAX_PLAYER and check if player is online, but you can just loop through vector (hard to explain)

Example filterscript:
pawn Code:
#include <a_samp>
#include <cstl>

new const USERS_ONLINE = 0; // vector of all online users

public OnPlayerConnect(playerid)
{
    // now we add connected user into vector
    vector_push_back(USERS_ONLINE, playerid);
}

public OnPlayerDisconnect(playerid, reason)
{
    new index;
    // get index of playerid in vector
    index = vector_find(USERS_ONLINE, playerid);

    if (index != -1) // if vector contains this playerid, remove it (because player disconnected)
    {
             vector_remove(USERS_ONLINE, index);
    }

}

stock KickAllPlayers() // with this we can kick all players (not recommended)
{
    for (new i = 0 ; i < vector_size(USERS_ONLINE) ; i++)
    {
        Kick(vector_get(USERS_ONLINE, i));
    }
}
Reply
#5

Quote:
Originally Posted by Teprey
View Post
Its "dynamic array" (you dont have to know maximum size for it, unlike normal arrays in PAWN)

For example you can store all online playerids in it, and the vector size changes according to player count.
Then if you need to loop through all players online, you do not have to loop from 0 to MAX_PLAYER and check if player is online, but you can just loop through vector (hard to explain)

Example filterscript:
pawn Code:
#include <a_samp>
#include <cstl>

new const USERS_ONLINE = 0; // vector of all online users

public OnPlayerConnect(playerid)
{
    // now we add connected user into vector
    vector_push_back(USERS_ONLINE, playerid);
}

public OnPlayerDisconnect(playerid, reason)
{
    new index;
    // get index of playerid in vector
    index = vector_find(USERS_ONLINE, playerid);

    if (index != -1) // if vector contains this playerid, remove it (because player disconnected)
    {
             vector_remove(USERS_ONLINE, index);
    }

}

stock KickAllPlayers() // with this we can kick all players (not recommended)
{
    for (new i = 0 ; i < vector_size(USERS_ONLINE) ; i++)
    {
        Kick(vector_get(USERS_ONLINE, i));
    }
}
So this must be really fast compared to the old way of doing loops.
Now i understand, genius! Good job.
Reply
#6

In another words, this is kinda like foreach?

pawn Code:
#include <a_samp>
#include <foreach>

public OnPlayerConnect(playerid)
{
    // now we add connected user into vector
    Itter_Add(Player, playerid);//vector_push_back(USERS_ONLINE, playerid);
}

public OnPlayerDisconnect(playerid, reason)
{
    Itter_Remove(Player, playerid);
}

stock KickAllPlayers() // with this we can kick all players (not recommended)
{
    foreach(Player, i)//for (new i = 0 ; i < vector_size(USERS_ONLINE) ; i++)
    {
        Kick(i);
    }
}
BUT, good job on the plugin!!!
Reply
#7

This can be used like foreach and is suitable for that but basically this is suitable for many other things too.
You can search values and get values from middle of vector easily without looping. Basically this is array without some restrictions (need to specify size in code). I'm gonna extend this plugin to have other data containers too (std::map: key->value storage, kinda like dictionary)
Reply
#8

Good. I haven't used something like this before, but I will use it for my gamemode
Reply
#9

really nice work!!
Reply
#10

Update
Now plugin also provides std::map data container.

std::map is basically key-value list. Key is always string (array). Value can be either int, float or array (string). Values are referenced with keys (map_get(MAPID, "key") to get integer value)

Example:

"stringkey1" => "this is value"
"floatkey2" => 0.492
"intkey" => 46
Reply
#11

Cool. Finally we don't have to decide the array's size when writing the script. I used to achieve this with the GVar plugin.
Reply
#12

Is this faster than Y_Less's foreach include?
Reply
#13

Nice Job!
Quote:
Originally Posted by anonymousx
View Post
Is this faster than Y_Less's foreach include?
Someone should do a test O.o
Reply
#14

First of all, dynamic implementation of this plugin can't be faster than static one from foreach.
Second, it uses natives calls to get data from memory witch are slower than getting data from pawn variables.

Just like pvars, gvars, etc It just manages memory more efficient.
Reply
#15

Yes, foreach is faster in looping through iterator than vector looping (vector/iter size: 50)
I used this script: http://pastebin.com/3hxJuFUe
Result:
Code:
Bench for foreach: executes, by average, 366.14 times/ms
foreach ran 50 times
Bench for vector loop: executes, by average, 214.64 times/ms
vector loop ran 50 times
But in defend of my plugin () I would say both are fast enough, but foreach is faster.
Reply
#16

About time someone worked on this
Reply
#17

Great, so actually you can create a streamer in PAWN with "unlimited" amount of objects using this plugin? Cause so did I in C++ for my own a while ago.

I'm not sure, cause I didn't check the functions yet. Like nice though, good job.
Reply
#18

GreatІ.

Good contribution with your work, it's look very useful and dynamic.
Reply
#19

Maybe I'm gonna use it for something.
Reply
#20

Ironically maps and vectors have been available for a really long time, its just no on really thinks outside the box. You can achieve the same things with incognito's GVAR plugin, you just gotta use a little brain power.


Though i am excited to see the STL library coming to pawn! I've been wondering when someone was going to implement it.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)