Just a handy little trick I came up with today (or within the last 24 hours at least). y_hashmap has the following function:
pawn Код:
enum E_DATA
{
E_NAME[32],
E_HASH[HASH_MAP_DATA],
E_CUSTOM_FIELDS
}
new HashMap:gMap<>;
new gArray[100][E_DATA];
HashMap_Init(gMap, gArray, E_HASH);
The hash map library allows for fast lookup of strings in an array, so you can use those instead of indexes. The "gMap" variable is used to quickly enter the main "gArray" array to find similar strings. "HashMap_Init" links the two. This, however, is a macro that expands to:
pawn Код:
_HashMap_Init(gMap, gArray[0][E_HASH], sizeof (gArray), sizeof (gArray[]) * 4, gArray[0][0])
There are 5 parameters:
1) The map.
2) The address of the first hash data.
3) The size of the array.
4) The size of the enum in bytes.
5) The address of the first name.
I'm not going to lie, the API isn't brilliantly designed. A better way would be:
pawn Код:
_HashMap_Init(gMap, gArray[0][0], sizeof (gArray), sizeof (gArray[]) * 4, _:E_HASH)
So the last parameter is an offset with a tag override. The API also requires the name (i.e. the string used to look up the entry) to be the first item in the enum.
However, the exact parameters and their order don't matter for this, the problem is here:
That is a tag mismatch - the second "0" does not have a tag of "E_DATA" so will give a warning. The easy way to fix this would be to do "gArray[0][E_NAME]" and have that as an extra macro parameter:
pawn Код:
HashMap_Init(gMap, gArray, E_NAME, E_HASH);
That seems pointless because it is ALWAYS "0" with a tag. We could instead do an explicit tag override:
pawn Код:
HashMap_Init(gMap, gArray, E_DATA, E_HASH); // gArray[0][E_DATA:0]
That still has the extra parameter for constant data. Note that the "E_HASH" parameter IS required because the size of the name isn't known and thus must be passed in. So I needed a way to make "0" without getting a tag mismatch warning, and without passing the tag. Fortunately, "E_HASH" has the correct tag but the wrong value, but that can change:
pawn Код:
gArray[0][E_HASH - E_HASH]
Any number subtracted from itself is 0, subtraction preserves tags, and because this is a constant minus a constant the compiler can do it for us and generate a constant in the resulting AMX (instead of generating code to do the maths).
Hence the macro contains the slightly odd looking "%1[0][(%2) - (%2)]" to generate a tagged 0 constant without passing in either 0 or the tag.