diff --git a/plugins/disabled/dynamic-example.smx b/plugins/disabled/dynamic-example.smx index f2f2c42..5ba6d0a 100644 Binary files a/plugins/disabled/dynamic-example.smx and b/plugins/disabled/dynamic-example.smx differ diff --git a/plugins/dynamic.smx b/plugins/dynamic.smx index 73191e5..96d717c 100644 Binary files a/plugins/dynamic.smx and b/plugins/dynamic.smx differ diff --git a/scripting/dynamic-example.sp b/scripting/dynamic-example.sp index 9cfa4fc..db838be 100644 --- a/scripting/dynamic-example.sp +++ b/scripting/dynamic-example.sp @@ -49,6 +49,12 @@ public void OnPluginStart() Dynamic anotherobj = Dynamic(); anotherobj.SetInt("someint", 128); someobj.SetObject("anotherobj", anotherobj); + + // You can name a dynamic object + someobj.SetName("someobj"); + + // So another plugin can access it like so + someobj = Dynamic.FindByName("someobj"); // Sometimes you might want to iterate through members to accomplish stuff int count = someobj.MemberCount; @@ -101,9 +107,11 @@ public void OnPluginStart() someobj.SetString("somestring", "ye sure moite"); // You MUST! dispose your dynamic objects when your done. - someobj.Dispose(); anotherobj.Dispose(); + // You can also dispose of any disposable members like this + someobj.Dispose(true); + // You can also use Dynamic to back Methodmap properties. This is another step // towards pawn feeling a bit more OO // -> Find the methodmap in 'include/dynamic-example.sp' diff --git a/scripting/dynamic.sp b/scripting/dynamic.sp index 8842787..8a15d78 100644 --- a/scripting/dynamic.sp +++ b/scripting/dynamic.sp @@ -5,13 +5,14 @@ static Handle s_Collection = null; static int s_CollectionSize = 0; static Handle s_FreeIndicies = null; +static Handle s_tObjectNames = null; public Plugin myinfo = { name = "Dynamic", author = "Neuro Toxin", description = "Shared Dynamic Objects for Sourcepawn", - version = "0.0.7", + version = "0.0.8", url = "https://forums.alliedmods.net/showthread.php?t=270519" } @@ -33,6 +34,8 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max RegPluginLibrary("dynamic"); CreateNative("Dynamic_Initialise", Native_Dynamic_Initialise); CreateNative("Dynamic_Dispose", Native_Dynamic_Dispose); + CreateNative("Dynamic_SetName", Native_Dynamic_SetName); + CreateNative("Dynamic_FindByName", Native_Dynamic_FindByName); CreateNative("Dynamic_GetInt", Native_Dynamic_GetInt); CreateNative("Dynamic_SetInt", Native_Dynamic_SetInt); CreateNative("Dynamic_GetIntByOffset", Native_Dynamic_GetIntByOffset); @@ -76,6 +79,7 @@ public void OnPluginStart() s_Collection = CreateArray(Dynamic_Field_Count); s_CollectionSize = 0; s_FreeIndicies = CreateStack(); + s_tObjectNames = CreateTrie(); } public void OnPluginEnd() @@ -83,7 +87,7 @@ public void OnPluginEnd() // Dipose of all objects in the collection pool while (s_CollectionSize > 0) { - Dynamic_Dispose(view_as(s_CollectionSize - 1)); + Dynamic_Dispose(s_CollectionSize - 1, false); } } @@ -129,8 +133,32 @@ public int Native_Dynamic_Dispose(Handle plugin, int params) { // Get and validate index int index = GetNativeCell(1); - if (!Dynamic_IsValid(index)) + if (!Dynamic_IsValid(index, true)) return 0; + + // Dispose of child members if + if (GetNativeCell(2)) + { + Handle data = GetArrayCell(s_Collection, index, Dynamic_Data); + int blocksize = GetArrayCell(s_Collection, index, Dynamic_Blocksize); + int count = GetMemberCount(index); + int offset; int position; int disposablemember; + Dynamic_MemberType membertype; + + for (int i = 0; i < count; i++) + { + position = 0; + offset = GetMemberOffsetByIndex(index, i); + membertype = GetMemberType(data, position, offset, blocksize); + + if (membertype == DynamicType_Object) + { + disposablemember = GetMemberDataInt(data, position, offset, blocksize); + if (Dynamic_IsValid(disposablemember)) + Dynamic_Dispose(disposablemember, true); + } + } + } // Close dynamic object array handles CloseHandle(GetArrayCell(s_Collection, index, Dynamic_Offsets)); @@ -160,10 +188,40 @@ public int Native_Dynamic_Dispose(Handle plugin, int params) SetArrayCell(s_Collection, index, -1, Dynamic_Index); PushStackCell(s_FreeIndicies, index); } - return 1; } +public int Native_Dynamic_SetName(Handle plugin, int params) +{ + // Get and validate index + int index = GetNativeCell(1); + if (!Dynamic_IsValid(index)) + return 0; + + int length; + GetNativeStringLength(2, length); + char[] objectname = new char[length]; + GetNativeString(2, objectname, length); + return SetTrieValue(s_tObjectNames, objectname, index, GetNativeCell(3)); +} + +public int Native_Dynamic_FindByName(Handle plugin, int params) +{ + int length; + GetNativeStringLength(1, length); + char[] objectname = new char[length]; + GetNativeString(1, objectname, length); + + int index; + if (!GetTrieValue(s_tObjectNames, objectname, index)) + return INVALID_DYNAMIC_OBJECT; + + if (!Dynamic_IsValid(index)) + return INVALID_DYNAMIC_OBJECT; + + return index; +} + public int Native_Dynamic_IsValid(Handle plugin, int params) { int index = GetNativeCell(1); @@ -1453,7 +1511,11 @@ public int Native_Dynamic_GetMemberOffsetByIndex(Handle plugin, int params) return INVALID_DYNAMIC_OFFSET; int memberindex = GetNativeCell(2); - + return GetMemberOffsetByIndex(index, memberindex); +} + +public int GetMemberOffsetByIndex(int index, int memberindex) +{ Handle memberoffsets = GetArrayCell(s_Collection, index, Dynamic_MemberOffsets); int membercount = GetArraySize(memberoffsets); diff --git a/scripting/include/dynamic.inc b/scripting/include/dynamic.inc index 09ae3b5..73d1e06 100644 --- a/scripting/include/dynamic.inc +++ b/scripting/include/dynamic.inc @@ -26,7 +26,7 @@ native int Dynamic_GetCollectionSize(); native Dynamic Dynamic_Initialise(int blocksize=64, int startsize=0); native bool Dynamic_IsValid(int index, bool throwerror=false); -native bool Dynamic_Dispose(Dynamic obj); +native bool Dynamic_Dispose(int index, bool disposemembers); native int Dynamic_GetMemberCount(Dynamic obj); native int Dynamic_GetMemberOffset(Dynamic obj, const char[] membername); @@ -36,6 +36,9 @@ native bool Dynamic_GetMemberNameByOffset(Dynamic obj, int offset, char[] buffer native Dynamic_MemberType Dynamic_GetMemberType(Dynamic obj, const char[] membername); native Dynamic_MemberType Dynamic_GetMemberTypeByOffset(Dynamic obj, int offset); +native bool Dynamic_SetName(Dynamic obj, const char[] objectname, bool replace); +native Dynamic Dynamic_FindByName(const char[] objectname); + native int Dynamic_CallbackCount(Dynamic obj); native bool Dynamic_HookChanges(Dynamic obj, DynamicHookCB callback); native bool Dynamic_UnHookChanges(Dynamic obj, DynamicHookCB callback); @@ -90,9 +93,19 @@ methodmap Dynamic } } - public void Dispose() + public void Dispose(bool disposemembers=true) + { + Dynamic_Dispose(view_as(this), disposemembers); + } + + public bool SetName(const char[] objectname, bool replace=false) + { + return Dynamic_SetName(this, objectname, replace); + } + + public static Dynamic FindByName(const char[] objectname) { - Dynamic_Dispose(this); + return Dynamic_FindByName(objectname); } public int GetInt(const char[] membername, int defaultvalue=-1) @@ -251,6 +264,8 @@ public __pl_dynamic_SetNTVOptional() { MarkNativeAsOptional("Dynamic_Initialise"); MarkNativeAsOptional("Dynamic_Dispose"); + MarkNativeAsOptional("Dynamic_SetName"); + MarkNativeAsOptional("Dynamic_FindByName"); MarkNativeAsOptional("Dynamic_GetInt"); MarkNativeAsOptional("Dynamic_SetInt"); MarkNativeAsOptional("Dynamic_GetIntByOffset");