View Single Post
Peace-Maker
SourceMod Plugin Approver
Join Date: Aug 2008
Location: Germany
Old 10-12-2020 , 04:55   Re: Return arrays in ArrayLists by reference
Reply With Quote #5

You can specify which index inside the arraylist entry you get or set using the ArrayList.Get or ArrayList.Set natives ' "block" parameter.

When creating the ArrayList, you set the blocksize to be the number of cells of your enum struct.
PHP Code:
players = new ArrayList(sizeof(Player)); 
Then you can access the different cells/blocks of every pushed enum struct directly by accessing the block at that offset into the enum struct. You can get the cell offset of an enum struct member using the :: operator like Player::ballEntRef. Cells of an array are called "blocks" in ArrayList terms..
PHP Code:
int ballEntRef players.Get(indexPlayer::ballEntRef); 
Your example isn't a great one for this kind of stuff, since there is a known, small fixed upper limit of players which you can just access directly using Player players[MAXPLAYERS+1];
But if we really want to use ArrayLists, you can use them like above. Of course you have to get the correct index into the ArrayList which belongs to the entry for your client first, but luckly ArrayList.FindValue has a block parameter too, so you can look for entries which have the client index at the e.g. 2nd block.

This allows you to access enum struct members without grabbing the whole array - BUT the performance gain you're hoping for is gone once you need to get/set two members at once. Additionally you have to keep a local copy of the enum struct updated yourself.

PHP Code:
enum struct Player {
    
bool cool;
    
int client;
    
int ballEntRef;
    
int ballColor[3];
}

ArrayList players

public 
void OnPluginStart() {
    
players = new ArrayList(sizeof(Player));

    
// Add new entry
    
Player p;
    
p.cool true;
    
p.client 1;
    
p.ballEntRef 1234;
    
p.ballColor = {255,255,255};
    
int index players.PushArray(p);

    
// Change color
    
UpdateColor(1, {123,123,123});

    
// Check color
    
Player p2;
    
players.GetArray(indexp2);
    
PrintToServer("color = {%d, %d, %d}"p2.ballColor[0], p2.ballColor[1], p2.ballColor[2]);
    
// Caution, "p" isn't updated!
    
PrintToServer("old color = {%d, %d, %d}"p.ballColor[0], p.ballColor[1], p.ballColor[2]);

    
int ballEntRef players.Get(indexPlayer::ballEntRef);
    
PrintToServer("ballEntRef = %d"ballEntRef);
}

void UpdateColor(int clientint color[3]) {
    
// Find the Player enum struct entry with that client index.
    
int index players.FindValue(clientPlayer::client);
    if (
index == -1)
        return;

    
// Update the ball color array directly
    
for (int i3i++)
        
players.Set(indexcolor[i], Player::ballColor i);

__________________

Last edited by Peace-Maker; 10-12-2020 at 04:59.
Peace-Maker is offline