View Single Post
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