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
__________________