Raised This Month: $32 Target: $400
 8% 

Extended arraylist


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Sizzla
Junior Member
Join Date: Jun 2014
Old 07-18-2017 , 08:37   Extended arraylist
Reply With Quote #1

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?
Sizzla is offline
Chaosxk
Veteran Member
Join Date: Aug 2010
Location: Westeros
Old 07-18-2017 , 10:16   Re: Extended arraylist
Reply With Quote #2

An arraylist of datapacks maybe?
__________________
Chaosxk is offline
shavit
AlliedModders Donor
Join Date: Dec 2011
Location: Israel
Old 07-18-2017 , 11:28   Re: Extended arraylist
Reply With Quote #3

SourcePawn can't do that unfortunately. Use Dynamic! https://forums.alliedmods.net/showthread.php?t=270519
__________________
retired
shavit is offline
DJ Tsunami
DJ Post Spammer
Join Date: Feb 2008
Location: The Netherlands
Old 07-18-2017 , 13:11   Re: Extended arraylist
Reply With Quote #4

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);
    }

__________________
Advertisements | REST in Pawn - HTTP client for JSON REST APIs
Please do not PM me with questions. Post in the plugin thread.

Last edited by DJ Tsunami; 07-19-2017 at 18:44. Reason: Methodmap
DJ Tsunami is offline
headline
SourceMod Moderator
Join Date: Mar 2015
Old 07-18-2017 , 14:08   Re: Extended arraylist
Reply With Quote #5

Quote:
Originally Posted by shavit View Post
SourcePawn can't do that unfortunately. Use Dynamic! https://forums.alliedmods.net/showthread.php?t=270519
Definitely use SourceMod's StringMap instead of Dynamic.
headline is offline
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 07-19-2017 , 07:34   Re: Extended arraylist
Reply With Quote #6

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.
__________________
asherkin is offline
Neuro Toxin
Veteran Member
Join Date: Oct 2013
Location: { closing the void; }
Old 07-19-2017 , 17:41   Re: Extended arraylist
Reply With Quote #7

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
__________________

Last edited by Neuro Toxin; 07-19-2017 at 17:58.
Neuro Toxin is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 17:46.


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