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

It should return -1 in that case. Can you try in your format change %d to %i and look if slot is -1 then
Reply
#42

Does this accepts multi-dimensional vectors/maps/arrays (whatever they're call'd) ?
Reply
#43

This is awesome! I'm using this right now, though not on anything important.
Reply
#44

Quote:
Originally Posted by Macluawn
Посмотреть сообщение
Does this accepts multi-dimensional vectors/maps/arrays (whatever they're call'd) ?
It doesnt directly support them but you can have a vector which contains indexes of other vectors. Thats how you can get it multidimensional.
Reply
#45

What does it have with the SA-MP scripting?
Reply
#46

Quote:
Originally Posted by GangsTa_
Посмотреть сообщение
What does it have with the SA-MP scripting?
You can use vectors and maps to store data (variables). They use dynamic memory, and are very efficient.

Vectors are sequence containers, meaning they remember the order in which the data is stored. So if you add playerids to a vector: you can loop through the vector, and not do any needless loops. Similar to foreach but not as fast. A simple example, but I'm sure you can think of other uses for a vector.

Maps are associative containers, meaning they use a key and a value (similar to a 2D array using an enum the enum would be the key). Maps DO NOT remember the order in which data is stored, usually the keys are sorted in ascending order, (there are ways to change which order). With maps an example would be an inventory system - the key could be the name of the item and the value can be the amount of items the player has. Again a simple example...

There are a lot more features to them than that also.
Reply
#47

Just did these defines for enumerating through vector easily. Vector must only contain entries of same data type.
Код:
#define vector_enum_cell<%0,%1> for (new _%0_it = 0, %1 = 0 ; (_%0_it < vector_size(%0) && (%1 = vector_get(%0,_%0_it)))  ; _%0_it++)
#define vector_enum_float<%0,%1> for (new _%0_it = 0, Float:%1 = 0 ; (_%0_it < vector_size(%0) && (%1 = vector_get_float(%0,_%0_it)))  ; _%0_it++)
#define vector_enum_arr<%0,%1,%2> for (new _%0_it = 0, %1[%2] ; (_%0_it < vector_size(%0) && (vector_get_arr(%0,_%0_it,%1,%2)))  ; _%0_it++)
Example usage:

Код:
	new vector_id = 0, index = 0;

	vector_push_back_arr(vector_id, "Hello, World!");
	vector_push_back_arr(vector_id, "Hello to you too.");
	
	vector_enum_arr<vector_id, curStr, 128>
	{
	    printf("index %i: %s", index, curStr);
	    index++;
	}
	vector_clear(vector_id);
Prints
0: Hello, World!
1: Hello to you too.


How-to use:

Код:
vector_enum_cell<vectorid, currentcell>
Specify vector to enumerate in vectorid.
Specify variable name to store current cell.

vector_enum_float<vectorid, currentfloat>
Specify vector to enumerate in vectorid.
Specify variable name to store current float.

vector_enum_arr<vectorid, currentarr, length>
Specify vector to enumerate in vectorid.
Specify variable name to store current array.
Specify length for currentarr (if vector contains array larger than it, its truncated)
Index of current entry is stored in variable named "_X_it" where X is vector id specified in vectorid (if you specified a variable there, X will be variable name, not the content). So its not suggested to use this. Better to use your own index variable like in example.

These defines can be put into cstl.inc file for easy usage.
Reply
#48

Soon going to update this. Planned to include function to enumerate through map (currently its not possible, you have to know the correct key)
Reply
#49

Newest cstl (with vector_index_exists function) for linux, compiled on Linux Debian 5 Lenny
http://solidfiles.com/d/dda54/
Reply
#50

Please update for 0.3d
Reply
#51

0.3d? Has it been released, I can find only RC versions.
Reply
#52

Great job! This plugin saved my AMX a couple megabytes..

I'd like to suggest a couple changes to the include file, though. Add the "const" keyword for all strings that won't get changed (i.e. element[], key[], value[]). Also, change buflen to "buflen = sizeof(buffer)" so you won't have to specify that argument in most cases.

Actually, I could just do that for you.. Here:
pawn Код:
#if defined _cstl_inc
    #endinput
#endif
#define _cstl_inc
#pragma library cstl

#define VEC_ENTRY_TYPE_CELL 1
#define VEC_ENTRY_TYPE_ARRAY 2
#define VEC_ENTRY_TYPE_FLOAT 3

// VECTOR

native vector_push_back(vecid, element); // push element
native vector_push_back_float(vecid, Float:element); // push element
native vector_push_back_arr(vecid, const element[]); // push array

native vector_size(vecid); // get vector size

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

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

native vector_clear(vecid); // clear vector
native vector_resize(vecid, newsize); // attention!: reducing size causes memory leaks if array pointers are removed

native vector_entry_type(vecid, id); // get element type
native vector_remove(vecid, id); // remove element by ID

native vector_find(vecid, element);  // find ID of int element
native vector_find_float(vecid, Float:element); // find ID of float element
native vector_find_arr(vecid, const element[]); // find ID 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

native vector_index_exists(vecid, index); // does index exist

// MAP

native map_insert(mapid, const key[], value);
native map_insert_float(mapid, const key[], Float:value);
native map_insert_arr(mapid, const key[], const value[]);

native map_get(mapid, const key[]);
native Float:map_get_float(mapid, const key[]);
native map_get_arr(mapid, const key[], buffer[], buflen = sizeof(buffer));

native map_size(mapid);
native map_remove(mapid, const key[]);
native map_contains(mapid, const key[]);
native map_entry_type(mapid, const key[]);

native map_clear(mapid);

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
Reply
#53

This is awesome
Reply
#54

Nice to hear that this actually has users :P New update is coming in near future (havent been so interested in samp recently). And thanks for include file update, I'm going to include updated file in next release.
Reply
#55

i <3 your plugin, Teprey! without it, i would still suffer at optimizing my ugly arrays. its so awesome to use the containers for tons of objects with my fireworks script - no more shuffling around huge arrays, i even use it for sorting aswell - and btw: the profiler results are looking promising for a nice CPU-meltdown
Reply
#56

I'm experiencing an issue with this plugin. Everything works very nicely on Windows, but last night I figured I had to compile the plugin on my own for Linux (CentOS to be more precise). I was getting some library errors prior to that.

A link to the version I compiled: http://sf-se.net/dev/cstl.so

Now to the main problem - maps do not work. Everything to do with maps will make the server lock up. Again, this must be an issue with my plugin version and my server setup. Vectors work like charm.

Can anyone think of a way to fix this?
Reply
#57

Quote:
Originally Posted by AndreT
Посмотреть сообщение
I'm experiencing an issue with this plugin. Everything works very nicely on Windows, but last night I figured I had to compile the plugin on my own for Linux (CentOS to be more precise). I was getting some library errors prior to that.

A link to the version I compiled: http://sf-se.net/dev/cstl.so

Now to the main problem - maps do not work. Everything to do with maps will make the server lock up. Again, this must be an issue with my plugin version and my server setup. Vectors work like charm.

Can anyone think of a way to fix this?
I will test your compiled version on a Linux server and tell you if I can properly re-create this.

EDIT: Problems with my Linux server. Sorry, I can't help you.
Reply
#58

I got around to finally being able to test this (was locked up in jail meh long story, anyhow) I got a new dedicated so I am able to continue testing/devin on linux. I found out the problems with maps on linux.

There is a try catch block in map_insert that is causing an infinite loop. It works fine on windows but on linux it has different results. To be honest that block of code is not even needed, seeing that maps will automatically add a new key value or if it exists just update the keys data. So you can get this working on linux with maps just comment out (or remove) this from n_map_insert.....

Код:
	try {
		maps[amx][mapid].erase(maps[amx][mapid].find(key));
	} catch(std::exception e) {  }
You can find that at lines 439-441, removing that has normal functioning maps on linux. I have not tested all the other map functions I only needed to use map_insert, map_contains and map_clear.

Seeing that Teprey doesn't seem to be active developing this anymore I may give it a rewrite adding more of the cstl containers. I can see a real benefit to having multi maps available to server owners saving lots of file loads or SQL queries by keeping data chunks loaded in memory (If you have it available such as I do...). No point in having to reread account data when a player crashes just store it in the map check if they exist in the map load the map data. Not sure how the speed would end up but I think it warrants some testing.
Reply
#59

Hey, cyber_punk!

I'm glad you're out of jail and will maybe be working on making this awesome plugin even better. Thanks for the information on the maps bug.
Reply
#60

I got a bot attack on my server, not sure how the hell they got around needing a player name to connect but I ended up discovering a run time error with the way map functions are scripted in this. The error would terminate the server which sucks. I have it fixed though.

The error: terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_S_construct null not valid

So if you went to add a key that was null/empty it would pop that. Like I said under normal conditions this would not happen but with the attack I had the player name was empty and passed on to the map_insert function. The fix is just to set the char array to a default value of NULL then checking after using amx_StrParam to make sure there is a valid string (not NULL).

I also fixed map_remove which would crash a server if you tried to remove a key that did not exist in the map.

Just a tip you can save performance by not using map_contains before map_get functions. Just check that the returned value is not -1. The get functions have a built in check to see if they are contained in the map.


Just download the attached zip and compile. If you have or find any issues just report them and I will see what I can do.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)