In my plugin, I need to detect when a player touches a trigger_multiple and then uniquely identify the entity touched using a mapping that looks like:
entity_index -> ID
Where the ID is simply an unsigned integer.
Assume, that all data structures are built once and only once, never to be have entries inserted/deleted post-initialization. In your opinion, which of the following ways is the best for data retrieval?
Edit: Assume further that the data retrieval happens the instant OnTouch event fires, and that a client can touch multiple trigger_multiple entities at a time.
1. Use a hard-coded constant and large global static array
Code:
#define MAXENTITIES 2048
new g_iMyIDs[MAXENTITIES];
public OnTouch(const String:output[], caller, activator, Float:delay)
{
if (caller < MAXENTITIES)
PrintToChatAll("Entity id is %d", g_iMyIDs[caller]);
}
Advantages:
- Super-quick, constant-time retrieval.
Disadvantages:
- Wastes a small amount of memory. Array will be sparse.
- You can't, on initialization, store more entities than the MAXENTITIES constant allows. The program must be recompiled with a new larger constant.
2. Use a global dynamic array
Code:
new Handle:g_hMyIDs = CreateArray(2);
public OnTouch(const String:output[], caller, activator, Float:delay)
{
new ref = EntIndexToEntRef(caller);
for (new i = 0; i < GetArraySize(g_hMyIDs); i++)
{
if (GetArrayCell(g_hMyIDs, i, 0) == ref)
{
PrintToChatAll("Entity id is %d", GetArrayCell(g_hMyIDs, i, 1));
break;
}
}
}
Advantages:
- No memory is wasted.
- No need to set arbitrary constants pre-compilation, the array will automatically grow larger to accomodate the entities.
Disadvantages:
- Dynamic arrays are slower than static arrays. It takes linear time to find the entity, and assuming GetArrayCell() also takes linear(?) time, it would, at worst, take exponential time.
3. Modify the m_iName ent prop data at initialization to include the ID
Code:
public OnTouch(const String:output[], caller, activator, Float:delay)
{
decl String:sTargetName[256];
GetEntPropString(caller, Prop_Data, "m_iName", sTargetName, sizeof(sTargetName));
PrintToChatAll("Entity id is %d", StringToInt(sTargetName));
}
Advantages:
- No space is wasted.
- Constant-time retrieval.
Disadvantages:
- This will break communication if one entity hooked receives output from another entity.