AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Extended arraylist (https://forums.alliedmods.net/showthread.php?t=299553)

Sizzla 07-18-2017 08:37

Extended arraylist
 
Hello
For my purposes I need structure something like own arraylist with additional variables and i wondering how to obtain this goal. Normally I would use enum and then array of enums, but is there any other better way?

ArrayList g_Zoo = new ArrayList(SIZE);
-g_Zoo[0]
---char[] name
---char[] description
---int years
---ArrayList animals

-g_Zoo[1]
---char[] name2
---char[] description2
---int years2
---ArrayList animals2

...

-g_Zoo[SIZE-1]
---char[] nameSIZE-1
---char[] descriptionSIZE-1
---int yearsSIZE-1
---ArrayList animalsSIZE-1


etc..


Any ideas?

Chaosxk 07-18-2017 10:16

Re: Extended arraylist
 
An arraylist of datapacks maybe?

shavit 07-18-2017 11:28

Re: Extended arraylist
 
SourcePawn can't do that unfortunately. Use Dynamic! https://forums.alliedmods.net/showthread.php?t=270519

DJ Tsunami 07-18-2017 13:11

Re: Extended arraylist
 
Something like this?

zoo.inc:
PHP Code:

methodmap Zoo StringMap
{
    public 
Zoo() { return view_as<Zoo>(new StringMap()); }

    public 
void GetName(char[] bufferint maxlength)
    {
        
this.GetString("name"buffermaxlength);
    }
    public 
void SetName(const char[] value)
    {
        
this.SetString("name"value);
    }

    public 
void GetDescription(char[] bufferint maxlength)
    {
        
this.GetString("description"buffermaxlength);
    }
    public 
void SetDescription(const char[] value)
    {
        
this.SetString("description"value);
    }

    
property int Years
    
{
        public 
get()
        {
            
int years;
            
this.GetValue("years"years);

            return 
years;
        }
        public 
set(int years)
        {
            
this.SetValue("years"years);
        }
    }

    
property ArrayList Animals
    
{
        public 
get()
        {
            
ArrayList animals;
            
this.GetValue("animals"animals);

            return 
animals;
        }
        public 
set(ArrayList animals)
        {
            
this.SetValue("animals"animals);
        }
    }
}; 

zoo.sp:
PHP Code:

#include <sourcemod>
#include <zoo>

Zoo g_Zoo[32];

public 
void OnPluginStart()
{
    
ArrayList animals = new ArrayList(ByteCountToCells(256));

    
g_Zoo[0] = new Zoo();
    
g_Zoo[0].SetName("Foo");
    
g_Zoo[0].SetDescription("Boo");
    
g_Zoo[0].Years 5;
    
g_Zoo[0].Animals animals;

    
g_Zoo[1] = new Zoo();
    
g_Zoo[1].SetName("Foo");
    
g_Zoo[1].SetDescription("Boo");
    
g_Zoo[1].Years 5;
    
g_Zoo[1].Animals animals;

    
g_Zoo[2] = new Zoo();
    
g_Zoo[2].SetName("Foo");
    
g_Zoo[2].SetDescription("Boo");
    
g_Zoo[2].Years 5;
    
g_Zoo[2].Animals animals;

    
char name[256];
    for (
int i 0sizeof(g_Zoo); i++)
    {
        if (
g_Zoo[i] == null) continue;

        
g_Zoo[i].GetName(namesizeof(name));
        
PrintToServer("Zoo %s"name);
    }



headline 07-18-2017 14:08

Re: Extended arraylist
 
Quote:

Originally Posted by shavit (Post 2536132)
SourcePawn can't do that unfortunately. Use Dynamic! https://forums.alliedmods.net/showthread.php?t=270519

Definitely use SourceMod's StringMap instead of Dynamic.

asherkin 07-19-2017 07:34

Re: Extended arraylist
 
You can indeed do this using a single ArrayList with a suitably large blocksize, but some helper functions would be required as GetString can't take a starting offset.

Neuro Toxin 07-19-2017 17:41

Re: Extended arraylist
 
An example of Dynamic...

Using the class builder I created this methodmap.

Code:

#if defined _dynamic_class_zoo_
  #endinput
#endif
#define _dynamic_class_zoo_

methodmap Zoo < Dynamic
{
        public Zoo()
        {
                // First we make a new dymanic object
                Dynamic myclass = Dynamic(774, 0);

                // Next we will define all the members
                // -> We do this to force the offsets to always be in the same location
                //    over multiple instances of the same class.
                myclass.SetString("Name", "", 256);
                myclass.SetString("Description", "", 512);
                myclass.SetInt("Years", 0);
                myclass.SetObject("ChildAnimals", view_as<Dynamic>(INVALID_DYNAMIC_OBJECT));
                return view_as<Animals>(myclass);
        }

        // Note that I use static offsets to access members.
        // -> This improves performance by caching member offsets
        // -> This is why we force the members in during the contructor
        // -> Failure to force members in the constructor will cause corruption

        public bool GetName(char[] buffer, int length)
        {
                static DynamicOffset offset = INVALID_DYNAMIC_OFFSET;
                if (offset == INVALID_DYNAMIC_OFFSET)
                {
                        offset = this.GetMemberOffset("Name");
                        if (offset == INVALID_DYNAMIC_OFFSET)
                                SetFailState("A serious error occured in Dynamic!");
                }
                this.GetStringByOffset(offset, buffer, length);
                return true;
        }

        public void SetName(const char[] buffer)
        {
                static DynamicOffset offset = INVALID_DYNAMIC_OFFSET;
                if (offset == INVALID_DYNAMIC_OFFSET)
                {
                        offset = this.GetMemberOffset("Name");
                        if (offset == INVALID_DYNAMIC_OFFSET)
                        {
                                offset = this.SetString("Name", buffer);
                                return;
                        }
                }
                this.SetStringByOffset(offset, buffer);
        }

        public bool GetDescription(char[] buffer, int length)
        {
                static DynamicOffset offset = INVALID_DYNAMIC_OFFSET;
                if (offset == INVALID_DYNAMIC_OFFSET)
                {
                        offset = this.GetMemberOffset("Description");
                        if (offset == INVALID_DYNAMIC_OFFSET)
                                SetFailState("A serious error occured in Dynamic!");
                }
                this.GetStringByOffset(offset, buffer, length);
                return true;
        }

        public void SetDescription(const char[] buffer)
        {
                static DynamicOffset offset = INVALID_DYNAMIC_OFFSET;
                if (offset == INVALID_DYNAMIC_OFFSET)
                {
                        offset = this.GetMemberOffset("Description");
                        if (offset == INVALID_DYNAMIC_OFFSET)
                        {
                                offset = this.SetString("Description", buffer);
                                return;
                        }
                }
                this.SetStringByOffset(offset, buffer);
        }

        property int Years
        {
                public get()
                {
                        static DynamicOffset offset = INVALID_DYNAMIC_OFFSET;
                        if (offset == INVALID_DYNAMIC_OFFSET)
                        {
                                offset = this.GetMemberOffset("Years");
                                if (offset == INVALID_DYNAMIC_OFFSET)
                                        SetFailState("A serious error occured in Dynamic!");
                        }
                        return this.GetIntByOffset(offset);
                }
                public set(int value)
                {
                        static DynamicOffset offset = INVALID_DYNAMIC_OFFSET;
                        if (offset == INVALID_DYNAMIC_OFFSET)
                        {
                                offset = this.GetMemberOffset("Years");
                                if (offset == INVALID_DYNAMIC_OFFSET)
                                {
                                        offset = this.SetInt("Years", value);
                                        return;
                                }
                        }
                        this.SetIntByOffset(offset, value);
                }
        }

        property Dynamic Animals
        {
                public get()
                {
                        static DynamicOffset offset = INVALID_DYNAMIC_OFFSET;
                        if (offset == INVALID_DYNAMIC_OFFSET)
                        {
                                offset = this.GetMemberOffset("Animals");
                                if (offset == INVALID_DYNAMIC_OFFSET)
                                        SetFailState("A serious error occured in Dynamic!");
                        }
                        return this.GetObjectByOffset(offset);
                }
                public set(Dynamic value)
                {
                        static DynamicOffset offset = INVALID_DYNAMIC_OFFSET;
                        if (offset == INVALID_DYNAMIC_OFFSET)
                        {
                                offset = this.GetMemberOffset("Animals");
                                if (offset == INVALID_DYNAMIC_OFFSET)
                                {
                                        offset = this.SetObject("ChildAnimals", value);
                                        return;
                                }
                        }
                        this.SetObjectByOffset(offset, value);
                }
        }
}

And here is the example code in this thread converted to use Dynamic!

Code:

#include <sourcemod>
#include <dymamic>
#include <dynamic/methodmaps/zoo>

Dynamic g_Zoos = INVALID_DYNAMIC_OBJECT;

public void OnPluginStart()
{
    g_Zoos = Dynamic();

    Zoo zoo = Zoo();
    zoo.SetName("Foo");
    zoo.SetDescription("Boo");
    zoo.Years = 5;
    zoo.Animals = Dynamic();
    g_Zoos.PushDynamic(zoo);

    zoo = Zoo();
    zoo.SetName("Foo");
    zoo.SetDescription("Boo");
    zoo.Years = 5;
    zoo.Animals = Dynamic();
    g_Zoos.PushDynamic(zoo);

    zoo = Zoo();
    zoo.SetName("Foo");
    zoo.SetDescription("Boo");
    zoo.Years = 5;
    zoo.Animals = Dynamic();
    g_Zoos.PushDynamic(zoo);

    char name[256];
    int count = g_Zoos.MemberCount;
    for (int i = 0; i < count; i++)
    {
        zoo = view_as<Zoo>(g_Zoos.GetDynamicByIndex(i));
        if (!zoo.IsValid) continue;

        zoo.GetName(name, sizeof(name));
        PrintToServer("Zoo %s", name);
    }
}

You could then create an Animal methodmap and implement it the same way to zoo.Animals


All times are GMT -4. The time now is 20:56.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.