├── GPLv3.txt
├── LICENSE.txt
├── plugins
├── disabled
│ ├── dynamic-classexample.smx
│ ├── dynamic-example.smx
│ └── dynamic-test.smx
├── dynamic.smx
└── dynamic
│ └── dynamic.smx
└── scripting
├── dynamic-test.sp
├── dynamic.sp
├── dynamic
├── examples
│ ├── 001-the_dynamic_lifecycle
│ │ └── dynamic-example.sp
│ ├── 002-accessing_dynamic_members
│ │ └── dynamic-example.sp
│ ├── 003-type_conversion
│ │ └── dynamic-example.sp
│ ├── 999-old
│ │ ├── basics.sp
│ │ ├── collections
│ │ │ ├── collection.sp
│ │ │ ├── people.inc
│ │ │ └── person.inc
│ │ ├── dynamic-classexample.sp
│ │ ├── dynamic-example.sp
│ │ └── keyvalues
│ │ │ └── using_read_hook.sp
│ └── wiki_resources
│ │ ├── a_basic_methodmap.sp
│ │ └── accessing_members.sp
└── system
│ ├── benchmark
│ └── output.txt
│ ├── commands.sp
│ ├── datatypes
│ ├── bool.sp
│ ├── dynamic.sp
│ ├── float.sp
│ ├── function.sp
│ ├── handle.sp
│ ├── int.sp
│ ├── string.sp
│ └── vector.sp
│ ├── flatconfigs.sp
│ ├── handleusage.sp
│ ├── hooks.sp
│ ├── keyvalues.sp
│ ├── methodmaps
│ └── dynamicobject.sp
│ ├── natives.sp
│ ├── plugins.sp
│ ├── preparedquery.sp
│ └── selftest.sp
└── include
├── dynamic-example.inc
├── dynamic.inc
└── dynamic
├── methodmaps
├── basic.inc
├── collection.inc
├── dynamic.inc
├── dynamicoffset.inc
└── preparedquery.inc
└── natives.inc
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
--------------------------------------------------------------------------------
/plugins/disabled/dynamic-classexample.smx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntoxin66/Dynamic/ddecdaae44a2c0f43486a3952a2a0bd45ae915a3/plugins/disabled/dynamic-classexample.smx
--------------------------------------------------------------------------------
/plugins/disabled/dynamic-example.smx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntoxin66/Dynamic/ddecdaae44a2c0f43486a3952a2a0bd45ae915a3/plugins/disabled/dynamic-example.smx
--------------------------------------------------------------------------------
/plugins/disabled/dynamic-test.smx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntoxin66/Dynamic/ddecdaae44a2c0f43486a3952a2a0bd45ae915a3/plugins/disabled/dynamic-test.smx
--------------------------------------------------------------------------------
/plugins/dynamic.smx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntoxin66/Dynamic/ddecdaae44a2c0f43486a3952a2a0bd45ae915a3/plugins/dynamic.smx
--------------------------------------------------------------------------------
/plugins/dynamic/dynamic.smx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ntoxin66/Dynamic/ddecdaae44a2c0f43486a3952a2a0bd45ae915a3/plugins/dynamic/dynamic.smx
--------------------------------------------------------------------------------
/scripting/dynamic-test.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | public Plugin myinfo =
5 | {
6 | name = "Dynamic Test",
7 | author = "Neuro Toxin",
8 | description = "Benchmarks and Tests all Dynamic Object aspects",
9 | version = "1.0.2",
10 | url = "https://forums.alliedmods.net/showthread.php?t=270519"
11 | }
12 |
13 | public void OnPluginStart()
14 | {
15 | BenchmarkTest();
16 | }
17 |
18 | stock void BenchmarkTest()
19 | {
20 | int objectcount = 1000;
21 | int membercount = 100; // must be a multiple of 5
22 |
23 | PrintToServer("[SM] Preparing benchmark Test...");
24 | Dynamic someobject;
25 | char membernames[100][DYNAMIC_MEMBERNAME_MAXLEN];
26 | DynamicOffset memberoffsets[100];
27 | char buffer[DYNAMIC_MEMBERNAME_MAXLEN];
28 | int ival; float fval; char sval[DYNAMIC_MEMBERNAME_MAXLEN]; float vector[3];
29 | DynamicOffset offset;
30 | Dynamic objects[1000];
31 |
32 | // Make member names
33 | for (int x = 0; x < membercount; x++)
34 | {
35 | Format(membernames[x], DYNAMIC_MEMBERNAME_MAXLEN, "m_Field_%d", x);
36 | }
37 | PrintToServer("[SM] Starting Benchmark Tests...");
38 |
39 | // Create objectcount objects with 100 fields in each
40 | float start = GetEngineTime();
41 | for (int i=0; i({1.0, 2.0, 3.0}));
74 | x++;
75 | }
76 | else if (p==5)
77 | {
78 | memberoffsets[x] = someobject.SetString(membernames[x], "Some nice string that has some data", 128);
79 | }
80 | }
81 | }
82 | }
83 | PrintToServer("Created %d dynamic member(s) in %f second(s)", objectcount * membercount, GetEngineTime() - start);
84 |
85 | start = GetEngineTime();
86 | for (int i=0; i({2.0, 3.0, 4.0}));
259 | x++;
260 | }
261 | else if (p==5)
262 | {
263 | someobject.SetString(membernames[x], "123Some nice string that has some data123");
264 | }
265 | }
266 | }
267 | }
268 | PrintToServer("Updated %d dynamic member(s) in %f second(s)", objectcount * membercount, GetEngineTime() - start);
269 |
270 | start = GetEngineTime();
271 | for (int i=0; iobj.%s = %d", offset, member, obj.GetIntByOffset(offset));
361 | }
362 | case DynamicType_Float:
363 | {
364 | PrintToServer("[%d] obj.%s = %f", offset, member, obj.GetFloatByOffset(offset));
365 | }
366 | case DynamicType_String:
367 | {
368 | char somestring[64];
369 | obj.GetStringByOffset(offset, somestring, sizeof(somestring));
370 | PrintToServer("[%d] obj.%s = '%s'", offset, member, somestring);
371 | }
372 | }
373 | }
--------------------------------------------------------------------------------
/scripting/dynamic.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 | #define dynamic_use_local_methodmap 1
20 | #include
21 | #include
22 | #undef INVALID_DYNAMIC_OBJECT
23 | #define INVALID_DYNAMIC_OBJECT view_as(-1)
24 | #pragma newdecls required
25 | #pragma semicolon 1
26 |
27 | // Public data
28 | int s_CollectionSize = 0;
29 | Handle s_FreeIndicies = null;
30 | StringMap s_tObjectNames = null;
31 | Handle g_sRegex_Vector = null;
32 | int g_iDynamic_MemberLookup_Offset;
33 | ArrayList g_aPlugins = null;
34 |
35 | // Dynamics internal methodmaps
36 | #include "dynamic/system/methodmaps/dynamicobject.sp"
37 |
38 | // Dynamic datatypes
39 | #include "dynamic/system/datatypes/bool.sp"
40 | #include "dynamic/system/datatypes/dynamic.sp"
41 | #include "dynamic/system/datatypes/float.sp"
42 | #include "dynamic/system/datatypes/handle.sp"
43 | #include "dynamic/system/datatypes/int.sp"
44 | #include "dynamic/system/datatypes/string.sp"
45 | #include "dynamic/system/datatypes/vector.sp"
46 | #include "dynamic/system/datatypes/function.sp"
47 |
48 | // Other features
49 | #include "dynamic/system/commands.sp"
50 | #include "dynamic/system/flatconfigs.sp"
51 | #include "dynamic/system/handleusage.sp"
52 | #include "dynamic/system/hooks.sp"
53 | #include "dynamic/system/keyvalues.sp"
54 | #include "dynamic/system/natives.sp"
55 | #include "dynamic/system/plugins.sp"
56 | #include "dynamic/system/selftest.sp"
57 | #include "dynamic/system/preparedquery.sp"
58 |
59 | public Plugin myinfo =
60 | {
61 | name = "Dynamic",
62 | author = "Neuro Toxin",
63 | description = "Shared Dynamic Objects for Sourcepawn",
64 | version = "0.0.32",
65 | url = "https://forums.alliedmods.net/showthread.php?t=270519"
66 | }
67 |
68 | public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
69 | {
70 | // Initialise static plugin data
71 | s_Collection = CreateArray(Dynamic_Field_Count);
72 | s_CollectionSize = 0;
73 | s_FreeIndicies = CreateStack();
74 | s_tObjectNames = new StringMap();
75 | g_iDynamic_MemberLookup_Offset = ByteCountToCells(DYNAMIC_MEMBERNAME_MAXLEN)+1;
76 | g_aPlugins = CreateArray(2);
77 |
78 | // Reserve first object index for global settings
79 | DynamicObject settings = DynamicObject();
80 | settings.Initialise(null);
81 |
82 | // Ensure settings is assigned index 0
83 | if (view_as(settings) != 0)
84 | SetFailState("Serious error encountered assigning server settings index!");
85 |
86 | // Reserve first object indicies for player objects
87 | for (int client = 1; client < MAXPLAYERS; client++)
88 | {
89 | settings = DynamicObject();
90 | settings.Initialise(null);
91 |
92 | // This is a check to ensure the index matches the client
93 | if (view_as(settings) != client)
94 | SetFailState("Serious error encountered assigning player settings indicies!");
95 | }
96 |
97 | // Create natives
98 | CreateNatives();
99 |
100 | // Register commands
101 | RegisterCommands();
102 |
103 | // Register library
104 | RegPluginLibrary("dynamic");
105 | return APLRes_Success;
106 | }
107 |
108 | public void OnLibraryRemoved(const char[] name)
109 | {
110 | _Dynamic_CollectGarbage();
111 | }
112 |
113 | public void OnPluginEnd()
114 | {
115 | // Dispose of all objects in the collection pool
116 | while (s_CollectionSize > 0)
117 | {
118 | _Dynamic_Dispose(view_as(s_CollectionSize - 1), false, _, _, false);
119 | }
120 | }
121 |
122 | public void OnMapStart()
123 | {
124 | _Dynamic_CollectGarbage();
125 | }
126 |
127 | stock void OnClientDisconnect_Post(int client)
128 | {
129 | _Dynamic_ResetObject(client);
130 | }
131 |
132 | stock int _Dynamic_Initialise(Handle plugin, int blocksize=64, int startsize=0, bool persistent=false)
133 | {
134 | int index = -1;
135 | DynamicObject member;
136 |
137 | // Always try to reuse a previously disposed index
138 | while (PopStackCell(s_FreeIndicies, index))
139 | {
140 | if (index < s_CollectionSize)
141 | {
142 | member = view_as(index);
143 | break;
144 | }
145 | index = -1;
146 | }
147 |
148 | // Create a new index if required
149 | if (index == -1)
150 | member = DynamicObject();
151 |
152 | // Initial
153 | member.Initialise(plugin, blocksize, startsize, persistent);
154 |
155 | // Return the index
156 | return member.Index;
157 | }
158 |
159 | stock bool _Dynamic_Dispose(DynamicObject dynamic, bool disposemembers, bool reuse=false, int startsize=0, bool fromnative=true)
160 | {
161 | if (!_Dynamic_IsValid(dynamic.Index, false, fromnative))
162 | return false;
163 |
164 | int blocksize = dynamic.BlockSize;
165 |
166 | // Dispose of child members if disposemembers is set
167 | if (disposemembers)
168 | {
169 | ArrayList data = dynamic.Data;
170 | int count = dynamic.MemberCount;
171 | DynamicOffset offset;
172 | DynamicObject disposableobject;
173 | Handle disposablehandle;
174 |
175 | Dynamic_MemberType membertype;
176 |
177 | for (int i = 0; i < count; i++)
178 | {
179 | offset = _Dynamic_GetMemberOffsetByIndex(dynamic, i);
180 | membertype = _Dynamic_GetMemberDataType(data, offset.Index, offset.Cell, blocksize);
181 |
182 | if (membertype == DynamicType_Dynamic)
183 | {
184 | disposableobject = view_as(_Dynamic_GetMemberDataInt(data, offset.Index, offset.Cell, blocksize));
185 | if (!disposableobject.IsValid(false))
186 | continue;
187 |
188 | // Check if member hasnt been referenced to another object
189 | if (disposableobject.Parent == dynamic)
190 | _Dynamic_Dispose(disposableobject, true);
191 | }
192 | else if (membertype == DynamicType_Handle)
193 | {
194 | disposablehandle = view_as(_Dynamic_GetMemberDataInt(data, offset.Index, offset.Cell, blocksize));
195 | _Dynamic_SetMemberDataInt(data, offset.Index, offset.Cell, blocksize, 0);
196 | CloseHandle(disposablehandle);
197 | }
198 | }
199 | }
200 |
201 | // Close dynamic object array handles
202 | dynamic.Dispose(reuse);
203 |
204 | if (reuse)
205 | {
206 | // Reset the dynamic object so it can be used straight
207 | dynamic.Reset();
208 | return true;
209 | }
210 |
211 | // Remove all indicies from the end of the array which are empty (trimend array)
212 | int index = dynamic.Index;
213 | if (index + 1 == s_CollectionSize)
214 | {
215 | RemoveFromArray(s_Collection, index);
216 | s_CollectionSize--;
217 |
218 | for (int i = index - 1; i >= 0; i--)
219 | {
220 | if (s_Collection.Get(i, Dynamic_Index) != Invalid_Dynamic_Object)
221 | break;
222 |
223 | RemoveFromArray(s_Collection, i);
224 | s_CollectionSize--;
225 | }
226 | }
227 | else
228 | {
229 | // Mark the index as diposed and report the free index for reusage
230 | PushStackCell(s_FreeIndicies, dynamic);
231 | }
232 | return true;
233 | }
234 |
235 | stock void _Dynamic_CollectGarbage()
236 | {
237 | // Dispose all objects owned by terminated plugins
238 | DynamicObject dynamic;
239 | for (int i = MAXPLAYERS; i < s_CollectionSize; i++)
240 | {
241 | dynamic = view_as(i);
242 |
243 | // Skip disposed objects
244 | if (!dynamic.IsValid(false))
245 | continue;
246 |
247 | // Skip persistent objects
248 | if (dynamic.Persistent)
249 | continue;
250 |
251 | // Validate owner plugin is still loaded
252 | if (!_Dynamic_Plugins_IsLoaded(dynamic.OwnerPlugin))
253 | {
254 | dynamic.Dispose(false);
255 | continue;
256 | }
257 |
258 | switch(GetPluginStatus(dynamic.OwnerPluginHandle))
259 | {
260 | case Plugin_Error, Plugin_Failed:
261 | {
262 | dynamic.Dispose(false);
263 | }
264 | }
265 | }
266 | }
267 |
268 | stock bool _Dynamic_ResetObject(DynamicObject dynamic, bool disposemembers, int blocksize=0, int startsize=0)
269 | {
270 | if (!dynamic.IsValid(true))
271 | return false;
272 |
273 | if (blocksize == 0)
274 | blocksize = dynamic.BlockSize;
275 |
276 | return _Dynamic_Dispose(dynamic, disposemembers, true, startsize);
277 | }
278 |
279 | stock Handle _Dynamic_GetOwnerPlugin(DynamicObject dynamic)
280 | {
281 | if (!dynamic.IsValid(true))
282 | return null;
283 |
284 | return dynamic.OwnerPluginHandle;
285 | }
286 |
287 | stock bool _Dynamic_SetName(DynamicObject dynamic, const char[] objectname, bool replace)
288 | {
289 | if (!dynamic.IsValid(true))
290 | return false;
291 |
292 | return s_tObjectNames.SetValue(objectname, dynamic, replace);
293 | }
294 |
295 | stock DynamicObject _Dynamic_FindByName(const char[] objectname)
296 | {
297 | // Find name in object names trie
298 | DynamicObject dynamic;
299 | if (!s_tObjectNames.GetValue(objectname, dynamic))
300 | return INVALID_DYNAMIC_OBJECT;
301 |
302 | // Check object is still valid
303 | if (!dynamic.IsValid(true))
304 | return INVALID_DYNAMIC_OBJECT;
305 |
306 | // Return object index
307 | return dynamic;
308 | }
309 |
310 | stock DynamicObject _Dynamic_GetParent(DynamicObject dynamic)
311 | {
312 | if (!dynamic.IsValid(true))
313 | return INVALID_DYNAMIC_OBJECT;
314 |
315 | return dynamic.Parent;
316 | }
317 |
318 | stock bool _Dynamic_GetName(DynamicObject dynamic, char[] buffer, int length)
319 | {
320 | if (!dynamic.IsValid(true))
321 | return false;
322 |
323 | DynamicObject parent = dynamic.Parent;
324 | if (!parent.IsValid(false))
325 | return false;
326 |
327 | DynamicOffset offset = dynamic.ParentOffset;
328 | if (offset == INVALID_DYNAMIC_OFFSET)
329 | return false;
330 |
331 | _Dynamic_GetMemberNameByOffset(parent, offset, buffer, length);
332 | return true;
333 | }
334 |
335 | stock bool _Dynamic_GetPersistence(DynamicObject dynamic)
336 | {
337 | if (!dynamic.IsValid(true))
338 | return false;
339 |
340 | return dynamic.Persistent;
341 | }
342 |
343 | stock bool _Dynamic_SetPersistence(DynamicObject dynamic, bool value)
344 | {
345 | if (!dynamic.IsValid(true))
346 | return false;
347 |
348 | dynamic.Persistent = value;
349 | return true;
350 | }
351 |
352 | stock bool _Dynamic_IsValid(int index, bool throwerror=false, bool fromnative=true)
353 | {
354 | // Check if object index is valid
355 | if (index < 0 || index >= s_CollectionSize)
356 | {
357 | if (throwerror)
358 | {
359 | if (fromnative)
360 | ThrowNativeError(SP_ERROR_NATIVE, "Unable to access dynamic handle %d", index);
361 | else
362 | ThrowError("Unable to access dynamic handle %d", index);
363 | }
364 | return false;
365 | }
366 |
367 | if (s_Collection.Get(index, Dynamic_Index) == -1)
368 | {
369 | if (throwerror)
370 | {
371 | if (fromnative)
372 | ThrowNativeError(SP_ERROR_NATIVE, "Tried to access disposed dynamic handle %d", index);
373 | else
374 | ThrowError("Tried to access disposed dynamic handle %d", index);
375 | }
376 | return false;
377 | }
378 |
379 | return true;
380 | }
381 |
382 | stock DynamicOffset _Dynamic_GetMemberOffset(DynamicObject dynamic, const char[] membername)
383 | {
384 | if (!dynamic.IsValid(true))
385 | return INVALID_DYNAMIC_OFFSET;
386 |
387 | // Find and return offset for member
388 | StringMap offsets = dynamic.Offsets;
389 | DynamicOffset offset;
390 | if (GetTrieValue(offsets, membername, offset))
391 | return offset;
392 |
393 | // No offset found
394 | return INVALID_DYNAMIC_OFFSET;
395 | }
396 |
397 | stock bool _Dynamic_GetMemberDataOffset(DynamicObject dynamic, const char[] membername, bool create, DynamicOffset &offset, Dynamic_MemberType type, int stringlength=0)
398 | {
399 | // Find and return member offset
400 | if (dynamic.Offsets.GetValue(membername, offset))
401 | return true;
402 |
403 | // Return false if offset was not found
404 | if (!create)
405 | return false;
406 |
407 | // We need to create a new member
408 | _Dynamic_CreateMemberOffset(dynamic, offset, membername, type, stringlength);
409 | return true;
410 | }
411 |
412 | stock int _Dynamic_CreateMemberOffset(DynamicObject dynamic, DynamicOffset &offset, const char[] membername, Dynamic_MemberType type, int stringlength=0, StringMap offsets=null)
413 | {
414 | int memberindex;
415 | ArrayList membernames = dynamic.MemberNames;
416 |
417 | // Increment member count
418 | dynamic.MemberCount++;
419 |
420 | // Get offsets if required
421 | if (offsets == null)
422 | offsets = dynamic.Offsets;
423 |
424 | offset = dynamic.NextOffset;
425 | offsets.SetValue(membername, offset);
426 | memberindex = membernames.PushString(membername);
427 | membernames.Set(memberindex, offset, g_iDynamic_MemberLookup_Offset);
428 | ArrayList data = dynamic.Data;
429 | int blocksize = dynamic.BlockSize;
430 |
431 | if (type == DynamicType_String)
432 | {
433 | if (stringlength == 0)
434 | {
435 | ThrowNativeError(SP_ERROR_NATIVE, "You must set a strings length when you initialise it");
436 | return false;
437 | }
438 |
439 | _Dynamic_ExpandIfRequired(data, offset, blocksize, ByteCountToCells(stringlength));
440 | _Dynamic_SetMemberDataType(data, offset, blocksize, type);
441 | _Dynamic_SetMemberStringLength(data, offset, blocksize, stringlength);
442 | dynamic.NextOffset = offset.Clone(blocksize, 3 + ByteCountToCells(stringlength));
443 | return memberindex;
444 | }
445 | else if (type == DynamicType_Vector)
446 | {
447 | _Dynamic_ExpandIfRequired(data, offset, blocksize, 3);
448 | _Dynamic_SetMemberDataType(data, offset, blocksize, type);
449 | dynamic.NextOffset = offset.Clone(blocksize, 4);
450 | return memberindex;
451 | }
452 | else
453 | {
454 | _Dynamic_ExpandIfRequired(data, offset, blocksize, 1);
455 | _Dynamic_SetMemberDataType(data, offset, blocksize, type);
456 | dynamic.NextOffset = offset.Clone(blocksize, 2);
457 | return memberindex;
458 | }
459 | }
460 |
461 | stock bool _Dynamic_RecalculateOffset(int &position, int &offset, int blocksize, bool aschar=false)
462 | {
463 | // Calculate offset into internal array index and cell position
464 | if (aschar)
465 | blocksize *= 4;
466 |
467 | while (offset < 0)
468 | {
469 | offset+=blocksize;
470 | position--;
471 | }
472 | while (offset >= blocksize)
473 | {
474 | offset-=blocksize;
475 | position++;
476 | }
477 | return true;
478 | }
479 |
480 | stock void _Dynamic_ExpandIfRequired(ArrayList data, DynamicOffset offset, int blocksize, int length=1)
481 | {
482 | // Used to expand internal object arrays by the _Dynamic_GetMemberDataOffset method
483 | int index = offset.Index;
484 | int cell = offset.Cell + length + 1;
485 | _Dynamic_RecalculateOffset(index, cell, blocksize);
486 |
487 | // Expand array if offset is outside of array bounds
488 | // Performance: Get array size should be replaced with an size counter
489 | // The above needs a really good think!!
490 | int size = GetArraySize(data);
491 | while (size <= index)
492 | {
493 | // -1 is the default value of unused memory to allow parenting via Set/PushObject
494 | int val = PushArrayCell(data, INVALID_DYNAMIC_OBJECT);
495 | size++;
496 |
497 | // This was added to ensure all memory is set to -1 for a parent resetting
498 | // -> this might impact performance and potentially cause parent resetting to be redone
499 | for (int block = 1; block < blocksize; block++)
500 | {
501 | SetArrayCell(data, val, INVALID_DYNAMIC_OBJECT, block);
502 | }
503 | }
504 | }
505 |
506 | stock Dynamic_MemberType _Dynamic_GetMemberDataType(ArrayList data, int position, int offset, int blocksize)
507 | {
508 | return data.Get(position, offset);
509 | }
510 |
511 | stock void _Dynamic_SetMemberDataType(ArrayList data, DynamicOffset offset, int blocksize, Dynamic_MemberType type)
512 | {
513 | // Set member type
514 | SetArrayCell(data, offset.Index, type, offset.Cell);
515 | }
516 |
517 | stock int _Dynamic_GetCollectionSize()
518 | {
519 | return s_CollectionSize;
520 | }
521 |
522 | stock int _Dynamic_GetMemberCount(DynamicObject dynamic)
523 | {
524 | if (!dynamic.IsValid(true))
525 | return 0;
526 |
527 | return dynamic.MemberCount;
528 | }
529 |
530 | stock DynamicOffset _Dynamic_GetMemberOffsetByIndex(DynamicObject dynamic, int memberindex)
531 | {
532 | if (!dynamic.IsValid(true))
533 | return INVALID_DYNAMIC_OFFSET;
534 |
535 | return dynamic.MemberNames.Get(memberindex, g_iDynamic_MemberLookup_Offset);
536 | }
537 |
538 | stock Dynamic_MemberType _Dynamic_GetMemberType(DynamicObject dynamic, const char[] membername)
539 | {
540 | if (!dynamic.IsValid(true))
541 | return DynamicType_Unknown;
542 |
543 | DynamicOffset offset;
544 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_Unknown))
545 | return DynamicType_Unknown;
546 |
547 | return _Dynamic_GetMemberDataType(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
548 | }
549 |
550 | stock Dynamic_MemberType _Dynamic_GetMemberTypeByOffset(DynamicObject dynamic, DynamicOffset offset)
551 | {
552 | if (!dynamic.IsValid(true))
553 | return DynamicType_Unknown;
554 |
555 | return _Dynamic_GetMemberDataType(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
556 | }
557 |
558 | stock bool _Dynamic_GetMemberNameByIndex(DynamicObject dynamic, int memberindex, char[] buffer, int length)
559 | {
560 | if (!dynamic.IsValid(true))
561 | return false;
562 |
563 | if (memberindex >= dynamic.MemberCount)
564 | {
565 | buffer[0] = '\0';
566 | return false;
567 | }
568 |
569 | GetArrayString(dynamic.MemberNames, memberindex, buffer, length);
570 | return true;
571 | }
572 |
573 | stock bool _Dynamic_GetMemberNameByOffset(DynamicObject dynamic, DynamicOffset offset, char[] buffer, int length)
574 | {
575 | if (!dynamic.IsValid(true))
576 | return false;
577 |
578 | ArrayList membernames = dynamic.MemberNames;
579 | int membercount = membernames.Length;
580 |
581 | for (int i = 0; i < membercount; i++)
582 | {
583 | if (membernames.Get(i, g_iDynamic_MemberLookup_Offset) == offset)
584 | {
585 | membernames.GetString(i, buffer, length);
586 | return true;
587 | }
588 | }
589 | return false;
590 | }
591 |
592 | stock bool _Dynamic_SortMembers(DynamicObject dynamic, SortOrder order)
593 | {
594 | if (!dynamic.IsValid(true))
595 | return false;
596 |
597 | int count = dynamic.MemberCount;
598 | if (count == 0)
599 | return false;
600 |
601 | // Dont bother sorting if there are no members
602 | ArrayList members = dynamic.MemberNames;
603 | StringMap offets = dynamic.Offsets;
604 | char[][] membernames = new char[count][DYNAMIC_MEMBERNAME_MAXLEN];
605 | DynamicOffset offset;
606 |
607 | // Get each membername into a string array
608 | for (int memberindex = 0; memberindex < count; memberindex++)
609 | GetArrayString(members, memberindex, membernames[memberindex], DYNAMIC_MEMBERNAME_MAXLEN);
610 |
611 | // Sort member names
612 | SortStrings(membernames, count, order);
613 |
614 | // Clear current member index lookup arrays
615 | ClearArray(members);
616 |
617 | // Rebuild member lookup arrays based on sorted membernames
618 | for (int memberindex = 0; memberindex < count; memberindex++)
619 | {
620 | if (!offets.GetValue(membernames[memberindex], offset))
621 | continue;
622 |
623 | memberindex = PushArrayString(members, membernames[memberindex]);
624 | SetArrayCell(members, memberindex, offset, g_iDynamic_MemberLookup_Offset);
625 | }
626 | return true;
627 | }
628 |
629 | stock Collection _Dynamic_FindByMemberValue(DynamicObject dynamic, DynamicObject params)
630 | {
631 | if (!dynamic.IsValid(true))
632 | return null;
633 |
634 | // Iterate through child dynamic objects
635 | int membercount = dynamic.MemberCount;
636 | if (membercount == 0)
637 | return null;
638 |
639 | // All the required stuff
640 | Collection results = new Collection();
641 | DynamicObject member;
642 | int paramcount = params.MemberCount;
643 | bool matched = true;
644 | int resultcount = 0;
645 | DynamicOffset memberoffset;
646 |
647 | // Compile params
648 | char[][] param_name = new char[paramcount][DYNAMIC_MEMBERNAME_MAXLEN];
649 | Dynamic_MemberType[] param_type = new Dynamic_MemberType[paramcount];
650 | DynamicObject[] param_object = new DynamicObject[paramcount];
651 | DynamicOffset[] param_offset = new DynamicOffset[paramcount];
652 | int[] param_length = new int[paramcount];
653 | int[] param_operator = new int[paramcount];
654 | int param_maxlength;
655 | DynamicObject paramater;
656 | for (int i=0; i param_maxlength)
669 | param_maxlength = param_length[i];
670 | }
671 | }
672 | char[] paramvalue = new char[param_maxlength];
673 |
674 | // Loop members in object
675 | for (int i = 0; i < membercount; i++)
676 | {
677 | // Get member offset and check its a dynamic object
678 | memberoffset = _Dynamic_GetMemberOffsetByIndex(dynamic, i);
679 | if (_Dynamic_GetMemberTypeByOffset(dynamic, memberoffset) != DynamicType_Dynamic)
680 | continue;
681 |
682 | // Get member and check its valid
683 | member = _Dynamic_GetDynamicByOffset(dynamic, memberoffset);
684 | if (!member.IsValid(false))
685 | continue;
686 |
687 | // Iterate through each param and check for matches
688 | matched = true;
689 | for (int param=0; param < paramcount; param++)
690 | {
691 | switch (param_type[param])
692 | {
693 | case DynamicType_String:
694 | {
695 | _Dynamic_GetStringByOffset(param_object[param], param_offset[param], paramvalue, param_length[param]);
696 | memberoffset = _Dynamic_GetMemberOffset(member, param_name[param]);
697 |
698 | switch(param_operator[param])
699 | {
700 | case DynamicOperator_Equals:
701 | {
702 | if (!_Dynamic_CompareStringByOffset(member, memberoffset, paramvalue, true))
703 | {
704 | matched = false;
705 | break;
706 | }
707 | }
708 | case DynamicOperator_NotEquals:
709 | {
710 | if (_Dynamic_CompareStringByOffset(member, memberoffset, paramvalue, true))
711 | {
712 | matched = false;
713 | break;
714 | }
715 | }
716 | default:
717 | {
718 | ThrowError("DynamicOperator %d is not yet supported", param_operator[param]);
719 | return null;
720 | }
721 | }
722 | }
723 | default:
724 | {
725 | ThrowError("Dynamic_MemberType %d is not yet supported", param_type[param]);
726 | return null;
727 | }
728 | }
729 | }
730 |
731 | // Check result
732 | if (!matched)
733 | continue;
734 |
735 | results.Push(member);
736 | resultcount++;
737 | }
738 |
739 | if (resultcount == 0)
740 | {
741 | delete results;
742 | return null;
743 | }
744 |
745 | return results;
746 | }
--------------------------------------------------------------------------------
/scripting/dynamic/examples/001-the_dynamic_lifecycle/dynamic-example.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #pragma newdecls required
3 | #pragma semicolon 1
4 |
5 | public void OnPluginStart()
6 | {
7 | // Creating a dynamic object
8 | Dynamic dynamic = Dynamic();
9 |
10 | // You must dispose of your dynamic objects!
11 | dynamic.Dispose();
12 |
13 | // You may want to set your reference to invalid
14 | dynamic = INVALID_DYNAMIC_OBJECT;
15 |
16 | // Sometimes you need to check if an object is still valid
17 | if (!dynamic.IsValid)
18 | dynamic = Dynamic();
19 |
20 | // What if you want to reset an object and keep the reference
21 | dynamic.Reset();
22 |
23 | // Dont forget to dispose!
24 | dynamic.Dispose();
25 | }
--------------------------------------------------------------------------------
/scripting/dynamic/examples/002-accessing_dynamic_members/dynamic-example.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #pragma newdecls required
3 | #pragma semicolon 1
4 |
5 | bool bvalue = false;
6 | Dynamic dvalue = INVALID_DYNAMIC_OBJECT;
7 | float fvalue = 0.0;
8 | Handle hvalue = null;
9 | int ivalue = 0;
10 | char svalue[16] = "";
11 | float vvalue[3] = {0.0, 0.0, 0.0};
12 |
13 | public void OnPluginStart()
14 | {
15 | Dynamic dynamic = Dynamic();
16 |
17 | dynamic.SetBool("Bool", false);
18 | dynamic.SetDynamic("Dynamic", INVALID_DYNAMIC_OBJECT);
19 | dynamic.SetFloat("Float", 0.0);
20 | dynamic.SetHandle("Handle", null);
21 | dynamic.SetInt("Int", 0);
22 | dynamic.SetString("String", "");
23 | dynamic.SetVector("Vector", NULL_VECTOR);
24 |
25 | bvalue = dynamic.GetBool("Bool");
26 | dvalue = dynamic.GetDynamic("Dynamic");
27 | fvalue = dynamic.GetFloat("Float");
28 | hvalue = dynamic.GetHandle("Handle");
29 | ivalue = dynamic.GetInt("Int");
30 | dynamic.GetString("String", svalue, sizeof(svalue));
31 | dynamic.GetVector("Vector", vvalue);
32 |
33 | bvalue = dynamic.GetBool("Bool", bvalue);
34 | fvalue = dynamic.GetFloat("Float", fvalue);
35 | ivalue = dynamic.GetInt("Int", ivalue);
36 |
37 | dynamic.Dispose();
38 | }
--------------------------------------------------------------------------------
/scripting/dynamic/examples/003-type_conversion/dynamic-example.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #pragma newdecls required
3 | #pragma semicolon 1
4 |
5 | public void OnPluginStart()
6 | {
7 | // Creating a dynamic object
8 | Dynamic dynamic = Dynamic();
9 |
10 | // Dynamic will convert member types automatically based on
11 | // the type used when they were first set.
12 |
13 | // Lets show each types setter
14 | dynamic.SetBool("Bool", false);
15 | dynamic.SetDynamic("Dynamic", INVALID_DYNAMIC_OBJECT);
16 | dynamic.SetFloat("Float", 77.7);
17 | dynamic.SetHandle("Handle", null);
18 | dynamic.SetInt("Int", 66);
19 | dynamic.SetString("String", "Hello!");
20 | dynamic.SetVector("Vector", NULL_VECTOR);
21 |
22 | // Each member above has it's type set because the first setter
23 | // determines the members lifetime type.
24 |
25 | // Lets give some examples
26 | dynamic.SetString("Bool", "True"); // Bool == bool:true
27 | dynamic.GetFloat("Int"); // returns float:66.0
28 | dynamic.GetInt("Float"); // returns int:78 (rounds to closest whole number)
29 |
30 | // Bool, Float, Int and String can all be all freely type
31 | // converted between eachother.
32 |
33 | // Dynamic and Int are convertable with eachother
34 |
35 | // Handle is not convertable with any other type
36 |
37 | // Vector and String are convertable with eachother
38 |
39 | // Any unconvertable types will receive an
40 | // `Unsupported member datatype` error
41 |
42 | // Dont forget to dispose!
43 | dynamic.Dispose();
44 | }
--------------------------------------------------------------------------------
/scripting/dynamic/examples/999-old/basics.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #pragma newdecls required
3 | #pragma semicolon 1
4 |
5 | public void OnPluginStart()
6 | {
7 | // Creating dynamic objects is straight foward
8 | Dynamic someobj = Dynamic();
9 |
10 | // Setting integers, floats and booleans also
11 | someobj.SetInt("someint", 1);
12 | someobj.SetFloat("somefloat", 512.7);
13 | someobj.SetBool("somebool", true);
14 |
15 | // When dealing with strings...
16 | // you want to set an appropriate length if the value will change
17 | someobj.SetString("somestring", "What did you say?", 64);
18 |
19 | // If the value of a string will never change you might as well
20 | someobj.SetString("our_planets_name", "Earth");
21 |
22 | // Getting integers, floats and booleans is also straight foward
23 | int someint = someobj.GetInt("someint");
24 | float somefloat = someobj.GetFloat("somefloat");
25 | bool somebool = someobj.GetBool("somebool");
26 |
27 | // You can also include default values in case a member doesn't exist
28 | someint = someobj.GetInt("someint1", -1);
29 | somefloat = someobj.GetFloat("somefloat2", 7.25);
30 | somebool = someobj.GetBool("somebool2", false);
31 |
32 | // And the normal "extra" stuff to get a string in sourcespawn
33 | char somestring[64];
34 | someobj.GetString("somestring", somestring, sizeof(somestring));
35 |
36 | // You can also get an exact string by size
37 | int length = someobj.GetStringLength("our_planets_name");
38 | char[] our_planets_name = new char[length];
39 | someobj.GetString("our_planets_name", our_planets_name, length);
40 |
41 | // Dynamic supports type conversion!!!!!!!!!!!
42 | someint = someobj.GetInt("somefloat"); // rounds to floor
43 | somefloat = someobj.GetFloat("someint");
44 | someobj.GetString("somefloat", somestring, sizeof(somestring));
45 | someobj.GetString("somebool", somestring, sizeof(somestring));
46 |
47 | // You can even set dynamic objects within themselves
48 | Dynamic anotherobj = Dynamic();
49 | anotherobj.SetInt("someint", 128);
50 | someobj.SetObject("anotherobj", anotherobj);
51 |
52 | // You can also get and set Handles
53 | someobj.SetHandle("somehandle", CreateArray());
54 | Handle somehandle = someobj.GetHandle("somehandle");
55 | PushArrayCell(somehandle, 1);
56 |
57 | // Vectors are also supported like so
58 | float somevec[3] = {1.0, 2.0, 3.0};
59 | someobj.SetVector("somevec", NULL_VECTOR);
60 | someobj.SetVector("somevec", somevec);
61 | someobj.GetVector("somevec", somevec);
62 |
63 | // You can name a dynamic object
64 | someobj.SetName("someobj");
65 |
66 | // So another plugin can access it like so
67 | someobj = Dynamic.FindByName("someobj");
68 |
69 | // You can also sort members within a dynamic object by name
70 | someobj.SortMembers(Sort_Ascending);
71 |
72 | // Dynamic assigns player settings which can be accessed like so
73 | int client = 1;
74 | Dynamic settings = Dynamic.GetPlayerSettings(client);
75 |
76 | // You can also access dynamic player settings like this
77 | settings = view_as(client);
78 |
79 | // Dynamic also provides a global settings object
80 | settings = Dynamic.GetSettings();
81 |
82 | // You can also access the global settings object like this
83 | settings = view_as(0);
84 |
85 | // This is to a stop compilation warning
86 | settings.SetInt("someint", 1);
87 |
88 | // Sometimes you might want to iterate through members to accomplish stuff
89 | int count = someobj.MemberCount;
90 | int memberoffset;
91 | char membername[DYNAMIC_MEMBERNAME_MAXLEN];
92 |
93 | PrintToServer("GETTING ALL DYNAMIC OBJECT MEMBERS");
94 | PrintToServer(" > someobj.MemberCount=%d", someobj.MemberCount);
95 | for (int i = 0; i < count; i++)
96 | {
97 | memberoffset = someobj.GetMemberOffsetByIndex(i);
98 | someobj.GetMemberNameByIndex(i, membername, sizeof(membername));
99 |
100 | switch (someobj.GetMemberType(memberoffset))
101 | {
102 | case DynamicType_Int:
103 | {
104 | someint = someobj.GetIntByOffset(memberoffset);
105 | PrintToServer("[%d] someobj.%s = %d", memberoffset, membername, someint);
106 | }
107 | case DynamicType_Bool:
108 | {
109 | somebool = someobj.GetBoolByOffset(memberoffset);
110 | PrintToServer("[%d] someobj.%s = %d", memberoffset, membername, somebool);
111 | }
112 | case DynamicType_Float:
113 | {
114 | somefloat = someobj.GetFloatByOffset(memberoffset);
115 | PrintToServer("[%d] someobj.%s = %f", memberoffset, membername, somefloat);
116 | }
117 | case DynamicType_String:
118 | {
119 | someobj.GetStringByOffset(memberoffset, somestring, sizeof(somestring));
120 | PrintToServer("[%d] someobj.%s = '%s'", memberoffset, membername, somestring);
121 | }
122 | case DynamicType_Object:
123 | {
124 | anotherobj = someobj.GetObjectByOffset(memberoffset);
125 | someint = anotherobj.GetInt("someint");
126 | PrintToServer("[%d] .someobj.%s.someint = %d", memberoffset, membername, someint);
127 | }
128 | case DynamicType_Handle:
129 | {
130 | somehandle = someobj.GetHandleByOffset(memberoffset);
131 | PrintToServer("[%d] .someobj.%s = %d", memberoffset, membername, somehandle);
132 | }
133 | case DynamicType_Vector:
134 | {
135 | someobj.GetVectorByOffset(memberoffset, somevec);
136 | PrintToServer("[%d] .someobj.%s = {%f, %f, %f}", memberoffset, membername, somevec[0], somevec[1], somevec[2]);
137 | }
138 | }
139 | }
140 |
141 | // Sometimes you may want to listen to member changes within a callback
142 | PrintToServer("CALLBACK TESTING MESSAGES");
143 | someobj.HookChanges(OnDynamicMemberChanged);
144 | someobj.SetInt("someint", 256);
145 | someobj.SetFloat("somefloat", -12.04);
146 | someobj.SetBool("somebool", false);
147 | someobj.SetString("somestring", "ye sure moite");
148 | someobj.SetVector("somevec", view_as({2.0, 3.0, 4.0}));
149 |
150 | // You MUST! dispose your dynamic objects when your done.
151 | anotherobj.Dispose();
152 |
153 | // You can also dispose of any disposable members like this
154 | // -> This includes auto closure of Handle datatypes
155 | someobj.Dispose(true);
156 | }
157 |
158 | public void OnDynamicMemberChanged(Dynamic obj, int offset, const char[] member, Dynamic_MemberType type)
159 | {
160 | switch (type)
161 | {
162 | case DynamicType_Int:
163 | {
164 | PrintToServer("[%d] obj.%s = %d", offset, member, obj.GetIntByOffset(offset));
165 | }
166 | case DynamicType_Float:
167 | {
168 | PrintToServer("[%d] obj.%s = %f", offset, member, obj.GetFloatByOffset(offset));
169 | }
170 | case DynamicType_Bool:
171 | {
172 | PrintToServer("[%d] obj.%s = %d", offset, member, obj.GetBoolByOffset(offset));
173 | }
174 | case DynamicType_String:
175 | {
176 | char somestring[64];
177 | obj.GetStringByOffset(offset, somestring, sizeof(somestring));
178 | PrintToServer("[%d] obj.%s = '%s'", offset, member, somestring);
179 | }
180 | case DynamicType_Vector:
181 | {
182 | char somestring[64];
183 | obj.GetStringByOffset(offset, somestring, sizeof(somestring));
184 | PrintToServer("[%d] obj.%s = %s", offset, member, somestring);
185 | }
186 | }
187 | }
--------------------------------------------------------------------------------
/scripting/dynamic/examples/999-old/collections/collection.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #include "person.inc"
3 | #include "people.inc"
4 | #pragma newdecls required
5 | #pragma semicolon 1
6 |
7 | public void OnPluginStart()
8 | {
9 | // New people collection as defined in `people.inc`
10 | People people = new People();
11 |
12 | // New person as defined in `person.inc`
13 | Person person = Person();
14 | person.SetName("Neuro Toxin");
15 | person.Age = 32;
16 | person.Height = 6.4;
17 | person.IsAlive = true;
18 |
19 | // Add person to people
20 | people.AddItem(person);
21 |
22 | // Lets add another person
23 | person = Person();
24 | person.SetName("Nouse");
25 | person.Age = 21;
26 | person.Height = 5.7;
27 | person.IsAlive = true;
28 | people.AddItem(person);
29 |
30 | // Iterating people in the collection
31 | for (int index = 0; index < people.Count; index++)
32 | {
33 | person = people.Items(index);
34 | if (!person.IsValid)
35 | continue;
36 |
37 | char name[1024];
38 | person.GetName(name, sizeof(name));
39 |
40 | PrintToServer("Found Person {Name:'%s', Age:%d, Height:%f, IsAlive:%d}",
41 | name, person.Age, person.Height, person.IsAlive);
42 | }
43 |
44 | // Always clean up when your done
45 | people.Dispose();
46 | }
47 |
--------------------------------------------------------------------------------
/scripting/dynamic/examples/999-old/collections/people.inc:
--------------------------------------------------------------------------------
1 | #if defined _dynamic_collection_people
2 | #endinput
3 | #endif
4 | #define _dynamic_collection_people
5 |
6 | /*
7 | This example demonstrates how to easily create a collection
8 | methodmap by inheriting Dynamic.
9 | */
10 |
11 | // We inherit Dynamic's collection methodmap
12 | methodmap People < Collection
13 | {
14 | public People()
15 | {
16 | // Return a new Dynamic Collection
17 | return view_as(new Collection());
18 | }
19 |
20 | // Override Items method to return type Person
21 | public Person Items(int index)
22 | {
23 | return view_as(this.Items(index));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/scripting/dynamic/examples/999-old/collections/person.inc:
--------------------------------------------------------------------------------
1 | #if defined _dynamic_methodmap_person
2 | #endinput
3 | #endif
4 | #define _dynamic_methodmap_person
5 |
6 | /*
7 | This example demonstrates how to easily store data for your
8 | own methodmaps by inherting Dynamic
9 | */
10 |
11 | methodmap Person < Dynamic
12 | {
13 | public Person()
14 | {
15 | Dynamic person = Dynamic();
16 | return view_as(person);
17 | }
18 |
19 | property int Age
20 | {
21 | public get()
22 | {
23 | return this.GetInt("Age", 0);
24 | }
25 | public set(int value)
26 | {
27 | this.SetInt("Age", value);
28 | }
29 | }
30 |
31 | property float Height
32 | {
33 | public get()
34 | {
35 | return this.GetFloat("Height", 0.0);
36 | }
37 | public set(float value)
38 | {
39 | this.SetFloat("Height", value);
40 | }
41 | }
42 |
43 | property bool IsAlive
44 | {
45 | public get()
46 | {
47 | return this.GetBool("IsAlive", false);
48 | }
49 | public set(bool value)
50 | {
51 | this.SetBool("IsAlive", value);
52 | }
53 | }
54 |
55 | public bool GetName(char[] buffer, int length)
56 | {
57 | return this.GetString("Name", buffer, length);
58 | }
59 |
60 | public void SetName(const char[] buffer)
61 | {
62 | this.SetString("Name", buffer, 1024);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/scripting/dynamic/examples/999-old/dynamic-classexample.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #pragma newdecls required
4 | #pragma semicolon 1
5 |
6 | public void OnPluginStart()
7 | {
8 | // You can also use Dynamic to back Methodmap properties.
9 | // This is another step towards sourcepawn feeling a bit more OO
10 | // -> Find the methodmap in 'include/dynamic-example.sp'
11 | // -> This class was generated @ 'http://console.aus-tg.com/index.php?page=createdynamicclass'
12 |
13 | // Creating dynamic classes is straight foward
14 | MyClass someobj = MyClass();
15 |
16 | // Setting integers, floats and booleans also
17 | someobj.SomeInt = 1;
18 | someobj.SomeFloat = 512.7;
19 | someobj.SomeBool = true;
20 |
21 | // The strings length is now defined within the class initialiser code
22 | someobj.SetSomeString("What did you say?");
23 |
24 | // Getting integers, floats and booleans is also straight foward
25 | int someint = someobj.SomeInt;
26 | float somefloat = someobj.SomeFloat;
27 | bool somebool = someobj.SomeBool;
28 |
29 | // And the normal "extra" stuff to get a string in sourcespawn
30 | char somestring[64];
31 | someobj.GetSomeString(somestring, 64);
32 |
33 | // You can also get an exact string by size
34 | int length = someobj.GetStringLength("SomeString");
35 | someobj.GetSomeString(somestring, length);
36 |
37 | // Dynamic supports type conversion!!!!!!!!!!!
38 | // -> Type conversion is not possible inside of classes
39 | //someint = someobj.GetInt("somefloat"); // rounds to floor
40 | //somefloat = someobj.GetFloat("someint");
41 | //someobj.GetString("somefloat", somestring, sizeof(somestring));
42 | //someobj.GetString("somebool", somestring, sizeof(somestring));
43 |
44 | // You can even set dynamic objects within themselves
45 | Dynamic anotherobj = Dynamic();
46 | anotherobj.SetInt("someint", 128);
47 | someobj.SomeObject = anotherobj;
48 |
49 | // You can also get and set Handles
50 | someobj.SomeHandle = CreateArray();
51 | Handle somehandle = someobj.SomeHandle;
52 | PushArrayCell(somehandle, 1);
53 |
54 | // Vectors are also supported like so
55 | float somevec[3] = {1.0, 2.0, 3.0};
56 | someobj.SetSomeVector(NULL_VECTOR);
57 | someobj.SetSomeVector(somevec);
58 | someobj.GetSomeVector(somevec);
59 |
60 | // You can name a dynamic object
61 | someobj.SetName("someobj");
62 |
63 | // So another plugin can access it like so
64 | someobj = view_as(Dynamic.FindByName("someobj"));
65 |
66 | // You can also sort members within a dynamic object by name
67 | someobj.SortMembers(Sort_Ascending);
68 |
69 | // Sometimes you might want to iterate through members to accomplish stuff
70 | int count = someobj.MemberCount;
71 | int memberoffset;
72 | char membername[DYNAMIC_MEMBERNAME_MAXLEN];
73 |
74 | PrintToServer("GETTING ALL DYNAMIC OBJECT MEMBERS");
75 | for (int i = 0; i < count; i++)
76 | {
77 | memberoffset = someobj.GetMemberOffsetByIndex(i);
78 | someobj.GetMemberNameByIndex(i, membername, sizeof(membername));
79 |
80 | switch (someobj.GetMemberType(memberoffset))
81 | {
82 | case DynamicType_Int:
83 | {
84 | someint = someobj.GetIntByOffset(memberoffset);
85 | PrintToServer("[%d] someobj.%s = %d", memberoffset, membername, someint);
86 | }
87 | case DynamicType_Bool:
88 | {
89 | somebool = someobj.GetBoolByOffset(memberoffset);
90 | PrintToServer("[%d] someobj.%s = %d", memberoffset, membername, somebool);
91 | }
92 | case DynamicType_Float:
93 | {
94 | somefloat = someobj.GetFloatByOffset(memberoffset);
95 | PrintToServer("[%d] someobj.%s = %f", memberoffset, membername, somefloat);
96 | }
97 | case DynamicType_String:
98 | {
99 | someobj.GetStringByOffset(memberoffset, somestring, sizeof(somestring));
100 | PrintToServer("[%d] someobj.%s = '%s'", memberoffset, membername, somestring);
101 | }
102 | case DynamicType_Object:
103 | {
104 | anotherobj = someobj.GetObjectByOffset(memberoffset);
105 | someint = anotherobj.GetInt("someint");
106 | PrintToServer("[%d] .someobj.%s.someint = %d", memberoffset, membername, someint);
107 | }
108 | case DynamicType_Handle:
109 | {
110 | somehandle = someobj.GetHandleByOffset(memberoffset);
111 | PrintToServer("[%d] .someobj.%s = %d", memberoffset, membername, somehandle);
112 | }
113 | case DynamicType_Vector:
114 | {
115 | someobj.GetVectorByOffset(memberoffset, somevec);
116 | PrintToServer("[%d] .someobj.%s = {%f, %f, %f}", memberoffset, membername, somevec[0], somevec[1], somevec[2]);
117 | }
118 | }
119 | }
120 |
121 | // Sometimes you may want to listen to member changes within a callback
122 | PrintToServer("CALLBACK TESTING MESSAGES");
123 | someobj.HookChanges(OnDynamicMemberChanged);
124 | someobj.SetInt("someint", 256);
125 | someobj.SetFloat("somefloat", -12.04);
126 | someobj.SetBool("somebool", false);
127 | someobj.SetString("somestring", "ye sure moite");
128 | someobj.SetVector("somevec", view_as({2.0, 3.0, 4.0}));
129 |
130 | // You MUST! dispose your dynamic objects when your done.
131 | anotherobj.Dispose();
132 |
133 | // You can also dispose of any disposable members like this
134 | // -> This includes auto closure of Handle datatypes
135 | someobj.Dispose(true);
136 | }
137 |
138 | public void OnDynamicMemberChanged(Dynamic obj, int offset, const char[] member, Dynamic_MemberType type)
139 | {
140 | switch (type)
141 | {
142 | case DynamicType_Int:
143 | {
144 | PrintToServer("[%d] obj.%s = %d", offset, member, obj.GetIntByOffset(offset));
145 | }
146 | case DynamicType_Float:
147 | {
148 | PrintToServer("[%d] obj.%s = %f", offset, member, obj.GetFloatByOffset(offset));
149 | }
150 | case DynamicType_Bool:
151 | {
152 | PrintToServer("[%d] obj.%s = %d", offset, member, obj.GetBoolByOffset(offset));
153 | }
154 | case DynamicType_String:
155 | {
156 | char somestring[64];
157 | obj.GetStringByOffset(offset, somestring, sizeof(somestring));
158 | PrintToServer("[%d] obj.%s = '%s'", offset, member, somestring);
159 | }
160 | case DynamicType_Vector:
161 | {
162 | char somestring[64];
163 | obj.GetStringByOffset(offset, somestring, sizeof(somestring));
164 | PrintToServer("[%d] obj.%s = %s", offset, member, somestring);
165 | }
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/scripting/dynamic/examples/999-old/dynamic-example.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #pragma newdecls required
3 | #pragma semicolon 1
4 |
5 | public void OnPluginStart()
6 | {
7 | // Creating dynamic objects is straight foward
8 | Dynamic someobj = Dynamic();
9 |
10 | // Setting integers, floats and booleans also
11 | someobj.SetInt("someint", 1);
12 | someobj.SetFloat("somefloat", 512.7);
13 | someobj.SetBool("somebool", true);
14 |
15 | // When dealing with strings...
16 | // you want to set an appropriate length if the value will change
17 | someobj.SetString("somestring", "What did you say?", 64);
18 |
19 | // If the value of a string will never change you might as well
20 | someobj.SetString("our_planets_name", "Earth");
21 |
22 | // Getting integers, floats and booleans is also straight foward
23 | int someint = someobj.GetInt("someint");
24 | float somefloat = someobj.GetFloat("somefloat");
25 | bool somebool = someobj.GetBool("somebool");
26 |
27 | // You can also include default values in case a member doesn't exist
28 | someint = someobj.GetInt("someint1", -1);
29 | somefloat = someobj.GetFloat("somefloat2", 7.25);
30 | somebool = someobj.GetBool("somebool2", false);
31 |
32 | // And the normal "extra" stuff to get a string in sourcespawn
33 | char somestring[64];
34 | someobj.GetString("somestring", somestring, sizeof(somestring));
35 |
36 | // You can also get an exact string by size
37 | int length = someobj.GetStringLength("our_planets_name");
38 | char[] our_planets_name = new char[length];
39 | someobj.GetString("our_planets_name", our_planets_name, length);
40 |
41 | // Dynamic supports type conversion!!!!!!!!!!!
42 | someint = someobj.GetInt("somefloat"); // rounds to floor
43 | somefloat = someobj.GetFloat("someint");
44 | someobj.GetString("somefloat", somestring, sizeof(somestring));
45 | someobj.GetString("somebool", somestring, sizeof(somestring));
46 |
47 | // You can even set dynamic objects within themselves
48 | Dynamic anotherobj = Dynamic();
49 | anotherobj.SetInt("someint", 128);
50 | someobj.SetObject("anotherobj", anotherobj);
51 |
52 | // You can also get and set Handles
53 | someobj.SetHandle("somehandle", CreateArray());
54 | Handle somehandle = someobj.GetHandle("somehandle");
55 | PushArrayCell(somehandle, 1);
56 |
57 | // Vectors are also supported like so
58 | float somevec[3] = {1.0, 2.0, 3.0};
59 | someobj.SetVector("somevec", NULL_VECTOR);
60 | someobj.SetVector("somevec", somevec);
61 | someobj.GetVector("somevec", somevec);
62 |
63 | // You can name a dynamic object
64 | someobj.SetName("someobj");
65 |
66 | // So another plugin can access it like so
67 | someobj = Dynamic.FindByName("someobj");
68 |
69 | // You can also sort members within a dynamic object by name
70 | someobj.SortMembers(Sort_Ascending);
71 |
72 | // Dynamic assigns player settings which can be accessed like so
73 | int client = 1;
74 | Dynamic settings = Dynamic.GetPlayerSettings(client);
75 |
76 | // You can also access dynamic player settings like this
77 | settings = view_as(client);
78 |
79 | // Dynamic also provides a global settings object
80 | settings = Dynamic.GetSettings();
81 |
82 | // You can also access the global settings object like this
83 | settings = view_as(0);
84 |
85 | // This is to a stop compilation warning
86 | settings.SetInt("someint", 1);
87 |
88 | // Sometimes you might want to iterate through members to accomplish stuff
89 | int count = someobj.MemberCount;
90 | int memberoffset;
91 | char membername[DYNAMIC_MEMBERNAME_MAXLEN];
92 |
93 | PrintToServer("GETTING ALL DYNAMIC OBJECT MEMBERS");
94 | for (int i = 0; i < count; i++)
95 | {
96 | memberoffset = someobj.GetMemberOffsetByIndex(i);
97 | someobj.GetMemberNameByIndex(i, membername, sizeof(membername));
98 |
99 | switch (someobj.GetMemberType(memberoffset))
100 | {
101 | case DynamicType_Int:
102 | {
103 | someint = someobj.GetIntByOffset(memberoffset);
104 | PrintToServer("[%d] someobj.%s = %d", memberoffset, membername, someint);
105 | }
106 | case DynamicType_Bool:
107 | {
108 | somebool = someobj.GetBoolByOffset(memberoffset);
109 | PrintToServer("[%d] someobj.%s = %d", memberoffset, membername, somebool);
110 | }
111 | case DynamicType_Float:
112 | {
113 | somefloat = someobj.GetFloatByOffset(memberoffset);
114 | PrintToServer("[%d] someobj.%s = %f", memberoffset, membername, somefloat);
115 | }
116 | case DynamicType_String:
117 | {
118 | someobj.GetStringByOffset(memberoffset, somestring, sizeof(somestring));
119 | PrintToServer("[%d] someobj.%s = '%s'", memberoffset, membername, somestring);
120 | }
121 | case DynamicType_Object:
122 | {
123 | anotherobj = someobj.GetObjectByOffset(memberoffset);
124 | someint = anotherobj.GetInt("someint");
125 | PrintToServer("[%d] .someobj.%s.someint = %d", memberoffset, membername, someint);
126 | }
127 | case DynamicType_Handle:
128 | {
129 | somehandle = someobj.GetHandleByOffset(memberoffset);
130 | PrintToServer("[%d] .someobj.%s = %d", memberoffset, membername, somehandle);
131 | }
132 | case DynamicType_Vector:
133 | {
134 | someobj.GetVectorByOffset(memberoffset, somevec);
135 | PrintToServer("[%d] .someobj.%s = {%f, %f, %f}", memberoffset, membername, somevec[0], somevec[1], somevec[2]);
136 | }
137 | }
138 | }
139 |
140 | // Sometimes you may want to listen to member changes within a callback
141 | PrintToServer("CALLBACK TESTING MESSAGES");
142 | someobj.HookChanges(OnDynamicMemberChanged);
143 | someobj.SetInt("someint", 256);
144 | someobj.SetFloat("somefloat", -12.04);
145 | someobj.SetBool("somebool", false);
146 | someobj.SetString("somestring", "ye sure moite");
147 | someobj.SetVector("somevec", view_as({2.0, 3.0, 4.0}));
148 |
149 | // You MUST! dispose your dynamic objects when your done.
150 | anotherobj.Dispose();
151 |
152 | // You can also dispose of any disposable members like this
153 | // -> This includes auto closure of Handle datatypes
154 | someobj.Dispose(true);
155 | }
156 |
157 | public void OnDynamicMemberChanged(Dynamic obj, int offset, const char[] member, Dynamic_MemberType type)
158 | {
159 | switch (type)
160 | {
161 | case DynamicType_Int:
162 | {
163 | PrintToServer("[%d] obj.%s = %d", offset, member, obj.GetIntByOffset(offset));
164 | }
165 | case DynamicType_Float:
166 | {
167 | PrintToServer("[%d] obj.%s = %f", offset, member, obj.GetFloatByOffset(offset));
168 | }
169 | case DynamicType_Bool:
170 | {
171 | PrintToServer("[%d] obj.%s = %d", offset, member, obj.GetBoolByOffset(offset));
172 | }
173 | case DynamicType_String:
174 | {
175 | char somestring[64];
176 | obj.GetStringByOffset(offset, somestring, sizeof(somestring));
177 | PrintToServer("[%d] obj.%s = '%s'", offset, member, somestring);
178 | }
179 | case DynamicType_Vector:
180 | {
181 | char somestring[64];
182 | obj.GetStringByOffset(offset, somestring, sizeof(somestring));
183 | PrintToServer("[%d] obj.%s = %s", offset, member, somestring);
184 | }
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/scripting/dynamic/examples/999-old/keyvalues/using_read_hook.sp:
--------------------------------------------------------------------------------
1 | /*
2 | In this example, you will see how Dynamic can parse a KeyValues file while using a hook
3 | to select the keys you would like to load.
4 | */
5 |
6 | #include
7 | #pragma newdecls required
8 | #pragma semicolon 1
9 |
10 | public void OnPluginStart()
11 | {
12 | // The normal old begining for Dynamic
13 | Dynamic items_game = Dynamic();
14 |
15 | // Lets load `items_game.txt` and parse our hook callback
16 | items_game.ReadKeyValues("scripts/items/items_game.txt", 1024, PK_ReadDynamicKeyValue);
17 |
18 | // The hook has now done it's work and we are left with only a couple of subkeys
19 | Dynamic game_info = items_game.GetObject("game_info");
20 | Dynamic prefabs = items_game.GetObject("prefabs");
21 | Dynamic items = items_game.GetObject("items");
22 | Dynamic attributes = items_game.GetObject("attributes");
23 |
24 | // Lets make a new version of `items_game.txt`
25 | items_game.WriteKeyValues("scripts/items/items_game_dynamic.txt");
26 |
27 | // That's all folks, better clean up my trash!
28 | items_game.Dispose(true);
29 | }
30 |
31 | public Action PK_ReadDynamicKeyValue(Dynamic obj, const char[] member, int depth)
32 | {
33 | // Allow the basekey (depth=0) to be loaded
34 | if (depth == 0)
35 | return Plugin_Continue;
36 |
37 | // Check all subkeys (depth=1) within the basekey (depth=0)
38 | if (depth == 1)
39 | {
40 | // Allow these subkeys (depth=1) in the basekey (depth=0) to load
41 | if (StrEqual(member, "game_info"))
42 | return Plugin_Continue;
43 | if (StrEqual(member, "prefabs"))
44 | return Plugin_Continue;
45 | if (StrEqual(member, "items"))
46 | return Plugin_Continue;
47 | if (StrEqual(member, "attributes"))
48 | return Plugin_Continue;
49 | else
50 | {
51 | // Block all other subkeys (depth=1)
52 | return Plugin_Stop;
53 | }
54 | }
55 |
56 | // Let all subkeys in higher depths load (depth>1)
57 | return Plugin_Continue;
58 | }
--------------------------------------------------------------------------------
/scripting/dynamic/examples/wiki_resources/a_basic_methodmap.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #pragma newdecls required
3 | #pragma semicolon 1
4 |
5 | methodmap MyPluginPlayerInfo < Dynamic
6 | {
7 | public MyPluginPlayerInfo()
8 | {
9 | Dynamic playerinfo = Dynamic();
10 | return view_as(playerinfo);
11 | }
12 |
13 | property int Points
14 | {
15 | public get()
16 | {
17 | return this.GetInt("Points");
18 | }
19 | public set(int value)
20 | {
21 | this.SetInt("Points", value);
22 | }
23 | }
24 |
25 | property float KDR
26 | {
27 | public get()
28 | {
29 | return this.GetFloat("KDR");
30 | }
31 | public set(float value)
32 | {
33 | this.SetFloat("KDR", value);
34 | }
35 | }
36 |
37 | property int Rank
38 | {
39 | public get()
40 | {
41 | return this.GetInt("Rank");
42 | }
43 | public set(int value)
44 | {
45 | this.SetInt("Rank", value);
46 | }
47 | }
48 | }
49 |
50 | public void OnClientConnected(int client)
51 | {
52 | MyPluginPlayerInfo playerinfo = MyPluginPlayerInfo();
53 | playerinfo.Points = 2217;
54 | playerinfo.KDR = 2.69;
55 | playerinfo.Rank = 1;
56 | }
--------------------------------------------------------------------------------
/scripting/dynamic/examples/wiki_resources/accessing_members.sp:
--------------------------------------------------------------------------------
1 | #include
2 | #pragma newdecls required
3 | #pragma semicolon 1
4 |
5 | bool bvalue = false;
6 | Dynamic dvalue = INVALID_DYNAMIC_OBJECT;
7 | float fvalue = 0.0;
8 | Handle hvalue = null;
9 | int ivalue = 0;
10 | char svalue[16] = "";
11 | float vvalue[3] = {0.0, 0.0, 0.0};
12 |
13 | public void OnPluginStart()
14 | {
15 | Dynamic dynamic = Dynamic();
16 |
17 | dynamic.SetBool("Bool", false);
18 | dynamic.SetDynamic("Dynamic", INVALID_DYNAMIC_OBJECT);
19 | dynamic.SetFloat("Float", 0.0);
20 | dynamic.SetHandle("Handle", null);
21 | dynamic.SetInt("Int", 0);
22 | dynamic.SetString("String", "");
23 | dynamic.SetVector("Vector", NULL_VECTOR);
24 |
25 | bvalue = dynamic.GetBool("Bool");
26 | dvalue = dynamic.GetDynamic("Dynamic");
27 | fvalue = dynamic.GetFloat("Float");
28 | hvalue = dynamic.GetHandle("Handle");
29 | ivalue = dynamic.GetInt("Int");
30 | dynamic.GetString("String", svalue, sizeof(svalue));
31 | dynamic.GetVector("Vector", vvalue);
32 |
33 | bvalue = dynamic.GetBool("Bool", bvalue);
34 | fvalue = dynamic.GetFloat("Float", fvalue);
35 | ivalue = dynamic.GetInt("Int", ivalue);
36 |
37 | dynamic.Dispose();
38 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/benchmark/output.txt:
--------------------------------------------------------------------------------
1 | [SM] Preparing benchmark Test...
2 | [SM] Starting Benchmark Tests...
3 | Created 1000 dynamic object(s) in 0.000000 second(s)
4 | Created 100000 dynamic member(s) in 0.164062 second(s)
5 | Read 100000 dynamic member(s) in 0.070312 second(s)
6 | Read 100000 dynamic member(s) using offsets in 0.054687 second(s)
7 | Verified 100000 dynamic member(s) in 0.222656 second(s)
8 | Updated 100000 dynamic member(s) in 0.078125 second(s)
9 | Offset verification with 100000 dynamic member(s) in 0.203125 second(s)
10 | Disposed 1000 dynamic object(s) in 0.023437 second(s)
11 |
12 | [SM] Preparing benchmark Test...
13 | [SM] Starting Benchmark Tests...
14 | Created 1000 dynamic object(s) in 0.000000 second(s)
15 | Created 100000 dynamic member(s) in 0.160156 second(s)
16 | Read 100000 dynamic member(s) in 0.070312 second(s)
17 | Read 100000 dynamic member(s) using offsets in 0.054687 second(s)
18 | Verified 100000 dynamic member(s) in 0.218750 second(s)
19 | Updated 100000 dynamic member(s) in 0.078125 second(s)
20 | Offset verification with 100000 dynamic member(s) in 0.207031 second(s)
21 | Disposed 1000 dynamic object(s) in 0.019531 second(s)
22 |
23 | [SM] Preparing benchmark Test...
24 | [SM] Starting Benchmark Tests...
25 | Created 1000 dynamic object(s) in 0.000000 second(s)
26 | Created 100000 dynamic member(s) in 0.164062 second(s)
27 | Read 100000 dynamic member(s) in 0.070312 second(s)
28 | Read 100000 dynamic member(s) using offsets in 0.054687 second(s)
29 | Verified 100000 dynamic member(s) in 0.222656 second(s)
30 | Updated 100000 dynamic member(s) in 0.078125 second(s)
31 | Offset verification with 100000 dynamic member(s) in 0.203125 second(s)
32 | Disposed 1000 dynamic object(s) in 0.023437 second(s)
--------------------------------------------------------------------------------
/scripting/dynamic/system/commands.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_commands
21 | #endinput
22 | #endif
23 | #define _dynamic_system_commands
24 |
25 | stock void RegisterCommands()
26 | {
27 | RegAdminCmd("sm_dynamic_selftest", OnDynamicSelfTestCommand, ADMFLAG_RCON, "performs a Dynamic SelfTest to verify Dynamic is running properly");
28 | RegAdminCmd("sm_dynamic_handles", OnDynamicHandlesCommand, ADMFLAG_RCON, "displays a Dynamic Handle usage report per plugin");
29 | RegAdminCmd("sm_dynamic_collectgarbage", OnDynamicCollectGarbageCommand, ADMFLAG_RCON, "runs Dynamic's garbage collector");
30 | }
31 |
32 | public Action OnDynamicSelfTestCommand(int client, int args)
33 | {
34 | ReplyToCommand(client, "Dynamic is running a SelfTest...");
35 | RequestFrame(_Dynamic_SelfTest, (client > 0 ? GetClientUserId(client) : 0));
36 | return Plugin_Handled;
37 | }
38 |
39 | public Action OnDynamicHandlesCommand(int client, int args)
40 | {
41 | PrintToConsole(client, "Dynamic is running a HandleUsage report...");
42 | RequestFrame(_Dynamic_HandleUsage, (client > 0 ? GetClientUserId(client) : 0));
43 | return Plugin_Handled;
44 | }
45 |
46 | public Action OnDynamicCollectGarbageCommand(int client, int args)
47 | {
48 | PrintToConsole(client, "Dynamic is starting it's garbage collector...");
49 | _Dynamic_CollectGarbage();
50 | return Plugin_Handled;
51 | }
52 |
--------------------------------------------------------------------------------
/scripting/dynamic/system/datatypes/bool.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_datatypes_bool
21 | #endinput
22 | #endif
23 | #define _dynamic_system_datatypes_bool
24 |
25 | stock bool _GetBool(ArrayList data, int position, int offset, int blocksize, bool defaultvalue)
26 | {
27 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
28 | if (type == DynamicType_Bool)
29 | return view_as(_Dynamic_GetMemberDataInt(data, position, offset, blocksize));
30 | else if (type == DynamicType_Int)
31 | return (_Dynamic_GetMemberDataInt(data, position, offset, blocksize) == 0 ? false : true);
32 | else if (type == DynamicType_Float)
33 | return (_Dynamic_GetMemberDataFloat(data, position, offset, blocksize) == 0.0 ? false : true);
34 | else if (type == DynamicType_String)
35 | {
36 | int length = _Dynamic_GetMemberStringLength(data, position, offset, blocksize);
37 | char[] buffer = new char[length];
38 | _Dynamic_GetMemberDataString(data, position, offset, blocksize, buffer, length);
39 | if (StrEqual(buffer, "false", false))
40 | return false;
41 | else if (StrEqual(buffer, "0"))
42 | return false;
43 |
44 | return true;
45 | }
46 | else if (type == DynamicType_Dynamic)
47 | {
48 | DynamicObject value = view_as(_Dynamic_GetMemberDataInt(data, position, offset, blocksize));
49 | if (!value.IsValid(false))
50 | return false;
51 | return true;
52 | }
53 | else
54 | {
55 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
56 | return defaultvalue;
57 | }
58 | }
59 |
60 | stock Dynamic_MemberType _SetBool(ArrayList data, int position, int offset, int blocksize, bool value)
61 | {
62 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
63 | if (type == DynamicType_Bool)
64 | {
65 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, value);
66 | return DynamicType_Bool;
67 | }
68 | else if (type == DynamicType_Int)
69 | {
70 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, value);
71 | return DynamicType_Int;
72 | }
73 | else if (type == DynamicType_Float)
74 | {
75 | _Dynamic_SetMemberDataFloat(data, position, offset, blocksize, float(value));
76 | return DynamicType_Float;
77 | }
78 | else if (type == DynamicType_String)
79 | {
80 | int length = _Dynamic_GetMemberStringLength(data, position, offset, blocksize);
81 | char[] buffer = new char[length];
82 | if (value)
83 | strcopy(buffer, length, "True");
84 | else
85 | strcopy(buffer, length, "False");
86 | _Dynamic_SetMemberDataString(data, position, offset, blocksize, buffer);
87 | return DynamicType_String;
88 | }
89 | else
90 | {
91 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
92 | return DynamicType_Unknown;
93 | }
94 | }
95 |
96 | stock bool _Dynamic_GetBool(DynamicObject dynamic, const char[] membername, bool defaultvalue=false)
97 | {
98 | if (!dynamic.IsValid(true))
99 | return defaultvalue;
100 |
101 | DynamicOffset offset;
102 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_Bool))
103 | return defaultvalue;
104 |
105 | return _GetBool(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, defaultvalue);
106 | }
107 |
108 | stock DynamicOffset _Dynamic_SetBool(DynamicObject dynamic, const char[] membername, bool value)
109 | {
110 | if (!dynamic.IsValid(true))
111 | return INVALID_DYNAMIC_OFFSET;
112 |
113 | DynamicOffset offset;
114 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, true, offset, DynamicType_Bool))
115 | return INVALID_DYNAMIC_OFFSET;
116 |
117 | Dynamic_MemberType type = _SetBool(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
118 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
119 | return offset;
120 | }
121 |
122 | stock bool _Dynamic_GetBoolByOffset(DynamicObject dynamic, DynamicOffset offset, bool defaultvalue=false)
123 | {
124 | if (!dynamic.IsValid(true))
125 | return defaultvalue;
126 |
127 | return _GetBool(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, defaultvalue);
128 | }
129 |
130 | stock bool _Dynamic_SetBoolByOffset(DynamicObject dynamic, DynamicOffset offset, bool value)
131 | {
132 | if (!dynamic.IsValid(true))
133 | return false;
134 |
135 | Dynamic_MemberType type = _SetBool(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
136 | _Dynamic_CallOnChangedForwardByOffset(dynamic, offset, type);
137 | return true;
138 | }
139 |
140 | stock int _Dynamic_PushBool(DynamicObject dynamic, bool value, const char[] name="")
141 | {
142 | if (!dynamic.IsValid(true))
143 | return INVALID_DYNAMIC_INDEX;
144 |
145 | DynamicOffset offset;
146 | int memberindex = _Dynamic_CreateMemberOffset(dynamic, offset, name, DynamicType_Bool);
147 | _Dynamic_SetMemberDataInt(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
148 | _Dynamic_CallOnChangedForward(dynamic, offset, name, DynamicType_Bool);
149 | return memberindex;
150 | }
151 |
152 | stock bool _Dynamic_GetBoolByIndex(DynamicObject dynamic, int memberindex, bool defaultvalue=false)
153 | {
154 | if (!dynamic.IsValid(true))
155 | return false;
156 |
157 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
158 | if (offset == INVALID_DYNAMIC_OFFSET)
159 | return defaultvalue;
160 |
161 | return _Dynamic_GetBoolByOffset(dynamic, offset, defaultvalue);
162 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/datatypes/dynamic.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_datatypes_dynamic
21 | #endinput
22 | #endif
23 | #define _dynamic_system_datatypes_dynamic
24 |
25 | stock DynamicObject _GetDynamic(ArrayList data, int position, int offset, int blocksize)
26 | {
27 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
28 | if (type == DynamicType_Dynamic)
29 | return view_as(_Dynamic_GetMemberDataInt(data, position, offset, blocksize));
30 | else
31 | {
32 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
33 | return INVALID_DYNAMIC_OBJECT;
34 | }
35 | }
36 |
37 | stock Dynamic_MemberType _SetDynamic(DynamicObject dynamic, ArrayList data, int position, int offset, int blocksize, DynamicObject value, const char[] membername="")
38 | {
39 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
40 | if (type == DynamicType_Dynamic)
41 | {
42 | // remove parent from current value
43 | DynamicObject currentvalue = view_as(_Dynamic_GetMemberDataInt(data, position, offset, blocksize));
44 | if (currentvalue != INVALID_DYNAMIC_OBJECT)
45 | {
46 | currentvalue.Parent = INVALID_DYNAMIC_OBJECT;
47 | currentvalue.ParentOffset = INVALID_DYNAMIC_OFFSET;
48 | }
49 |
50 | // set value and name
51 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, value.Index);
52 |
53 | // set parent
54 | if (value != INVALID_DYNAMIC_OBJECT)
55 | {
56 | value.Parent = dynamic;
57 | value.ParentOffset = DynamicOffset(position, offset);
58 | }
59 | return DynamicType_Dynamic;
60 | }
61 | else
62 | {
63 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
64 | return DynamicType_Unknown;
65 | }
66 | }
67 |
68 | stock DynamicObject _Dynamic_GetDynamic(DynamicObject dynamic, const char[] membername)
69 | {
70 | if (!dynamic.IsValid(true))
71 | return INVALID_DYNAMIC_OBJECT;
72 |
73 | DynamicOffset offset;
74 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_Dynamic))
75 | return INVALID_DYNAMIC_OBJECT;
76 |
77 | return _GetDynamic(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
78 | }
79 |
80 | stock DynamicOffset _Dynamic_SetDynamic(DynamicObject dynamic, const char[] membername, DynamicObject value)
81 | {
82 | if (!dynamic.IsValid(true))
83 | return INVALID_DYNAMIC_OFFSET;
84 |
85 | DynamicOffset offset;
86 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, true, offset, DynamicType_Dynamic))
87 | return INVALID_DYNAMIC_OFFSET;
88 |
89 | Dynamic_MemberType type = _SetDynamic(dynamic, dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value, membername);
90 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
91 | return offset;
92 | }
93 |
94 | stock DynamicObject _Dynamic_GetDynamicByOffset(DynamicObject dynamic, DynamicOffset offset)
95 | {
96 | if (!dynamic.IsValid(true))
97 | return INVALID_DYNAMIC_OBJECT;
98 |
99 | return _GetDynamic(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
100 | }
101 |
102 | stock bool _Dynamic_SetDynamicByOffset(DynamicObject dynamic, DynamicOffset offset, DynamicObject value)
103 | {
104 | if (!dynamic.IsValid(true))
105 | return false;
106 |
107 | Dynamic_MemberType type = _SetDynamic(dynamic, dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
108 | _Dynamic_CallOnChangedForwardByOffset(dynamic, offset, type);
109 | return true;
110 | }
111 |
112 | stock int _Dynamic_PushDynamic(DynamicObject dynamic, DynamicObject value, const char[] name="")
113 | {
114 | if (!dynamic.IsValid(true))
115 | return INVALID_DYNAMIC_INDEX;
116 |
117 | DynamicOffset offset;
118 | int memberindex = _Dynamic_CreateMemberOffset(dynamic, offset, name, DynamicType_Dynamic);
119 | _Dynamic_SetMemberDataInt(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value.Index);
120 |
121 | // set parent
122 | if (value != INVALID_DYNAMIC_OBJECT)
123 | {
124 | value.Parent = dynamic;
125 | value.ParentOffset = offset;
126 | }
127 |
128 | _Dynamic_CallOnChangedForward(dynamic, offset, name, DynamicType_Dynamic);
129 | return memberindex;
130 | }
131 |
132 | stock DynamicObject _Dynamic_GetDynamicByIndex(DynamicObject dynamic, int memberindex)
133 | {
134 | if (!dynamic.IsValid(true))
135 | return INVALID_DYNAMIC_OBJECT;
136 |
137 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
138 | if (offset == INVALID_DYNAMIC_OFFSET)
139 | return INVALID_DYNAMIC_OBJECT;
140 |
141 | return _Dynamic_GetDynamicByOffset(dynamic, offset);
142 | }
143 |
144 | stock bool _Dynamic_SetDynamicByIndex(DynamicObject dynamic, int memberindex, DynamicObject value)
145 | {
146 | if (!dynamic.IsValid(true))
147 | return false;
148 |
149 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
150 | if (offset == INVALID_DYNAMIC_OFFSET)
151 | return false;
152 |
153 | return _Dynamic_SetDynamicByOffset(dynamic, offset, value);
154 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/datatypes/float.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_datatypes_float
21 | #endinput
22 | #endif
23 | #define _dynamic_system_datatypes_float
24 |
25 | stock float _GetFloat(ArrayList data, int position, int offset, int blocksize, float defaultvalue)
26 | {
27 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
28 | if (type == DynamicType_Float)
29 | return _Dynamic_GetMemberDataFloat(data, position, offset, blocksize);
30 | else if (type == DynamicType_Int || type == DynamicType_Bool)
31 | return float(_Dynamic_GetMemberDataInt(data, position, offset, blocksize));
32 | else if (type == DynamicType_String)
33 | {
34 | int length = _Dynamic_GetMemberStringLength(data, position, offset, blocksize);
35 | char[] buffer = new char[length];
36 | _Dynamic_GetMemberDataString(data, position, offset, blocksize, buffer, length);
37 | return StringToFloat(buffer);
38 | }
39 | else
40 | {
41 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
42 | return defaultvalue;
43 | }
44 | }
45 |
46 | stock Dynamic_MemberType _SetFloat(ArrayList data, int position, int offset, int blocksize, float value)
47 | {
48 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
49 | if (type == DynamicType_Float)
50 | {
51 | _Dynamic_SetMemberDataFloat(data, position, offset, blocksize, value);
52 | return DynamicType_Float;
53 | }
54 | else if (type == DynamicType_Int)
55 | {
56 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, RoundFloat(value));
57 | return DynamicType_Int;
58 | }
59 | else if (type == DynamicType_Bool)
60 | {
61 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, RoundFloat(value));
62 | return DynamicType_Bool;
63 | }
64 | else if (type == DynamicType_String)
65 | {
66 | int length = _Dynamic_GetMemberStringLength(data, position, offset, blocksize);
67 | char[] buffer = new char[length];
68 | FloatToString(value, buffer, length);
69 | _Dynamic_SetMemberDataString(data, position, offset, blocksize, buffer);
70 | return DynamicType_String;
71 | }
72 | else
73 | {
74 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
75 | return DynamicType_Unknown;
76 | }
77 | }
78 |
79 | stock float _Dynamic_GetFloat(DynamicObject dynamic, const char[] membername, float defaultvalue=-1.0)
80 | {
81 | if (!dynamic.IsValid(true))
82 | return defaultvalue;
83 |
84 | DynamicOffset offset;
85 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_Float))
86 | return defaultvalue;
87 |
88 | return _GetFloat(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, defaultvalue);
89 | }
90 |
91 | stock DynamicOffset _Dynamic_SetFloat(DynamicObject dynamic, const char[] membername, float value)
92 | {
93 | if (!dynamic.IsValid(true))
94 | return INVALID_DYNAMIC_OFFSET;
95 |
96 | DynamicOffset offset;
97 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, true, offset, DynamicType_Float))
98 | return INVALID_DYNAMIC_OFFSET;
99 |
100 | Dynamic_MemberType type = _SetFloat(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
101 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
102 | return offset;
103 | }
104 |
105 | stock float _Dynamic_GetFloatByOffset(DynamicObject dynamic, DynamicOffset offset, float defaultvalue=-1.0)
106 | {
107 | if (!dynamic.IsValid(true))
108 | return defaultvalue;
109 |
110 | return _GetFloat(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, defaultvalue);
111 | }
112 |
113 | stock bool _Dynamic_SetFloatByOffset(DynamicObject dynamic, DynamicOffset offset, float value)
114 | {
115 | if (!dynamic.IsValid(true))
116 | return false;
117 |
118 | Dynamic_MemberType type = _SetFloat(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
119 | _Dynamic_CallOnChangedForwardByOffset(dynamic, offset, type);
120 | return true;
121 | }
122 |
123 | stock int _Dynamic_PushFloat(DynamicObject dynamic, float value, const char[] name="")
124 | {
125 | if (!dynamic.IsValid(true))
126 | return INVALID_DYNAMIC_INDEX;
127 |
128 | DynamicOffset offset;
129 | int memberindex = _Dynamic_CreateMemberOffset(dynamic, offset, name, DynamicType_Float);
130 | _Dynamic_SetMemberDataFloat(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
131 | _Dynamic_CallOnChangedForward(dynamic, offset, name, DynamicType_Float);
132 | return memberindex;
133 | }
134 |
135 | stock float _Dynamic_GetFloatByIndex(DynamicObject dynamic, int memberindex, float defaultvalue=-1.0)
136 | {
137 | if (!dynamic.IsValid(true))
138 | return defaultvalue;
139 |
140 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
141 | if (offset == INVALID_DYNAMIC_OFFSET)
142 | return defaultvalue;
143 |
144 | return _Dynamic_GetFloatByOffset(dynamic, offset, defaultvalue);
145 | }
146 |
147 | stock float _Dynamic_GetMemberDataFloat(ArrayList data, int position, int offset, int blocksize)
148 | {
149 | // Move the offset forward by one cell as this is where the value is stored
150 | offset++;
151 |
152 | // Calculate internal data array index and cell position
153 | _Dynamic_RecalculateOffset(position, offset, blocksize);
154 |
155 | // Return value
156 | return data.Get(position, offset);
157 | }
158 |
159 | stock void _Dynamic_SetMemberDataFloat(ArrayList data, int position, int offset, int blocksize, float value)
160 | {
161 | // Move the offset forward by one cell as this is where the value is stored
162 | offset++;
163 |
164 | // Calculate internal data array index and cell position
165 | _Dynamic_RecalculateOffset(position, offset, blocksize);
166 |
167 | // Set the value
168 | SetArrayCell(data, position, value, offset);
169 | }
170 |
--------------------------------------------------------------------------------
/scripting/dynamic/system/datatypes/function.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_datatypes_function
21 | #endinput
22 | #endif
23 | #define _dynamic_system_datatypes_function
24 |
25 | stock Function _GetFunction(ArrayList data, int position, int offset, int blocksize)
26 | {
27 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
28 | if (type == DynamicType_Function)
29 | return _Dynamic_GetMemberDataFunction(data, position, offset, blocksize);
30 | else
31 | {
32 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
33 | return INVALID_FUNCTION;
34 | }
35 | }
36 |
37 | stock Dynamic_MemberType _SetFunction(ArrayList data, int position, int offset, int blocksize, Function value, const char[] membername="")
38 | {
39 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
40 | if (type == DynamicType_Function)
41 | {
42 | _Dynamic_SetMemberDataFunction(data, position, offset, blocksize, value);
43 | return DynamicType_Function;
44 | }
45 | else
46 | {
47 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
48 | return DynamicType_Unknown;
49 | }
50 | }
51 |
52 | stock Function _Dynamic_GetFunction(DynamicObject dynamic, const char[] membername)
53 | {
54 | if (!dynamic.IsValid(true))
55 | return INVALID_FUNCTION;
56 |
57 | DynamicOffset offset;
58 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_Function))
59 | return INVALID_FUNCTION;
60 |
61 | return _GetFunction(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
62 | }
63 |
64 | stock DynamicOffset _Dynamic_SetFunction(DynamicObject dynamic, const char[] membername, Function value)
65 | {
66 | if (!dynamic.IsValid(true))
67 | return INVALID_DYNAMIC_OFFSET;
68 |
69 | DynamicOffset offset;
70 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, true, offset, DynamicType_Function))
71 | return INVALID_DYNAMIC_OFFSET;
72 |
73 | Dynamic_MemberType type = _SetFunction(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
74 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
75 | return offset;
76 | }
77 |
78 | stock Function _Dynamic_GetFunctionByOffset(DynamicObject dynamic, DynamicOffset offset)
79 | {
80 | if (!dynamic.IsValid(true))
81 | return INVALID_FUNCTION;
82 |
83 | return _GetFunction(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
84 | }
85 |
86 | stock bool _Dynamic_SetFunctionByOffset(DynamicObject dynamic, DynamicOffset offset, Function value)
87 | {
88 | if (!dynamic.IsValid(true))
89 | return false;
90 |
91 | Dynamic_MemberType type = _SetFunction(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
92 | _Dynamic_CallOnChangedForwardByOffset(dynamic, offset, type);
93 | return true;
94 | }
95 |
96 | stock int _Dynamic_PushFunction(DynamicObject dynamic, Function value, const char[] name="")
97 | {
98 | if (!dynamic.IsValid(true))
99 | return INVALID_DYNAMIC_INDEX;
100 |
101 | DynamicOffset offset;
102 | int memberindex = _Dynamic_CreateMemberOffset(dynamic, offset, name, DynamicType_Function);
103 | _Dynamic_SetMemberDataFunction(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
104 | _Dynamic_CallOnChangedForward(dynamic, offset, name, DynamicType_Function);
105 | return memberindex;
106 | }
107 |
108 | stock Function _Dynamic_GetFunctionByIndex(DynamicObject dynamic, int memberindex)
109 | {
110 | if (!dynamic.IsValid(true))
111 | return INVALID_FUNCTION;
112 |
113 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
114 | if (offset == INVALID_DYNAMIC_OFFSET)
115 | return INVALID_FUNCTION;
116 |
117 | return _Dynamic_GetFunctionByOffset(dynamic, offset);
118 | }
119 |
120 | stock Function _Dynamic_GetMemberDataFunction(ArrayList data, int position, int offset, int blocksize)
121 | {
122 | // Move the offset forward by one cell as this is where the value is stored
123 | offset++;
124 |
125 | // Calculate internal data array index and cell position
126 | _Dynamic_RecalculateOffset(position, offset, blocksize);
127 |
128 | // Return value
129 | return data.Get(position, offset);
130 | }
131 |
132 | stock void _Dynamic_SetMemberDataFunction(ArrayList data, int position, int offset, int blocksize, Function value)
133 | {
134 | // Move the offset forward by one cell as this is where the value is stored
135 | offset++;
136 |
137 | // Calculate internal data array index and cell position
138 | _Dynamic_RecalculateOffset(position, offset, blocksize);
139 |
140 | // Set the value
141 | SetArrayCell(data, position, view_as(value), offset);
142 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/datatypes/handle.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_datatypes_handle
21 | #endinput
22 | #endif
23 | #define _dynamic_system_datatypes_handle
24 |
25 | stock int _GetHandle(ArrayList data, int position, int offset, int blocksize)
26 | {
27 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
28 | if (type == DynamicType_Handle)
29 | return _Dynamic_GetMemberDataInt(data, position, offset, blocksize);
30 | else
31 | {
32 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
33 | return 0;
34 | }
35 | }
36 |
37 | stock Dynamic_MemberType _SetHandle(ArrayList data, int position, int offset, int blocksize, int value, const char[] membername="")
38 | {
39 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
40 | if (type == DynamicType_Handle)
41 | {
42 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, view_as(value));
43 | return DynamicType_Handle;
44 | }
45 | else
46 | {
47 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
48 | return DynamicType_Unknown;
49 | }
50 | }
51 |
52 | stock int _Dynamic_GetHandle(DynamicObject dynamic, const char[] membername)
53 | {
54 | if (!dynamic.IsValid(true))
55 | return 0;
56 |
57 | DynamicOffset offset;
58 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_Handle))
59 | return 0;
60 |
61 | return _GetHandle(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
62 | }
63 |
64 | stock DynamicOffset _Dynamic_SetHandle(DynamicObject dynamic, const char[] membername, int value)
65 | {
66 | if (!dynamic.IsValid(true))
67 | return INVALID_DYNAMIC_OFFSET;
68 |
69 | DynamicOffset offset;
70 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, true, offset, DynamicType_Handle))
71 | return INVALID_DYNAMIC_OFFSET;
72 |
73 | Dynamic_MemberType type = _SetHandle(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
74 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
75 | return offset;
76 | }
77 |
78 | stock int _Dynamic_GetHandleByOffset(DynamicObject dynamic, DynamicOffset offset)
79 | {
80 | if (!dynamic.IsValid(true))
81 | return 0;
82 |
83 | return _GetHandle(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
84 | }
85 |
86 | stock bool _Dynamic_SetHandleByOffset(DynamicObject dynamic, DynamicOffset offset, int value)
87 | {
88 | if (!dynamic.IsValid(true))
89 | return false;
90 |
91 | Dynamic_MemberType type = _SetHandle(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
92 | _Dynamic_CallOnChangedForwardByOffset(dynamic, offset, type);
93 | return true;
94 | }
95 |
96 | stock int _Dynamic_PushHandle(DynamicObject dynamic, int value, const char[] name="")
97 | {
98 | if (!dynamic.IsValid(true))
99 | return INVALID_DYNAMIC_INDEX;
100 |
101 | DynamicOffset offset;
102 | int memberindex = _Dynamic_CreateMemberOffset(dynamic, offset, name, DynamicType_Dynamic);
103 | _Dynamic_SetMemberDataInt(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
104 | _Dynamic_CallOnChangedForward(dynamic, offset, name, DynamicType_Handle);
105 | return memberindex;
106 | }
107 |
108 | stock int _Dynamic_GetHandleByIndex(DynamicObject dynamic, int memberindex)
109 | {
110 | if (!dynamic.IsValid(true))
111 | return 0;
112 |
113 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
114 | if (offset == INVALID_DYNAMIC_OFFSET)
115 | return 0;
116 |
117 | return _Dynamic_GetHandleByOffset(dynamic, offset);
118 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/datatypes/int.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_datatypes_int
21 | #endinput
22 | #endif
23 | #define _dynamic_system_datatypes_int
24 |
25 | stock int _GetInt(ArrayList data, int position, int offset, int blocksize, int defaultvalue)
26 | {
27 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
28 | if (type == DynamicType_Int || type == DynamicType_Bool)
29 | return _Dynamic_GetMemberDataInt(data, position, offset, blocksize);
30 | else if (type == DynamicType_Float)
31 | return RoundFloat(_Dynamic_GetMemberDataFloat(data, position, offset, blocksize));
32 | else if (type == DynamicType_String)
33 | {
34 | int length = _Dynamic_GetMemberStringLength(data, position, offset, blocksize);
35 | char[] buffer = new char[length];
36 | _Dynamic_GetMemberDataString(data, position, offset, blocksize, buffer, length);
37 | return StringToInt(buffer);
38 | }
39 | else if (type == DynamicType_Dynamic)
40 | return _Dynamic_GetMemberDataInt(data, position, offset, blocksize);
41 | else
42 | {
43 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
44 | return defaultvalue;
45 | }
46 | }
47 |
48 | stock Dynamic_MemberType _SetInt(ArrayList data, int position, int offset, int blocksize, int value)
49 | {
50 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
51 | if (type == DynamicType_Int)
52 | {
53 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, value);
54 | return DynamicType_Int;
55 | }
56 | else if (type == DynamicType_Float)
57 | {
58 | _Dynamic_SetMemberDataFloat(data, position, offset, blocksize, float(value));
59 | return DynamicType_Float;
60 | }
61 | else if (type == DynamicType_Bool)
62 | {
63 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, value);
64 | return DynamicType_Bool;
65 | }
66 | else if (type == DynamicType_String)
67 | {
68 | int length = _Dynamic_GetMemberStringLength(data, position, offset, blocksize);
69 | char[] buffer = new char[length];
70 | IntToString(value, buffer, length);
71 | _Dynamic_SetMemberDataString(data, position, offset, blocksize, buffer);
72 | return DynamicType_String;
73 | }
74 | else
75 | {
76 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
77 | return DynamicType_Unknown;
78 | }
79 | }
80 |
81 | stock int _Dynamic_GetInt(DynamicObject dynamic, const char[] membername, int defaultvalue=-1)
82 | {
83 | if (!dynamic.IsValid(true))
84 | return defaultvalue;
85 |
86 | DynamicOffset offset;
87 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_Int))
88 | return defaultvalue;
89 |
90 | return _GetInt(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, defaultvalue);
91 | }
92 |
93 | // native int Dynamic_SetInt(Dynamic obj, const char[] membername, int value);
94 | stock DynamicOffset _Dynamic_SetInt(DynamicObject dynamic, const char[] membername, int value)
95 | {
96 | if (!dynamic.IsValid(true))
97 | return INVALID_DYNAMIC_OFFSET;
98 |
99 | DynamicOffset offset;
100 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, true, offset, DynamicType_Int))
101 | return INVALID_DYNAMIC_OFFSET;
102 |
103 | Dynamic_MemberType type = _SetInt(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
104 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
105 | return offset;
106 | }
107 |
108 | stock int _Dynamic_GetIntByOffset(DynamicObject dynamic, DynamicOffset offset, int defaultvalue=-1)
109 | {
110 | if (!dynamic.IsValid(true))
111 | return defaultvalue;
112 |
113 | return _GetInt(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, defaultvalue);
114 | }
115 |
116 | stock bool _Dynamic_SetIntByOffset(DynamicObject dynamic, DynamicOffset offset, int value)
117 | {
118 | if (!dynamic.IsValid(true))
119 | return false;
120 |
121 | Dynamic_MemberType type = _SetInt(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
122 | _Dynamic_CallOnChangedForwardByOffset(dynamic, offset, type);
123 | return true;
124 | }
125 |
126 | stock int _Dynamic_PushInt(DynamicObject dynamic, int value, const char[] name="")
127 | {
128 | if (!dynamic.IsValid(true))
129 | return INVALID_DYNAMIC_INDEX;
130 |
131 | DynamicOffset offset;
132 | int memberindex = _Dynamic_CreateMemberOffset(dynamic, offset, name, DynamicType_Int);
133 | _Dynamic_SetMemberDataInt(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
134 | _Dynamic_CallOnChangedForward(dynamic, offset, name, DynamicType_Int);
135 | return memberindex;
136 | }
137 |
138 | stock int _Dynamic_GetIntByIndex(DynamicObject dynamic, int memberindex, int defaultvalue=-1)
139 | {
140 | if (!dynamic.IsValid(true))
141 | return INVALID_DYNAMIC_INDEX;
142 |
143 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
144 | if (offset == INVALID_DYNAMIC_OFFSET)
145 | return defaultvalue;
146 |
147 | return _Dynamic_GetIntByOffset(dynamic, offset, defaultvalue);
148 | }
149 |
150 | stock int _Dynamic_GetMemberDataInt(ArrayList data, int position, int offset, int blocksize)
151 | {
152 | // Move the offset forward by one cell as this is where the value is stored
153 | offset++;
154 |
155 | // Calculate internal data array index and cell position
156 | _Dynamic_RecalculateOffset(position, offset, blocksize);
157 |
158 | // Return value
159 | return data.Get(position, offset);
160 | }
161 |
162 | stock void _Dynamic_SetMemberDataInt(ArrayList data, int position, int offset, int blocksize, int value)
163 | {
164 | // Move the offset forward by one cell as this is where the value is stored
165 | offset++;
166 |
167 | // Calculate internal data array index and cell position
168 | _Dynamic_RecalculateOffset(position, offset, blocksize);
169 |
170 | // Set the value
171 | SetArrayCell(data, position, value, offset);
172 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/datatypes/string.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_datatypes_string
21 | #endinput
22 | #endif
23 | #define _dynamic_system_datatypes_string
24 |
25 | stock bool _GetString(ArrayList data, int position, int offset, int blocksize, char[] buffer, int length)
26 | {
27 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
28 | if (type == DynamicType_String)
29 | {
30 | _Dynamic_GetMemberDataString(data, position, offset, blocksize, buffer, length);
31 | return true;
32 | }
33 | else if (type == DynamicType_Int)
34 | {
35 | int value = _Dynamic_GetMemberDataInt(data, position, offset, blocksize);
36 | IntToString(value, buffer, length);
37 | return true;
38 | }
39 | else if (type == DynamicType_Float)
40 | {
41 | float value = _Dynamic_GetMemberDataFloat(data, position, offset, blocksize);
42 | FloatToString(value, buffer, length);
43 | return true;
44 | }
45 | else if (type == DynamicType_Bool)
46 | {
47 | if (_Dynamic_GetMemberDataInt(data, position, offset, blocksize))
48 | Format(buffer, length, "True");
49 | else
50 | Format(buffer, length, "False");
51 | return true;
52 | }
53 | else if (type == DynamicType_Vector)
54 | {
55 | float vector[3];
56 | _Dynamic_GetMemberDataVector(data, position, offset, blocksize, vector);
57 | Format(buffer, length, "{%f, %f, %f}", vector[0], vector[1], vector[2]);
58 | return true;
59 | }
60 | else
61 | {
62 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
63 | buffer[0] = '\0';
64 | return false;
65 | }
66 | }
67 |
68 | stock Dynamic_MemberType _SetString(ArrayList data, int position, int offset, int blocksize, const char[] value)
69 | {
70 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
71 | if (type == DynamicType_String)
72 | {
73 | _Dynamic_SetMemberDataString(data, position, offset, blocksize, value);
74 | return DynamicType_String;
75 | }
76 | else if (type == DynamicType_Int)
77 | {
78 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, StringToInt(value));
79 | return DynamicType_Int;
80 | }
81 | else if (type == DynamicType_Float)
82 | {
83 | _Dynamic_SetMemberDataFloat(data, position, offset, blocksize, StringToFloat(value));
84 | return DynamicType_Float;
85 | }
86 | else if (type == DynamicType_Bool)
87 | {
88 | if (StrEqual(value, "True"))
89 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, true);
90 | else if (StrEqual(value, "1"))
91 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, true);
92 | else
93 | _Dynamic_SetMemberDataInt(data, position, offset, blocksize, false);
94 | return DynamicType_Bool;
95 | }
96 | else if (type == DynamicType_Vector)
97 | {
98 | float vector[3];
99 | if (!GetVectorFromString(value, vector))
100 | {
101 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
102 | return DynamicType_Unknown;
103 | }
104 |
105 | _SetVector(data, position, offset, blocksize, vector);
106 | return DynamicType_Vector;
107 | }
108 | else
109 | {
110 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
111 | return DynamicType_Unknown;
112 | }
113 | }
114 |
115 | stock bool _Dynamic_GetString(DynamicObject dynamic, const char[] membername, char[] buffer, int length)
116 | {
117 | if (!dynamic.IsValid(true))
118 | {
119 | buffer[0] = '\0';
120 | return false;
121 | }
122 |
123 | DynamicOffset offset;
124 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_String))
125 | {
126 | buffer[0] = '\0';
127 | return false;
128 | }
129 |
130 | return _GetString(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, buffer, length);
131 | }
132 |
133 | stock DynamicOffset _Dynamic_SetString(DynamicObject dynamic, const char[] membername, const char[] value, int length, int valuelength)
134 | {
135 | if (!dynamic.IsValid(true))
136 | return INVALID_DYNAMIC_OFFSET;
137 |
138 | if (length == 0)
139 | length = valuelength;
140 |
141 | DynamicOffset offset;
142 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, true, offset, DynamicType_String, length))
143 | return INVALID_DYNAMIC_OFFSET;
144 |
145 | Dynamic_MemberType type = _SetString(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
146 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
147 | return offset;
148 | }
149 |
150 | stock bool _Dynamic_GetStringByOffset(DynamicObject dynamic, DynamicOffset offset, char[] buffer, int length)
151 | {
152 | if (!dynamic.IsValid(true))
153 | {
154 | buffer[0] = '\0';
155 | return false;
156 | }
157 |
158 | return _GetString(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, buffer, length);
159 | }
160 |
161 | stock bool _Dynamic_SetStringByOffset(DynamicObject dynamic, DynamicOffset offset, const char[] value)
162 | {
163 | if (!dynamic.IsValid(true))
164 | return false;
165 |
166 | Dynamic_MemberType type = _SetString(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
167 | _Dynamic_CallOnChangedForwardByOffset(dynamic, offset, type);
168 | return true;
169 | }
170 |
171 | stock int _Dynamic_PushString(DynamicObject dynamic, const char[] value, int length, int valuelength, const char[] name)
172 | {
173 | if (!dynamic.IsValid(true))
174 | return INVALID_DYNAMIC_INDEX;
175 |
176 | if (length == 0)
177 | length = ++valuelength;
178 |
179 | DynamicOffset offset;
180 | int memberindex = _Dynamic_CreateMemberOffset(dynamic, offset, name, DynamicType_String, length);
181 |
182 | length+=2; // this can probably be removed (review Native_Dynamic_SetString for removal also)
183 | _Dynamic_SetMemberDataString(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
184 | _Dynamic_CallOnChangedForward(dynamic, offset, name, DynamicType_String);
185 | return memberindex;
186 | }
187 |
188 | stock bool _Dynamic_GetStringByIndex(DynamicObject dynamic, int memberindex, char[] buffer, int length)
189 | {
190 | if (!dynamic.IsValid(true))
191 | {
192 | buffer[0] = '\0';
193 | return false;
194 | }
195 |
196 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
197 | if (offset == INVALID_DYNAMIC_OFFSET)
198 | {
199 | buffer[0] = '\0';
200 | return false;
201 | }
202 |
203 | if (_Dynamic_GetStringByOffset(dynamic, offset, buffer, length))
204 | return true;
205 |
206 | return false;
207 | }
208 |
209 | stock int _Dynamic_GetStringLength(DynamicObject dynamic, const char[] membername)
210 | {
211 | if (!dynamic.IsValid(true))
212 | return 0;
213 |
214 | DynamicOffset offset;
215 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_String))
216 | return 0;
217 |
218 | return _Dynamic_GetMemberStringLength(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
219 | }
220 |
221 | stock bool _Dynamic_CompareString(DynamicObject dynamic, const char[] membername, const char[] value, bool casesensitive)
222 | {
223 | DynamicOffset offset = _Dynamic_GetMemberOffset(dynamic, membername);
224 | if (offset == INVALID_DYNAMIC_OFFSET)
225 | return false;
226 |
227 | return _Dynamic_CompareStringByOffset(dynamic, offset, value, casesensitive);
228 | }
229 |
230 | stock bool _Dynamic_CompareStringByOffset(DynamicObject dynamic, DynamicOffset offset, const char[] value, bool casesensitive)
231 | {
232 | int length = _Dynamic_GetStringLengthByOffset(dynamic, offset);
233 | char[] buffer = new char[length];
234 | _Dynamic_GetStringByOffset(dynamic, offset, buffer, length);
235 | return StrEqual(value, buffer, casesensitive);
236 | }
237 |
238 | stock int _Dynamic_GetStringLengthByOffset(DynamicObject dynamic, DynamicOffset offset)
239 | {
240 | if (!dynamic.IsValid(true))
241 | return 0;
242 |
243 | return _Dynamic_GetMemberStringLength(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize);
244 | }
245 |
246 | stock int _Dynamic_GetMemberStringLength(ArrayList data, int position, int offset, int blocksize)
247 | {
248 | // Move the offset forward by one cell as this is where a strings length is stored
249 | offset++;
250 |
251 | // Calculate internal data array index and cell position
252 | _Dynamic_RecalculateOffset(position, offset, blocksize);
253 |
254 | // Return string length
255 | return data.Get(position, offset);
256 | }
257 |
258 | stock void _Dynamic_SetMemberStringLength(ArrayList data, DynamicOffset offset, int blocksize, int length)
259 | {
260 | offset = offset.Clone(blocksize, 1);
261 | data.Set(offset.Index, length, offset.Cell);
262 | }
263 |
264 | stock void _Dynamic_SetMemberDataString(ArrayList data, int position, int offset, int blocksize, const char[] buffer)
265 | {
266 | int length = _Dynamic_GetMemberStringLength(data, position, offset, blocksize);
267 |
268 | // Move the offset forward by two cells as this is where the string data starts
269 | offset+=2;
270 | _Dynamic_RecalculateOffset(position, offset, blocksize);
271 |
272 | // Offsets for Strings must by multiplied by 4
273 | offset*=4;
274 |
275 | // Set string data cell by cell and recalculate offset incase the string data wraps onto a new array index
276 | int i;
277 | char letter;
278 | for (i=0; i < length; i++)
279 | {
280 | letter = buffer[i];
281 | SetArrayCell(data, position, letter, offset, true);
282 |
283 | // If the null terminator exists we are done
284 | if (letter == 0)
285 | return;
286 |
287 | offset++;
288 | _Dynamic_RecalculateOffset(position, offset, blocksize, true);
289 | }
290 |
291 | // Set null terminator
292 | SetArrayCell(data, position, 0, offset, true);
293 | }
294 |
295 | stock void _Dynamic_GetMemberDataString(ArrayList data, int position, int offset, int blocksize, char[] buffer, int length)
296 | {
297 | // Move the offset forward by two cells as this is where the string data starts
298 | offset+=2;
299 | _Dynamic_RecalculateOffset(position, offset, blocksize);
300 |
301 | // Offsets for Strings must by multiplied by 4
302 | offset*=4;
303 |
304 | // Get string data cell by cell and recalculate offset incase the string data wraps onto a new array index
305 | int i; char letter;
306 | for (i=0; i < length; i++)
307 | {
308 | letter = view_as(data.Get(position, offset, true));
309 | buffer[i] = letter;
310 |
311 | // If the null terminator exists we are done
312 | if (letter == 0)
313 | return;
314 |
315 | offset++;
316 | _Dynamic_RecalculateOffset(position, offset, blocksize, true);
317 | }
318 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/datatypes/vector.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_datatypes_vector
21 | #endinput
22 | #endif
23 | #define _dynamic_system_datatypes_vector
24 |
25 | stock bool _GetVector(ArrayList data, int position, int offset, int blocksize, float value[3])
26 | {
27 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
28 | if (type == DynamicType_Vector)
29 | return _Dynamic_GetMemberDataVector(data, position, offset, blocksize, value);
30 | else if (type == DynamicType_String)
31 | {
32 | int length = _Dynamic_GetMemberStringLength(data, position, offset, blocksize);
33 | char[] buffer = new char[length];
34 | _Dynamic_GetMemberDataString(data, position, offset, blocksize, buffer, length);
35 | return GetVectorFromString(buffer, value);
36 | }
37 | else
38 | {
39 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
40 | return false;
41 | }
42 | }
43 |
44 | stock Dynamic_MemberType _SetVector(ArrayList data, int position, int offset, int blocksize, const float value[3], const char[] membername="")
45 | {
46 | Dynamic_MemberType type = _Dynamic_GetMemberDataType(data, position, offset, blocksize);
47 | if (type == DynamicType_Vector)
48 | {
49 | _Dynamic_SetMemberDataVector(data, position, offset, blocksize, value);
50 | return DynamicType_Vector;
51 | }
52 | else if (type == DynamicType_String)
53 | {
54 | char buffer[192];
55 | Format(buffer, sizeof(buffer), "{%f, %f, %f}", value[0], value[1], value[2]);
56 | _Dynamic_SetMemberDataString(data, position, offset, blocksize, buffer);
57 | return DynamicType_String;
58 | }
59 | else
60 | {
61 | ThrowNativeError(SP_ERROR_NATIVE, "Unsupported member datatype (%d)", type);
62 | return DynamicType_Unknown;
63 | }
64 | }
65 |
66 | stock bool _Dynamic_GetVector(DynamicObject dynamic, const char[] membername, float[3] vector)
67 | {
68 | if (!dynamic.IsValid(true))
69 | return false;
70 |
71 | DynamicOffset offset;
72 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, false, offset, DynamicType_Vector))
73 | return false;
74 |
75 | return _GetVector(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, vector);
76 | }
77 |
78 | stock DynamicOffset _Dynamic_SetVector(DynamicObject dynamic, const char[] membername, const float value[3])
79 | {
80 | if (!dynamic.IsValid(true))
81 | return INVALID_DYNAMIC_OFFSET;
82 |
83 | DynamicOffset offset;
84 | if (!_Dynamic_GetMemberDataOffset(dynamic, membername, true, offset, DynamicType_Vector))
85 | return INVALID_DYNAMIC_OFFSET;
86 |
87 | Dynamic_MemberType type = _SetVector(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value, membername);
88 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
89 | return offset;
90 | }
91 |
92 | stock bool _Dynamic_GetVectorByOffset(DynamicObject dynamic, DynamicOffset offset, float[3] value)
93 | {
94 | if (!dynamic.IsValid(true))
95 | return false;
96 |
97 | return _GetVector(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
98 | }
99 |
100 | stock bool _Dynamic_SetVectorByOffset(DynamicObject dynamic, DynamicOffset offset, const float value[3])
101 | {
102 | if (!dynamic.IsValid(true))
103 | return false;
104 |
105 | Dynamic_MemberType type = _SetVector(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
106 | _Dynamic_CallOnChangedForwardByOffset(dynamic, offset, type);
107 | return true;
108 | }
109 |
110 | stock int _Dynamic_PushVector(DynamicObject dynamic, const float value[3], const char[] name="")
111 | {
112 | if (!dynamic.IsValid(true))
113 | return INVALID_DYNAMIC_INDEX;
114 |
115 | DynamicOffset offset;
116 | int memberindex = _Dynamic_CreateMemberOffset(dynamic, offset, name, DynamicType_Vector);
117 | _Dynamic_SetMemberDataVector(dynamic.Data, offset.Index, offset.Cell, dynamic.BlockSize, value);
118 | _Dynamic_CallOnChangedForward(dynamic, offset, name, DynamicType_Vector);
119 | return memberindex;
120 | }
121 |
122 | stock bool _Dynamic_GetVectorByIndex(DynamicObject dynamic, int memberindex, float value[3])
123 | {
124 | if (!dynamic.IsValid(true))
125 | return false;
126 |
127 | DynamicOffset offset = _Dynamic_GetMemberOffsetByIndex(dynamic, memberindex);
128 | if (offset == INVALID_DYNAMIC_OFFSET)
129 | return false;
130 |
131 | return _Dynamic_GetVectorByOffset(dynamic, offset, value);
132 | }
133 |
134 | stock bool _Dynamic_GetMemberDataVector(ArrayList data, int position, int offset, int blocksize, float vector[3])
135 | {
136 | // A vector has 3 cells of data to be retrieved
137 | for (int i=0; i<3; i++)
138 | {
139 | // Move the offset forward by one cell as this is where the value is stored
140 | offset++;
141 |
142 | // Calculate internal data array index and cell position
143 | _Dynamic_RecalculateOffset(position, offset, blocksize);
144 |
145 | // Get the value
146 | vector[i] = data.Get(position, offset);
147 | }
148 | return true;
149 | }
150 |
151 | stock void _Dynamic_SetMemberDataVector(ArrayList data, int position, int offset, int blocksize, const float value[3])
152 | {
153 | // A vector has 3 cells of data to be stored
154 | for (int i=0; i<3; i++)
155 | {
156 | // Move the offset forward by one cell as this is where the value is stored
157 | offset++;
158 |
159 | // Calculate internal data array index and cell position
160 | _Dynamic_RecalculateOffset(position, offset, blocksize);
161 |
162 | // Set the value
163 | SetArrayCell(data, position, value[i], offset);
164 | }
165 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/flatconfigs.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_flatconfigs
21 | #endinput
22 | #endif
23 | #define _dynamic_system_flatconfigs
24 |
25 | stock bool _Dynamic_ReadConfig(DynamicObject dynamic, const char[] path, bool use_valve_fs=false, int valuelength=128)
26 | {
27 | if (!dynamic.IsValid(true))
28 | return false;
29 |
30 | // Check file exists
31 | if (!FileExists(path, use_valve_fs))
32 | {
33 | ThrowNativeError(0, "Filepath '%s' doesn't exist!", path);
34 | return false;
35 | }
36 |
37 | // Open file for reading
38 | File stream = OpenFile(path, "r", use_valve_fs);
39 |
40 | // Exit if failed to open
41 | if (stream == null)
42 | {
43 | ThrowNativeError(0, "Unable to open file stream '%s'!", path);
44 | return false;
45 | }
46 |
47 | // Loop through file in blocks
48 | char buffer[16];
49 | bool readingname = true;
50 | bool readingstring = false;
51 | bool readingvalue = false;
52 | int lastchar = 0;
53 | bool skippingcomment = false;
54 | ArrayList settingnamearray = CreateArray(1);
55 | int settingnamelength = 0;
56 | ArrayList settingvaluearray = CreateArray(1);
57 | int settingvaluelength = 0;
58 | int length;
59 |
60 | while ((length = stream.ReadString(buffer, sizeof(buffer))) > 0)
61 | {
62 | for (int i = 0; i < length; i++)
63 | {
64 | int byte = buffer[i];
65 |
66 | // space and tabspace
67 | if (byte == 9 || byte == 32)
68 | {
69 | // continue if skipping comments
70 | if (skippingcomment)
71 | continue;
72 |
73 | if (readingname)
74 | {
75 | if (readingstring)
76 | {
77 | settingvaluearray.Push(byte);
78 | settingvaluelength++;
79 | }
80 | else
81 | {
82 | readingname = false;
83 | readingvalue = true;
84 | }
85 | }
86 |
87 | else if (readingvalue)
88 | {
89 | if (readingstring)
90 | {
91 | settingvaluearray.Push(byte);
92 | settingvaluelength++;
93 | }
94 | else
95 | {
96 | //if (settingvaluelength > 0)
97 | // skippingcomment = true;
98 | }
99 | }
100 | }
101 |
102 | // new line
103 | else if (byte == 10)
104 | {
105 | readingname = true;
106 | readingstring = false;
107 | readingvalue = false;
108 |
109 | if (skippingcomment)
110 | {
111 | skippingcomment = false;
112 | continue;
113 | }
114 |
115 | AddConfigSetting(dynamic, settingnamearray, settingnamelength, settingvaluearray, settingvaluelength, valuelength);
116 | settingnamelength = 0;
117 | settingvaluelength = 0;
118 | }
119 |
120 | // quote
121 | else if (byte == 34)
122 | {
123 | readingstring = !readingstring;
124 |
125 | if (!readingstring && readingvalue)
126 | {
127 | AddConfigSetting(dynamic, settingnamearray, settingnamelength, settingvaluearray, settingvaluelength, valuelength);
128 | settingnamelength = 0;
129 | settingvaluelength = 0;
130 | skippingcomment = true;
131 | }
132 | }
133 | else
134 | {
135 | // continue if skipping a comment
136 | if (skippingcomment)
137 | continue;
138 |
139 | // skip double backslash comments
140 | if (byte == 92 && lastchar == 92)
141 | {
142 | skippingcomment = true;
143 | settingnamearray.Clear();
144 | settingnamelength = 0;
145 | settingvaluelength = 0;
146 | continue;
147 | }
148 |
149 | // skip double forward slash comments
150 | if (byte == 47 && lastchar == 47)
151 | {
152 | skippingcomment = true;
153 | settingnamearray.Clear();
154 | settingnamelength = 0;
155 | settingvaluelength = 0;
156 | continue;
157 | }
158 |
159 | lastchar = byte;
160 | if (readingname)
161 | {
162 | settingnamearray.Push(byte);
163 | settingnamelength++;
164 | }
165 | else if (readingvalue)
166 | {
167 | settingvaluearray.Push(byte);
168 | settingvaluelength++;
169 | }
170 | }
171 | }
172 | }
173 |
174 | delete stream;
175 | delete settingnamearray;
176 | delete settingvaluearray;
177 | return true;
178 | }
179 |
180 | stock void AddConfigSetting(DynamicObject dynamic, ArrayList name, int namelength, ArrayList value, int valuelength, int maxlength)
181 | {
182 | char[] settingname = new char[namelength];
183 | GetArrayStackAsString(name, settingname, namelength);
184 | name.Clear();
185 |
186 | char[] settingvalue = new char[valuelength];
187 | GetArrayStackAsString(value, settingvalue, valuelength);
188 | value.Clear();
189 |
190 | CreateMemberFromString(dynamic, settingname, settingvalue, maxlength);
191 | }
192 |
193 | stock Dynamic_MemberType CreateMemberFromString(DynamicObject dynamic, const char[] membername, const char[] value, int maxlength)
194 | {
195 | bool canbeint = true;
196 | bool canbefloat = false;
197 | int byte;
198 | int val;
199 |
200 | for (int i = 0; (byte = value[i]) != 0; i++)
201 | {
202 | // 48 = `0`, 57 = `9`, 46 = `.`, 45 = `-`
203 | if (byte < 48 || byte > 57)
204 | {
205 | // allow negative
206 | if (i == 0 && byte == 45)
207 | continue;
208 |
209 | // cant be an int anymore
210 | canbeint = false;
211 |
212 | // allow floats
213 | if (byte == 46)
214 | {
215 | // dont allow multiple periods
216 | if (canbefloat)
217 | {
218 | canbefloat = false;
219 | break;
220 | }
221 | canbeint = false;
222 | canbefloat = true;
223 | }
224 | }
225 |
226 | if (!canbeint && !canbefloat)
227 | break;
228 | }
229 |
230 | if (canbeint)
231 | {
232 | // Longs need to be stored as strings
233 | val = StringToInt(value);
234 | if (val == -1 && !StrEqual(value, "-1"))
235 | {
236 | _Dynamic_SetString(dynamic, membername, value, maxlength, maxlength);
237 | return DynamicType_String;
238 | }
239 | else
240 | {
241 | _Dynamic_SetInt(dynamic, membername, val);
242 | return DynamicType_Int;
243 | }
244 | }
245 | else if (canbefloat)
246 | {
247 | _Dynamic_SetFloat(dynamic, membername, StringToFloat(value));
248 | return DynamicType_Float;
249 | }
250 | else
251 | {
252 | // make regex if required
253 | if (g_sRegex_Vector == null)
254 | g_sRegex_Vector = CompileRegex("^\\{ ?+([-+]?[0-9]*\\.?[0-9]+) ?+, ?+([-+]?[0-9]*\\.?[0-9]+) ?+, ?+([-+]?[0-9]*\\.?[0-9]+) ?+\\}$");
255 |
256 | // check for vector
257 | int count = MatchRegex(g_sRegex_Vector, value);
258 | if (count == 4)
259 | {
260 | float vec[3];
261 | char matchbuffer[64];
262 |
263 | GetRegexSubString(g_sRegex_Vector, 1, matchbuffer, sizeof(matchbuffer));
264 | vec[0] = StringToFloat(matchbuffer);
265 |
266 | GetRegexSubString(g_sRegex_Vector, 2, matchbuffer, sizeof(matchbuffer));
267 | vec[1] = StringToFloat(matchbuffer);
268 |
269 | GetRegexSubString(g_sRegex_Vector, 3, matchbuffer, sizeof(matchbuffer));
270 | vec[2] = StringToFloat(matchbuffer);
271 |
272 | _Dynamic_SetVector(dynamic, membername, vec);
273 | return DynamicType_Vector;
274 | }
275 |
276 | // check for bool last
277 | if (StrEqual(value, "true", false))
278 | {
279 | _Dynamic_SetBool(dynamic, membername, true);
280 | return DynamicType_Bool;
281 | }
282 | else if (StrEqual(value, "false", false))
283 | {
284 | _Dynamic_SetBool(dynamic, membername, false);
285 | return DynamicType_Bool;
286 | }
287 |
288 | _Dynamic_SetString(dynamic, membername, value, maxlength, maxlength);
289 | return DynamicType_String;
290 | }
291 | }
292 |
293 | stock bool GetVectorFromString(const char[] input, float output[3])
294 | {
295 | // make regex if required
296 | if (g_sRegex_Vector == null)
297 | g_sRegex_Vector = CompileRegex("^\\{ ?+([-+]?[0-9]*\\.?[0-9]+) ?+, ?+([-+]?[0-9]*\\.?[0-9]+) ?+, ?+([-+]?[0-9]*\\.?[0-9]+) ?+\\}$");
298 |
299 | // check for vector
300 | int count = MatchRegex(g_sRegex_Vector, input);
301 | if (count == 4)
302 | {
303 | char buffer[64];
304 |
305 | GetRegexSubString(g_sRegex_Vector, 1, buffer, sizeof(buffer));
306 | output[0] = StringToFloat(buffer);
307 |
308 | GetRegexSubString(g_sRegex_Vector, 2, buffer, sizeof(buffer));
309 | output[1] = StringToFloat(buffer);
310 |
311 | GetRegexSubString(g_sRegex_Vector, 3, buffer, sizeof(buffer));
312 | output[2] = StringToFloat(buffer);
313 | return true;
314 | }
315 | return false;
316 | }
317 |
318 | stock void GetArrayStackAsString(ArrayList stack, char[] buffer, int length)
319 | {
320 | for (int i = 0; i < length; i++)
321 | {
322 | buffer[i] = view_as(stack.Get(i));
323 | }
324 | }
325 |
326 | stock bool _Dynamic_WriteConfig(DynamicObject dynamic, const char[] path)
327 | {
328 | if (!dynamic.IsValid(true))
329 | return false;
330 |
331 | // Open file for writting
332 | File stream = OpenFile(path, "w", false);
333 |
334 | // Exit if failed to open
335 | if (stream == null)
336 | {
337 | ThrowNativeError(0, "Unable to open file stream '%s'!", path);
338 | return false;
339 | }
340 |
341 | int count = _Dynamic_GetMemberCount(dynamic);
342 | DynamicOffset memberoffset;
343 | int length;
344 | char membername[DYNAMIC_MEMBERNAME_MAXLEN];
345 | for (int i = 0; i < count; i++)
346 | {
347 | memberoffset = _Dynamic_GetMemberOffsetByIndex(dynamic, i);
348 | _Dynamic_GetMemberNameByIndex(dynamic, i, membername, sizeof(membername));
349 |
350 | switch (_Dynamic_GetMemberTypeByOffset(dynamic, memberoffset))
351 | {
352 | case DynamicType_Int:
353 | {
354 | int value = _Dynamic_GetIntByOffset(dynamic, memberoffset);
355 | stream.WriteLine("%s\t\"%d\"", membername, value);
356 | }
357 | case DynamicType_Bool:
358 | {
359 | bool value = _Dynamic_GetBoolByOffset(dynamic, memberoffset);
360 | stream.WriteLine("%s\t\"%d\"", membername, value);
361 | }
362 | case DynamicType_Float:
363 | {
364 | float value = _Dynamic_GetFloatByOffset(dynamic, memberoffset);
365 | stream.WriteLine("%s\t\"%f\"", membername, value);
366 | }
367 | case DynamicType_String:
368 | {
369 | length = _Dynamic_GetStringLengthByOffset(dynamic, memberoffset);
370 | char[] value = new char[length];
371 | _Dynamic_GetStringByOffset(dynamic, memberoffset, value, length);
372 | stream.WriteLine("%s\t\"%s\"", membername, value);
373 | }
374 | case DynamicType_Object:
375 | {
376 | LogError("Unable to serialise type Dynamic in flat config!");
377 | }
378 | case DynamicType_Handle:
379 | {
380 | LogError("Unable to serialise type Handle in flat config!");
381 | }
382 | case DynamicType_Vector:
383 | {
384 | float value[3];
385 | _Dynamic_GetVectorByOffset(dynamic, memberoffset, value);
386 | stream.WriteLine("%s\t\"{%f, %f, %f}\"", membername, value[0], value[1], value[2]);
387 | }
388 | default:
389 | {
390 | LogError("Unable to serialise type Unknown in flat config!");
391 | }
392 | }
393 | }
394 |
395 | delete stream;
396 | return true;
397 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/handleusage.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_handleusage
21 | #endinput
22 | #endif
23 | #define _dynamic_system_handleusage
24 |
25 | public void _Dynamic_HandleUsage(any userid)
26 | {
27 | int client = 0;
28 | if (userid > 0)
29 | {
30 | client = GetClientOfUserId(userid);
31 | if (!IsClientConnected(client))
32 | client = 0;
33 | }
34 |
35 | _Dynamic_HandleUsage_TotalHandleCount(client);
36 |
37 | // Loop plugins
38 | Handle iterator = GetPluginIterator();
39 | Handle plugin;
40 | while (MorePlugins(iterator))
41 | {
42 | plugin = ReadPlugin(iterator);
43 | _Dynamic_HandleUsage_CountPluginHandles(plugin, client);
44 | }
45 | CloseHandle(iterator);
46 | }
47 |
48 | stock void _Dynamic_HandleUsage_TotalHandleCount(int client)
49 | {
50 | int count = 0;
51 | int persistant = 0;
52 | DynamicObject dynamic;
53 | for (int i = MAXPLAYERS; i < s_CollectionSize; i++)
54 | {
55 | dynamic = view_as(i);
56 |
57 | // Skip disposed objects
58 | if (!dynamic.IsValid(false))
59 | continue;
60 |
61 | if (dynamic.Persistent)
62 | persistant++;
63 |
64 | count++;
65 | }
66 |
67 | ReplyToCommand(client, "-> Total Handles: %d (%d persistant handles)", count, persistant);
68 | }
69 |
70 | stock void _Dynamic_HandleUsage_CountPluginHandles(Handle plugin, int client)
71 | {
72 | int count = 0;
73 | int persistant = 0;
74 |
75 | DynamicObject dynamic;
76 | for (int i = MAXPLAYERS; i < s_CollectionSize; i++)
77 | {
78 | dynamic = view_as(i);
79 |
80 | // Skip disposed objects
81 | if (!dynamic.IsValid(false))
82 | continue;
83 |
84 | if (dynamic.OwnerPluginHandle == plugin)
85 | {
86 | if (dynamic.Persistent)
87 | persistant++;
88 |
89 | count++;
90 | }
91 | }
92 |
93 | if (count == 0)
94 | return;
95 |
96 | char pluginname[64];
97 | GetPluginInfo(plugin, PlInfo_Name, pluginname, sizeof(pluginname));
98 | ReplyToCommand(client, "--> `%s`: %d Handles (%d persistant handles)", pluginname, count, persistant);
99 | }
100 |
--------------------------------------------------------------------------------
/scripting/dynamic/system/hooks.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_hooks
21 | #endinput
22 | #endif
23 | #define _dynamic_system_hooks
24 |
25 | stock bool _Dynamic_HookChanges(DynamicObject dynamic, Dynamic_HookType callback, Handle plugin)
26 | {
27 | if (!dynamic.IsValid(true))
28 | return false;
29 |
30 | Handle forwards = dynamic.Forwards;
31 | if (forwards == null)
32 | dynamic.Forwards = forwards = CreateForward(ET_Ignore, Param_Cell, Param_Cell, Param_String, Param_Cell);
33 |
34 | // Add forward to objects forward list
35 | AddToForward(forwards, plugin, callback);
36 |
37 | // Increment callback count
38 | dynamic.HookCount++;
39 | return true;
40 | }
41 |
42 | stock bool _Dynamic_UnHookChanges(DynamicObject dynamic, Dynamic_HookType callback, Handle plugin)
43 | {
44 | if (!dynamic.IsValid(true))
45 | return false;
46 |
47 | Handle forwards = dynamic.Forwards;
48 | if (forwards == null)
49 | dynamic.Forwards = forwards = CreateForward(ET_Ignore, Param_Cell, Param_Cell, Param_String, Param_Cell);
50 |
51 | // Remove forward from objects forward list
52 | RemoveFromForward(forwards, plugin, callback);
53 |
54 | // Decrement callback count
55 | if (--dynamic.HookCount == 0)
56 | {
57 | // Remove unused handle
58 | CloseHandle(forwards);
59 | dynamic.Forwards = null;
60 | }
61 | return true;
62 | }
63 |
64 | stock int _Dynamic_HookCount(DynamicObject dynamic)
65 | {
66 | if (!dynamic.IsValid(true))
67 | return 0;
68 |
69 | return dynamic.HookCount;
70 | }
71 |
72 | stock void _Dynamic_CallOnChangedForward(DynamicObject dynamic, DynamicOffset offset, const char[] member, Dynamic_MemberType type)
73 | {
74 | Handle forwards = dynamic.Forwards;
75 | if (forwards == null)
76 | return;
77 |
78 | Call_StartForward(forwards);
79 | Call_PushCell(dynamic);
80 | Call_PushCell(offset);
81 | Call_PushString(member);
82 | Call_PushCell(type);
83 | Call_Finish();
84 | }
85 |
86 | stock void _Dynamic_CallOnChangedForwardByOffset(DynamicObject dynamic, DynamicOffset offset, Dynamic_MemberType type)
87 | {
88 | if (dynamic.HookCount > 0)
89 | {
90 | char membername[DYNAMIC_MEMBERNAME_MAXLEN];
91 | _Dynamic_GetMemberNameByOffset(dynamic, offset, membername, sizeof(membername));
92 | _Dynamic_CallOnChangedForward(dynamic, offset, membername, type);
93 | }
94 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/keyvalues.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_keyvalues
21 | #endinput
22 | #endif
23 | #define _dynamic_system_keyvalues
24 |
25 | stock bool _Dynamic_ReadKeyValues(Handle plugin, DynamicObject dynamic, const char[] path, int valuelength=128, Dynamic_HookType hook=INVALID_FUNCTION)
26 | {
27 | if (!dynamic.IsValid(true))
28 | return false;
29 |
30 | // Check file exists
31 | if (!FileExists(path, false))
32 | {
33 | ThrowNativeError(0, "Filepath '%s' doesn't exist!", path);
34 | return false;
35 | }
36 |
37 | KeyValues kv = new KeyValues("");
38 | kv.SetEscapeSequences(true);
39 | if (!kv.ImportFromFile(path))
40 | {
41 | delete kv;
42 | return false;
43 | }
44 |
45 | Handle callbackforward = null;
46 | if (hook != INVALID_FUNCTION)
47 | {
48 | callbackforward = CreateForward(ET_Single, Param_Cell, Param_String, Param_Cell);
49 | AddToForward(callbackforward, plugin, hook);
50 | }
51 |
52 | IterateKeyValues(plugin, kv, dynamic, valuelength, callbackforward);
53 | delete kv;
54 |
55 | if (callbackforward != null)
56 | {
57 | RemoveFromForward(callbackforward, plugin, hook);
58 | delete callbackforward;
59 | }
60 | return true;
61 | }
62 |
63 | stock void IterateKeyValues(Handle plugin, KeyValues kv, DynamicObject dynamic, int valuelength, Handle callbackforward, int depth=0)
64 | {
65 | char key[DYNAMIC_MEMBERNAME_MAXLEN];
66 | KvDataTypes type;
67 |
68 | do
69 | {
70 | kv.GetSectionName(key, sizeof(key));
71 | if (kv.GotoFirstSubKey(false))
72 | {
73 | Action result;
74 | if (callbackforward != null)
75 | {
76 | Call_StartForward(callbackforward);
77 | Call_PushCell(dynamic);
78 | Call_PushString(key);
79 | Call_PushCell(depth);
80 | Call_Finish(result);
81 | }
82 |
83 | if (result == Plugin_Continue)
84 | {
85 | if (depth == 0)
86 | {
87 | IterateKeyValues(plugin, kv, dynamic, valuelength, callbackforward, depth+1);
88 | }
89 | else
90 | {
91 | DynamicObject child = _Dynamic_GetDynamic(dynamic, key);
92 | if (!child.IsValid(false))
93 | {
94 | child = DynamicObject();
95 | child.Initialise(plugin);
96 |
97 | _Dynamic_SetDynamic(dynamic, key, child);
98 | }
99 | IterateKeyValues(plugin, kv, child, valuelength, callbackforward, depth+1);
100 | }
101 | }
102 | kv.GoBack();
103 | }
104 | else
105 | {
106 | type = kv.GetDataType(NULL_STRING);
107 | switch(type)
108 | {
109 | case KvData_String:
110 | {
111 | char[] value = new char[valuelength];
112 | kv.GetString(NULL_STRING, value, valuelength);
113 | _Dynamic_SetString(dynamic, key, value, valuelength, valuelength);
114 | }
115 | case KvData_Int:
116 | {
117 | _Dynamic_SetInt(dynamic, key, kv.GetNum(NULL_STRING));
118 | }
119 | case KvData_Float:
120 | {
121 | _Dynamic_SetFloat(dynamic, key, kv.GetFloat(NULL_STRING));
122 | }
123 | case KvData_Ptr:
124 | {
125 | LogError("Type `KvData_Ptr` not yet supported!");
126 | }
127 | case KvData_WString:
128 | {
129 | LogError("Type `KvData_WString` not yet supported!");
130 | }
131 | case KvData_Color:
132 | {
133 | LogError("Type `KvData_Color` not yet supported!");
134 | }
135 | case KvData_UInt64:
136 | {
137 | LogError("Type `KvData_UInt64` not yet supported!");
138 | }
139 | }
140 | }
141 | }
142 | while (kv.GotoNextKey(false));
143 | }
144 |
145 | stock bool _Dynamic_WriteKeyValues(DynamicObject dynamic, const char[] path, const char[] basekey)
146 | {
147 | if (!dynamic.IsValid(true))
148 | return false;
149 |
150 | // Open file for writting
151 | File stream = OpenFile(path, "w", false);
152 |
153 | // Exit if failed to open
154 | if (stream == null)
155 | {
156 | ThrowNativeError(0, "Unable to open file stream '%s'!", path);
157 | return false;
158 | }
159 |
160 | stream.WriteLine("\"%s\"", basekey);
161 | stream.WriteLine("{");
162 | _Dynamic_KeyValues_WriteDynamic(stream, dynamic, 1);
163 | stream.WriteLine("}");
164 |
165 | delete stream;
166 | return true;
167 | }
168 |
169 | stock void _Dynamic_KeyValues_WriteDynamic(File stream, DynamicObject dynamic, int indent)
170 | {
171 | // Create indent
172 | char indextext[16];
173 | for (int i = 0; i < indent; i++)
174 | indextext[i] = 9;
175 | indextext[indent] = 0;
176 | int length = 1024;
177 | char buffer[1024];
178 |
179 | int count = dynamic.MemberCount;
180 | DynamicOffset memberoffset;
181 | char membername[DYNAMIC_MEMBERNAME_MAXLEN];
182 | for (int i = 0; i < count; i++)
183 | {
184 | memberoffset = _Dynamic_GetMemberOffsetByIndex(dynamic, i);
185 | _Dynamic_GetMemberNameByIndex(dynamic, i, membername, sizeof(membername));
186 | Dynamic_MemberType type = _Dynamic_GetMemberTypeByOffset(dynamic, memberoffset);
187 |
188 | if (type == DynamicType_Dynamic)
189 | {
190 | if (StrEqual(membername, ""))
191 | stream.WriteLine("%s\"%d\"", indextext, i);
192 | else
193 | {
194 | _Dynamic_KeyValues_EscapeString(membername, buffer, sizeof(membername));
195 | stream.WriteLine("%s\"%s\"", indextext, buffer);
196 | }
197 | stream.WriteLine("%s{", indextext);
198 | _Dynamic_KeyValues_WriteDynamic(stream, _Dynamic_GetDynamicByOffset(dynamic, memberoffset), indent+1);
199 | stream.WriteLine("%s}", indextext);
200 | }
201 | else
202 | {
203 | //length = GetStringLengthByOffset(view_as(dynamic), memberoffset);
204 | char[] membervalue = new char[length];
205 | _Dynamic_GetStringByOffset(dynamic, memberoffset, membervalue, length);
206 | _Dynamic_KeyValues_EscapeString(membervalue, buffer, sizeof(buffer));
207 | stream.WriteLine("%s\"%s\"\t\"%s\"", indextext, membername, membervalue);
208 | }
209 | }
210 | }
211 |
212 | stock void _Dynamic_KeyValues_EscapeString(const char[] input, char[] output, int length)
213 | {
214 | int pos_in=0;
215 | int pos_out=0;
216 | int x;
217 | do
218 | {
219 | x = input[pos_in++];
220 | switch (x)
221 | {
222 | case 34: // `"` -> `\"`
223 | {
224 | if (pos_out+1 >= length)
225 | return;
226 |
227 | output[pos_out++] = 92;
228 | output[pos_out++] = 34;
229 | }
230 | case 92: // `\` -> `\\`
231 | {
232 | if (pos_out+1 >= length)
233 | return;
234 |
235 | output[pos_out++] = 92;
236 | output[pos_out++] = 92;
237 | }
238 | case 10: // newline -> `\n`
239 | {
240 | if (pos_out+1 >= length)
241 | return;
242 |
243 | output[pos_out++] = 92;
244 | output[pos_out++] = 110;
245 | }
246 | case 13: // linefeed -> `\r`
247 | {
248 | if (pos_out+1 >= length)
249 | return;
250 |
251 | output[pos_out++] = 92;
252 | output[pos_out++] = 114;
253 | }
254 | default:
255 | {
256 | if (pos_out == length)
257 | return;
258 |
259 | output[pos_out++] = x;
260 | }
261 | }
262 | }
263 | while(x != 0);
264 | }
--------------------------------------------------------------------------------
/scripting/dynamic/system/methodmaps/dynamicobject.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_system_methomaps_dynamicobject
21 | #endinput
22 | #endif
23 | #define _dynamic_system_methomaps_dynamicobject
24 |
25 | #define Dynamic_Index 0
26 | // Size isn't yet implement for optimisation around _Dynamic_ExpandIfRequired()
27 | #define Dynamic_Size 1
28 | #define Dynamic_Blocksize 2
29 | #define Dynamic_Offsets 3
30 | #define Dynamic_MemberNames 4
31 | #define Dynamic_Data 5
32 | #define Dynamic_Forwards 6
33 | #define Dynamic_NextOffset 7
34 | #define Dynamic_CallbackCount 8
35 | #define Dynamic_ParentObject 9
36 | #define Dynamic_MemberCount 10
37 | #define Dynamic_OwnerPlugin 11
38 | #define Dynamic_Persistent 12
39 | #define Dynamic_ParentOffset 13
40 | #define Dynamic_Field_Count 14
41 | #define me view_as(this)
42 |
43 | // this should be static
44 | ArrayList s_Collection = null;
45 |
46 | methodmap DynamicObject
47 | {
48 | public DynamicObject()
49 | {
50 | int index = PushArrayCell(s_Collection, -1);
51 | s_CollectionSize++;
52 | return view_as(index);
53 | }
54 |
55 | public void Initialise(Handle plugin, int blocksize=64, int startsize=0, bool persistent=false)
56 | {
57 | SetArrayCell(s_Collection, me, me, Dynamic_Index);
58 | SetArrayCell(s_Collection, me, 0, Dynamic_Size);
59 | SetArrayCell(s_Collection, me, blocksize, Dynamic_Blocksize);
60 | SetArrayCell(s_Collection, me, new StringMap(), Dynamic_Offsets);
61 | SetArrayCell(s_Collection, me, new ArrayList(blocksize, startsize), Dynamic_Data);
62 | SetArrayCell(s_Collection, me, 0, Dynamic_Forwards);
63 | SetArrayCell(s_Collection, me, new ArrayList(g_iDynamic_MemberLookup_Offset+1), Dynamic_MemberNames);
64 | SetArrayCell(s_Collection, me, 0, Dynamic_NextOffset);
65 | SetArrayCell(s_Collection, me, 0, Dynamic_CallbackCount);
66 | SetArrayCell(s_Collection, me, INVALID_DYNAMIC_OBJECT, Dynamic_ParentObject);
67 | SetArrayCell(s_Collection, me, INVALID_DYNAMIC_OFFSET, Dynamic_ParentOffset);
68 | SetArrayCell(s_Collection, me, 0, Dynamic_MemberCount);
69 | SetArrayCell(s_Collection, me, _Dynamic_Plugins_GetIndex(plugin), Dynamic_OwnerPlugin);
70 | SetArrayCell(s_Collection, me, persistent, Dynamic_Persistent);
71 | }
72 |
73 | public void Dispose(bool reuse=false)
74 | {
75 | CloseHandle(GetArrayCell(s_Collection, me, Dynamic_Offsets));
76 | CloseHandle(GetArrayCell(s_Collection, me, Dynamic_Data));
77 | if (GetArrayCell(s_Collection, me, Dynamic_Forwards) != 0)
78 | CloseHandle(GetArrayCell(s_Collection, me, Dynamic_Forwards));
79 | CloseHandle(GetArrayCell(s_Collection, me, Dynamic_MemberNames));
80 | if (!reuse)
81 | SetArrayCell(s_Collection, me, Invalid_Dynamic_Object, Dynamic_Index);
82 | }
83 |
84 | property int BlockSize
85 | {
86 | public get()
87 | {
88 | return GetArrayCell(s_Collection, me, Dynamic_Blocksize);
89 | }
90 | }
91 |
92 | public void Reset(int blocksize=0, int startsize=0)
93 | {
94 | SetArrayCell(s_Collection, me, CreateTrie(), Dynamic_Offsets);
95 |
96 | if (blocksize == 0)
97 | blocksize = this.BlockSize;
98 | SetArrayCell(s_Collection, me, CreateArray(blocksize, startsize), Dynamic_Data);
99 | SetArrayCell(s_Collection, me, 0, Dynamic_Forwards);
100 | SetArrayCell(s_Collection, me, CreateArray(g_iDynamic_MemberLookup_Offset+1), Dynamic_MemberNames);
101 | SetArrayCell(s_Collection, me, 0, Dynamic_NextOffset);
102 | SetArrayCell(s_Collection, me, 0, Dynamic_CallbackCount);
103 | SetArrayCell(s_Collection, me, 0, Dynamic_Size);
104 | SetArrayCell(s_Collection, me, 0, Dynamic_MemberCount);
105 | }
106 |
107 | property int Index
108 | {
109 | public get()
110 | {
111 | return me;
112 | }
113 | }
114 |
115 | public bool IsValid(bool throwerror=false, bool fromnative=true)
116 | {
117 | return _Dynamic_IsValid(me, throwerror, fromnative);
118 | }
119 |
120 | public bool GetName(char[] buffer, int length)
121 | {
122 | return _Dynamic_GetName(this, buffer, length);
123 | }
124 |
125 | public bool SetName(const char[] objectname, bool replace)
126 | {
127 | return _Dynamic_SetName(this, objectname, replace);
128 | }
129 |
130 | property int Size
131 | {
132 | public get()
133 | {
134 | return 0;
135 | }
136 | }
137 |
138 | property ArrayList MemberNames
139 | {
140 | public get()
141 | {
142 | return GetArrayCell(s_Collection, me, Dynamic_MemberNames);
143 | }
144 | }
145 |
146 | property StringMap Offsets
147 | {
148 | public get()
149 | {
150 | return GetArrayCell(s_Collection, me, Dynamic_Offsets);
151 | }
152 | }
153 |
154 | property ArrayList Data
155 | {
156 | public get()
157 | {
158 | return GetArrayCell(s_Collection, me, Dynamic_Data);
159 | }
160 | }
161 |
162 | property Handle Forwards
163 | {
164 | public get()
165 | {
166 | return GetArrayCell(s_Collection, me, Dynamic_Forwards);
167 | }
168 | public set(Handle value)
169 | {
170 | SetArrayCell(s_Collection, me, value, Dynamic_Forwards);
171 | }
172 | }
173 |
174 | property DynamicOffset NextOffset
175 | {
176 | public get()
177 | {
178 | return GetArrayCell(s_Collection, me, Dynamic_NextOffset);
179 | }
180 | public set(DynamicOffset value)
181 | {
182 | SetArrayCell(s_Collection, me, value, Dynamic_NextOffset);
183 | }
184 | }
185 |
186 | property int HookCount
187 | {
188 | public get()
189 | {
190 | return GetArrayCell(s_Collection, me, Dynamic_CallbackCount);
191 | }
192 | public set(int value)
193 | {
194 | SetArrayCell(s_Collection, me, value, Dynamic_CallbackCount);
195 | }
196 | }
197 |
198 | property DynamicObject Parent
199 | {
200 | public get()
201 | {
202 | return GetArrayCell(s_Collection, me, Dynamic_ParentObject);
203 | }
204 | public set(DynamicObject value)
205 | {
206 | SetArrayCell(s_Collection, me, value, Dynamic_ParentObject);
207 | }
208 | }
209 |
210 | property DynamicOffset ParentOffset
211 | {
212 | public get()
213 | {
214 | return GetArrayCell(s_Collection, me, Dynamic_ParentOffset);
215 | }
216 | public set(DynamicOffset value)
217 | {
218 | SetArrayCell(s_Collection, me, value, Dynamic_ParentOffset);
219 | }
220 | }
221 |
222 | property int MemberCount
223 | {
224 | public get()
225 | {
226 | return GetArrayCell(s_Collection, me, Dynamic_MemberCount);
227 | }
228 | public set(int value)
229 | {
230 | SetArrayCell(s_Collection, me, value, Dynamic_MemberCount);
231 | }
232 | }
233 |
234 | property int OwnerPlugin
235 | {
236 | public get()
237 | {
238 | return GetArrayCell(s_Collection, me, Dynamic_OwnerPlugin);
239 | }
240 | public set(int value)
241 | {
242 | SetArrayCell(s_Collection, me, value, Dynamic_OwnerPlugin);
243 | }
244 | }
245 |
246 | property Handle OwnerPluginHandle
247 | {
248 | public get()
249 | {
250 | return _Dynamic_Plugins_GetHandleFromIndex(GetArrayCell(s_Collection, me, Dynamic_OwnerPlugin));
251 | }
252 | }
253 |
254 | property bool Persistent
255 | {
256 | public get()
257 | {
258 | return GetArrayCell(s_Collection, me, Dynamic_Persistent);
259 | }
260 | public set(bool value)
261 | {
262 | SetArrayCell(s_Collection, me, value, Dynamic_Persistent);
263 | }
264 | }
265 | }
266 |
--------------------------------------------------------------------------------
/scripting/dynamic/system/plugins.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | public int _Dynamic_Plugins_GetIndex(Handle plugin)
21 | {
22 | // Return plugin handle index if already registered
23 | int index = g_aPlugins.FindValue(plugin, 0);
24 | if (index > -1)
25 | return index;
26 |
27 | // Create forward and add plugin handle
28 | Handle pluginforward = CreateForward(ET_Ignore);
29 | AddToForward(pluginforward, plugin, view_as(1));
30 |
31 | // Create new index and push plugin handle and forward
32 | index = g_aPlugins.Push(plugin);
33 | g_aPlugins.Set(index, pluginforward, 1);
34 | return index;
35 | }
36 |
37 | public bool _Dynamic_Plugins_IsLoaded(int plugin)
38 | {
39 | // Get the plugins forward handle
40 | Handle pluginforward = g_aPlugins.Get(plugin, 1);
41 |
42 | // Check if the forward still has functions assigned to it
43 | if (GetForwardFunctionCount(pluginforward) == 0)
44 | return false;
45 |
46 | return true;
47 | }
48 |
49 | public Handle _Dynamic_Plugins_GetHandleFromIndex(int plugin)
50 | {
51 | return g_aPlugins.Get(plugin);
52 | }
53 |
--------------------------------------------------------------------------------
/scripting/dynamic/system/preparedquery.sp:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | public bool _Dynamic_PreparedQuery_Compile(const char[] query, Dynamic obj)
21 | {
22 | PrintToServer("query: %s", query);
23 | int i=0;
24 | char byte;
25 |
26 | char[] buffer = new char[strlen(query)+1];
27 | int bufferpos=0;
28 |
29 | char membername[DYNAMIC_MEMBERNAME_MAXLEN];
30 | int membernamepos=0;
31 | bool readingmembername=false;
32 |
33 | bool instring=false;
34 | char stringbyte;
35 |
36 | while ((byte=query[i++]) != '\0')
37 | {
38 | // " ' ? ` = \ " LOL WITHOUT THIS QUOTE THE COMPILER THROWS AN ERROR
39 | // 034 039 063 096 061 092
40 |
41 | if (byte==96) // `
42 | {
43 | buffer[bufferpos++]=byte;
44 | if (instring)
45 | continue;
46 |
47 | readingmembername=!readingmembername;
48 |
49 | if (readingmembername)
50 | membername[membernamepos=0]='\0';
51 | else
52 | membername[membernamepos++]='\0';
53 | }
54 | else if (byte==34 || byte==39) // " or '
55 | {
56 | buffer[bufferpos++]=byte;
57 | if (instring)
58 | {
59 | if (stringbyte==byte) // same string byte
60 | {
61 | if (query[i-2] == 92) // \ " LOL WITHOUT THIS QUOTE THE COMPILER THROWS AN ERROR
62 | continue; // is escaped
63 | }
64 | else
65 | continue; // different string byte
66 |
67 | instring=false;
68 | }
69 | else
70 | {
71 | instring=true;
72 | stringbyte=byte;
73 | }
74 | }
75 | else if (byte==63) // ?
76 | {
77 | buffer[bufferpos++]='\0';
78 | obj.PushString(buffer);
79 | obj.PushString(membername);
80 | buffer[0]='\0';
81 | bufferpos=0;
82 | }
83 | else // any other char
84 | {
85 | if (readingmembername)
86 | membername[membernamepos++]=byte;
87 |
88 | buffer[bufferpos++]=byte;
89 | }
90 | }
91 | return true;
92 | }
93 |
94 | public bool _Dynamic_PreparedQuery_Prepare(Dynamic query, Database db, Dynamic parameters, char[] buffer, int buffersize)
95 | {
96 | int bufferpos = 0;
97 | int count = query.MemberCount;
98 | bool issection=true;
99 | DynamicOffset offset;
100 | int length;
101 | char membername[DYNAMIC_MEMBERNAME_MAXLEN];
102 | char valuebuffer[64];
103 | for (int i=0; i buffersize)
110 | {
111 | LogError("Buffer is to small for Dynamic.PreparedQuery() instance.");
112 | return false;
113 | }
114 | query.GetStringByOffset(offset, buffer[bufferpos], length);
115 | bufferpos+=length-2;
116 | }
117 | else
118 | {
119 | query.GetStringByIndex(i, membername, sizeof(membername));
120 | offset = parameters.GetMemberOffset(membername);
121 |
122 | if (!offset.IsValid)
123 | {
124 | LogError("Member `%s` not found in PreparedQuery.SendQuery().", membername);
125 | return false;
126 | }
127 |
128 | switch (parameters.GetMemberType(offset))
129 | {
130 | case DynamicType_Int, DynamicType_Float, DynamicType_Bool:
131 | {
132 | parameters.GetStringByOffset(offset, valuebuffer, sizeof(valuebuffer));
133 | length = strlen(valuebuffer);
134 | if (length+bufferpos > buffersize)
135 | {
136 | LogError("Buffer is to small for Dynamic.PreparedQuery() instance.");
137 | return false;
138 | }
139 | for (int x=0; x buffersize)
156 | {
157 | LogError("Buffer is to small for Dynamic.PreparedQuery() instance.");
158 | return false;
159 | }
160 | buffer[bufferpos++] = 39;
161 | strcopy(buffer[bufferpos], length, strbuffer);
162 | bufferpos+=length-1;
163 | buffer[bufferpos++] = 39;
164 | }
165 | default:
166 | {
167 | LogError("MemberType %d is not supported by PreparedQuery.SendQuery().", parameters.GetMemberType(offset));
168 | return false;
169 | }
170 | }
171 | }
172 | issection=!issection;
173 | }
174 |
175 | PrintToServer("Prepared Query: %s", buffer);
176 | return true;
177 | }
178 |
179 | public bool _Dynamic_PreparedQuery_Execute(Dynamic query, Database db, Dynamic parameters, SQLQueryCallback callback, any data, int buffersize)
180 | {
181 | char[] buffer = new char[buffersize];
182 | if (!_Dynamic_PreparedQuery_Prepare(query, db, parameters, buffer, buffersize))
183 | return false;
184 |
185 | if (callback == INVALID_FUNCTION)
186 | callback = _Dynamic_PreparedQuery_Callback;
187 |
188 | db.Query(callback, buffer, data);
189 | return true;
190 | }
191 |
192 | public void _Dynamic_PreparedQuery_Callback(Database db, DBResultSet results, const char[] error, any data)
193 | {
194 | if (results == null)
195 | LogError("Database error: %s", error);
196 | }
--------------------------------------------------------------------------------
/scripting/include/dynamic-example.inc:
--------------------------------------------------------------------------------
1 | #if defined _dynamic_class_myclass_
2 | #endinput
3 | #endif
4 | #define _dynamic_class_myclass_
5 |
6 | methodmap MyClass < Dynamic
7 | {
8 | public MyClass()
9 | {
10 | // First we make a new dymanic object
11 | Dynamic myclass = Dynamic(64, 0);
12 |
13 | // Next we will define all the members
14 | // -> We do this to force the offsets to always be in the same location
15 | // over multiple instances of the same class.
16 | myclass.SetInt("SomeInt", 0);
17 | myclass.SetFloat("SomeFloat", 0.0);
18 | myclass.SetBool("SomeBool", false);
19 | myclass.SetString("SomeString", "", 64);
20 | myclass.SetHandle("SomeHandle", null);
21 | myclass.SetObject("SomeObject", view_as(INVALID_DYNAMIC_OBJECT));
22 | myclass.SetVector("SomeVector", NULL_VECTOR);
23 | return view_as(myclass);
24 | }
25 |
26 | // Note that I use static offsets to access members.
27 | // -> This improves performance by caching member offsets
28 | // -> This is why we force the members in during the contructor
29 | // -> Failure to force members in the constructor will cause corruption
30 |
31 | property int SomeInt
32 | {
33 | public get()
34 | {
35 | static int offset = INVALID_DYNAMIC_OFFSET;
36 | if (offset == INVALID_DYNAMIC_OFFSET)
37 | {
38 | offset = this.GetMemberOffset("SomeInt");
39 | if (offset == INVALID_DYNAMIC_OFFSET)
40 | SetFailState("A serious error occured in Dynamic!");
41 | }
42 | return this.GetIntByOffset(offset);
43 | }
44 | public set(int value)
45 | {
46 | static int offset = INVALID_DYNAMIC_OFFSET;
47 | if (offset == INVALID_DYNAMIC_OFFSET)
48 | {
49 | offset = this.GetMemberOffset("SomeInt");
50 | if (offset == INVALID_DYNAMIC_OFFSET)
51 | {
52 | offset = this.SetInt("SomeInt", value);
53 | return;
54 | }
55 | }
56 | this.SetIntByOffset(offset, value);
57 | }
58 | }
59 |
60 | property float SomeFloat
61 | {
62 | public get()
63 | {
64 | static int offset = INVALID_DYNAMIC_OFFSET;
65 | if (offset == INVALID_DYNAMIC_OFFSET)
66 | {
67 | offset = this.GetMemberOffset("SomeFloat");
68 | if (offset == INVALID_DYNAMIC_OFFSET)
69 | SetFailState("A serious error occured in Dynamic!");
70 | }
71 | return this.GetFloatByOffset(offset);
72 | }
73 | public set(float value)
74 | {
75 | static int offset = INVALID_DYNAMIC_OFFSET;
76 | if (offset == INVALID_DYNAMIC_OFFSET)
77 | {
78 | offset = this.GetMemberOffset("SomeFloat");
79 | if (offset == INVALID_DYNAMIC_OFFSET)
80 | {
81 | offset = this.SetFloat("SomeFloat", value);
82 | return;
83 | }
84 | }
85 | this.SetFloatByOffset(offset, value);
86 | }
87 | }
88 |
89 | property bool SomeBool
90 | {
91 | public get()
92 | {
93 | static int offset = INVALID_DYNAMIC_OFFSET;
94 | if (offset == INVALID_DYNAMIC_OFFSET)
95 | {
96 | offset = this.GetMemberOffset("SomeBool");
97 | if (offset == INVALID_DYNAMIC_OFFSET)
98 | SetFailState("A serious error occured in Dynamic!");
99 | }
100 | return this.GetBoolByOffset(offset);
101 | }
102 | public set(bool value)
103 | {
104 | static int offset = INVALID_DYNAMIC_OFFSET;
105 | if (offset == INVALID_DYNAMIC_OFFSET)
106 | {
107 | offset = this.GetMemberOffset("SomeBool");
108 | if (offset == INVALID_DYNAMIC_OFFSET)
109 | {
110 | offset = this.SetBool("SomeBool", value);
111 | return;
112 | }
113 | }
114 | this.SetBoolByOffset(offset, value);
115 | }
116 | }
117 |
118 | public bool GetSomeString(char[] buffer, int length)
119 | {
120 | static int offset = INVALID_DYNAMIC_OFFSET;
121 | if (offset == INVALID_DYNAMIC_OFFSET)
122 | {
123 | offset = this.GetMemberOffset("SomeString");
124 | if (offset == INVALID_DYNAMIC_OFFSET)
125 | SetFailState("A serious error occured in Dynamic!");
126 | }
127 | this.GetStringByOffset(offset, buffer, length);
128 | return true;
129 | }
130 |
131 | public void SetSomeString(const char[] buffer)
132 | {
133 | static int offset = INVALID_DYNAMIC_OFFSET;
134 | if (offset == INVALID_DYNAMIC_OFFSET)
135 | {
136 | offset = this.GetMemberOffset("SomeString");
137 | if (offset == INVALID_DYNAMIC_OFFSET)
138 | {
139 | offset = this.SetString("SomeString", buffer);
140 | return;
141 | }
142 | }
143 | this.SetStringByOffset(offset, buffer);
144 | }
145 |
146 | property Handle SomeHandle
147 | {
148 | public get()
149 | {
150 | static int offset = INVALID_DYNAMIC_OFFSET;
151 | if (offset == INVALID_DYNAMIC_OFFSET)
152 | {
153 | offset = this.GetMemberOffset("SomeHandle");
154 | if (offset == INVALID_DYNAMIC_OFFSET)
155 | SetFailState("A serious error occured in Dynamic!");
156 | }
157 | return this.GetHandleByOffset(offset);
158 | }
159 | public set(Handle value)
160 | {
161 | static int offset = INVALID_DYNAMIC_OFFSET;
162 | if (offset == INVALID_DYNAMIC_OFFSET)
163 | {
164 | offset = this.GetMemberOffset("SomeHandle");
165 | if (offset == INVALID_DYNAMIC_OFFSET)
166 | {
167 | offset = this.SetHandle("SomeHandle", value);
168 | return;
169 | }
170 | }
171 | this.SetHandleByOffset(offset, value);
172 | }
173 | }
174 |
175 | property Dynamic SomeObject
176 | {
177 | public get()
178 | {
179 | static int offset = INVALID_DYNAMIC_OFFSET;
180 | if (offset == INVALID_DYNAMIC_OFFSET)
181 | {
182 | offset = this.GetMemberOffset("SomeObject");
183 | if (offset == INVALID_DYNAMIC_OFFSET)
184 | SetFailState("A serious error occured in Dynamic!");
185 | }
186 | return this.GetObjectByOffset(offset);
187 | }
188 | public set(Dynamic value)
189 | {
190 | static int offset = INVALID_DYNAMIC_OFFSET;
191 | if (offset == INVALID_DYNAMIC_OFFSET)
192 | {
193 | offset = this.GetMemberOffset("SomeObject");
194 | if (offset == INVALID_DYNAMIC_OFFSET)
195 | {
196 | offset = this.SetObject("SomeObject", value);
197 | return;
198 | }
199 | }
200 | this.SetObjectByOffset(offset, value);
201 | }
202 | }
203 |
204 | public bool GetSomeVector(float[3] value)
205 | {
206 | static int offset = INVALID_DYNAMIC_OFFSET;
207 | if (offset == INVALID_DYNAMIC_OFFSET)
208 | {
209 | offset = this.GetMemberOffset("SomeVector");
210 | if (offset == INVALID_DYNAMIC_OFFSET)
211 | SetFailState("A serious error occured in Dynamic!");
212 | }
213 | this.GetVectorByOffset(offset, value);
214 | return true;
215 | }
216 |
217 | public void SetSomeVector(const float[3] value)
218 | {
219 | static int offset = INVALID_DYNAMIC_OFFSET;
220 | if (offset == INVALID_DYNAMIC_OFFSET)
221 | {
222 | offset = this.GetMemberOffset("SomeVector");
223 | if (offset == INVALID_DYNAMIC_OFFSET)
224 | {
225 | offset = this.SetVector("SomeVector", value);
226 | return;
227 | }
228 | }
229 | this.SetVectorByOffset(offset, value);
230 | }
231 | }
--------------------------------------------------------------------------------
/scripting/include/dynamic.inc:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_included
21 | #endinput
22 | #endif
23 | #define _dynamic_included
24 |
25 | #define INVALID_DYNAMIC_OBJECT view_as(-1)
26 | #define Invalid_Dynamic_Object -1
27 | #define INVALID_DYNAMIC_OFFSET view_as(-1)
28 | #define INVALID_DYNAMIC_INDEX -1
29 | #define DYNAMIC_MEMBERNAME_MAXLEN 64
30 |
31 | enum Dynamic_MemberType
32 | {
33 | DynamicType_Int = 0,
34 | DynamicType_Float = 1,
35 | DynamicType_String = 2,
36 | DynamicType_Object = 3,
37 | DynamicType_Dynamic = 3,
38 | DynamicType_Bool = 4,
39 | DynamicType_Handle = 5,
40 | DynamicType_Vector = 6,
41 | DynamicType_Function = 7,
42 | DynamicType_Unknown = 8
43 | }
44 |
45 | enum Dynamic_Operator
46 | {
47 | DynamicOperator_Equals=0,
48 | DynamicOperator_NotEquals,
49 | }
50 |
51 | typeset Dynamic_HookType
52 | {
53 | // HookChanges
54 | function void (Dynamic obj, DynamicOffset offset, const char[] member, Dynamic_MemberType type);
55 |
56 | // DynamicReadKeyValue
57 | function Action (Dynamic obj, const char[] member, int depth);
58 | }
59 |
60 | #include
61 | #include
62 | #include
63 | #include
64 | #include
65 | #include
66 |
67 | public SharedPlugin __pl_dynamic =
68 | {
69 | name = "dynamic",
70 | file = "dynamic.smx",
71 | #if defined REQUIRE_PLUGIN
72 | required = 1,
73 | #else
74 | required = 0,
75 | #endif
76 | };
--------------------------------------------------------------------------------
/scripting/include/dynamic/methodmaps/basic.inc:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_basic_included
21 | #endinput
22 | #endif
23 | #define _dynamic_basic_included
24 |
25 | /*
26 | This methodmap is based on the Dynamic methodmap while using a StringMap methodmap
27 | for implementation. This methodmap doesn't implement the full features of the Dynamic
28 | methodmap (type conversion, object naming, plugin sharing, ect). This methodmap can
29 | be used for basic storage using the standard Dynamic methodmap Methods.
30 |
31 | Please see '\scripting\dynamic\examples\basic\' for an example usage of this methodmap
32 | */
33 |
34 | methodmap Basic < StringMap
35 | {
36 | public Basic()
37 | {
38 | return new StringMap();
39 | }
40 |
41 | public void Dispose(bool disposemembers=true)
42 | {
43 | delete this;
44 | }
45 |
46 | public int GetInt(const char[] membername, int defaultvalue=-1)
47 | {
48 | int value;
49 | if (this.GetValue(membername, value))
50 | return value;
51 |
52 | return defaultvalue;
53 | }
54 |
55 | public void SetInt(const char[] membername, int value)
56 | {
57 | this.SetValue(membername, value);
58 | }
59 |
60 | public bool GetBool(const char[] membername, bool defaultvalue=false)
61 | {
62 | bool value;
63 | if (this.GetValue(membername, value))
64 | return value;
65 |
66 | return defaultvalue;
67 | }
68 |
69 | public void SetBool(const char[] membername, bool value)
70 | {
71 | this.SetValue(membername, value);
72 | }
73 |
74 | public float GetFloat(const char[] membername, float defaultvalue=-1.0)
75 | {
76 | float value;
77 | if (this.GetValue(membername, value))
78 | return value;
79 |
80 | return defaultvalue;
81 | }
82 |
83 | public void SetFloat(const char[] membername, float value)
84 | {
85 | this.SetValue(membername, value);
86 | }
87 |
88 | public bool GetString(const char[] membername, char[] buffer, int length)
89 | {
90 | return this.GetString(membername, buffer, length);
91 | }
92 |
93 | public void SetString(const char[] membername, const char[] value)
94 | {
95 | this.SetString(membername, value);
96 | }
97 |
98 | public Dynamic GetObject(const char[] membername)
99 | {
100 | Dynamic value;
101 | if (this.GetValue(membername, value))
102 | return value;
103 |
104 | return INVALID_DYNAMIC_OBJECT;
105 | }
106 |
107 | public void SetObject(const char[] membername, Dynamic value)
108 | {
109 | this.SetValue(membername, value);
110 | }
111 |
112 | public Handle GetHandle(const char[] membername)
113 | {
114 | Handle value;
115 | if (this.GetValue(membername, value))
116 | return value;
117 |
118 | return null;
119 | }
120 |
121 | public void SetHandle(const char[] membername, Handle value)
122 | {
123 | this.SetValue(membername, value);
124 | }
125 |
126 | public bool GetVector(const char[] membername, float[3] vector)
127 | {
128 | return this.GetArray(membername, vector, sizeof(vector));
129 | }
130 |
131 | public void SetVector(const char[] membername, const float[3] value)
132 | {
133 | this.SetArray(membername, value, sizeof(value));
134 | }
135 | }
--------------------------------------------------------------------------------
/scripting/include/dynamic/methodmaps/collection.inc:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | #if defined _dynamic_collection_included
21 | #endinput
22 | #endif
23 | #define _dynamic_collection_included
24 |
25 | /*
26 | This methodmap is used to store typed collections based on Dynamic methodmaps. Internally
27 | an ArrayList is used for storage. This methodmap can be inherited by your own methodmaps
28 | where you can override the Items method to return your custom methodmap type which MUST
29 | inherit a Dynamic methodmap.
30 |
31 | Please see '\scripting\dynamic\examples\collections\' for an example usage of this methodmap
32 | */
33 |
34 | methodmap Collection < ArrayList
35 | {
36 | public Collection()
37 | {
38 | return view_as(new ArrayList());
39 | }
40 |
41 | public void Clear(bool disposemembers=true)
42 | {
43 | if (disposemembers)
44 | {
45 | int count = this.Length;
46 | Dynamic member;
47 | for (int i = 0; i < count; i++)
48 | {
49 | member = view_as(this.Get(i));
50 | if (!member.IsValid)
51 | continue;
52 |
53 | member.Dispose();
54 | }
55 | }
56 |
57 | this.Clear();
58 | }
59 |
60 | public void Dispose(bool disposemembers=true)
61 | {
62 | if (disposemembers)
63 | this.Clear(true);
64 |
65 | CloseHandle(this);
66 | }
67 |
68 | public Dynamic Items(int index)
69 | {
70 | return this.Get(index);
71 | }
72 |
73 | property int Count
74 | {
75 | public get()
76 | {
77 | return this.Length;
78 | }
79 | }
80 |
81 | public int AddItem(Dynamic item)
82 | {
83 | this.Push(item);
84 | }
85 |
86 | public int FindItem(Dynamic item)
87 | {
88 | int count = this.Length;
89 | for (int i = 0; i < count; i++)
90 | {
91 | if (this.Get(i) == item)
92 | return i;
93 | }
94 | return -1;
95 | }
96 |
97 | public void RemoveItem(Dynamic item)
98 | {
99 | int index = this.FindItem(item);
100 | if (index == -1)
101 | return;
102 |
103 | this.Erase(index);
104 | }
105 |
106 | public void RemoveIndex(int index)
107 | {
108 | this.Erase(index);
109 | }
110 | }
--------------------------------------------------------------------------------
/scripting/include/dynamic/methodmaps/dynamic.inc:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | methodmap Dynamic
21 | {
22 | #if defined dynamic_persistent
23 | public Dynamic(int blocksize=64, int startsize=0, bool persistent=true)
24 | #else
25 | public Dynamic(int blocksize=64, int startsize=0, bool persistent=false)
26 | #endif
27 | {
28 | return Dynamic_Initialise(blocksize, startsize, persistent);
29 | }
30 |
31 | public static bool IsLoaded()
32 | {
33 | if (GetFeatureStatus(FeatureType_Native, "Native_Dynamic_Initialise") == FeatureStatus_Available)
34 | return true;
35 | else
36 | return false;
37 | }
38 |
39 | property int IsValid
40 | {
41 | public get()
42 | {
43 | return Dynamic_IsValid(view_as(this), false);
44 | }
45 | }
46 |
47 | property bool Persistent
48 | {
49 | public get()
50 | {
51 | return Dynamic_GetPersistence(this);
52 | }
53 | public set(bool value)
54 | {
55 | Dynamic_SetPersistence(this, value);
56 | }
57 | }
58 |
59 | property Dynamic Parent
60 | {
61 | public get()
62 | {
63 | return Dynamic_GetParent(this);
64 | }
65 | }
66 |
67 | public bool GetName(char[] buffer, int length)
68 | {
69 | return Dynamic_GetName(this, buffer, length);
70 | }
71 |
72 | property int MemberCount
73 | {
74 | public get()
75 | {
76 | return Dynamic_GetMemberCount(this);
77 | }
78 | }
79 |
80 | public void Dispose(bool disposemembers=true)
81 | {
82 | Dynamic_Dispose(view_as(this), disposemembers);
83 | }
84 |
85 | public bool Reset(bool disposemembers=true, int blocksize=0, int startsize=0)
86 | {
87 | return Dynamic_ResetObject(view_as(this), disposemembers, blocksize, startsize);
88 | }
89 |
90 | property Handle OwnerPlugin
91 | {
92 | public get()
93 | {
94 | return Dynamic_GetOwnerPlugin(this);
95 | }
96 | }
97 |
98 | public bool SetName(const char[] objectname, bool replace=false)
99 | {
100 | return Dynamic_SetName(this, objectname, replace);
101 | }
102 |
103 | public static Dynamic FindByName(const char[] objectname)
104 | {
105 | return Dynamic_FindByName(objectname);
106 | }
107 |
108 | public bool ReadConfig(const char[] path, bool use_valve_fs = false, int valuelength=256)
109 | {
110 | return Dynamic_ReadConfig(this, path, use_valve_fs, valuelength);
111 | }
112 |
113 | public bool WriteConfig(const char[] path)
114 | {
115 | return Dynamic_WriteConfig(this, path);
116 | }
117 |
118 | public bool ReadKeyValues(const char[] path, int valuelength = 256, Dynamic_HookType callback = INVALID_FUNCTION)
119 | {
120 | return Dynamic_ReadKeyValues(this, path, valuelength, callback);
121 | }
122 |
123 | public bool WriteKeyValues(const char[] path, const char[] basekey="")
124 | {
125 | return Dynamic_WriteKeyValues(this, path, basekey);
126 | }
127 |
128 | public static Dynamic GetSettings()
129 | {
130 | return view_as(0);
131 | }
132 |
133 | public static Dynamic GetPlayerSettings(int client)
134 | {
135 | return view_as(client);
136 | }
137 |
138 | public int GetInt(const char[] membername, int defaultvalue=-1)
139 | {
140 | return Dynamic_GetInt(this, membername, defaultvalue);
141 | }
142 |
143 | public DynamicOffset SetInt(const char[] membername, int value)
144 | {
145 | return Dynamic_SetInt(this, membername, value);
146 | }
147 |
148 | public int GetIntByOffset(DynamicOffset offset, int defaultvalue=-1)
149 | {
150 | return Dynamic_GetIntByOffset(this, offset, defaultvalue);
151 | }
152 |
153 | public void SetIntByOffset(DynamicOffset offset, int value)
154 | {
155 | Dynamic_SetIntByOffset(this, offset, value);
156 | }
157 |
158 | public int PushInt(int value, const char[] name="")
159 | {
160 | return Dynamic_PushInt(this, value, name);
161 | }
162 |
163 | public int GetIntByIndex(int index, int defaultvalue=-1)
164 | {
165 | return Dynamic_GetIntByIndex(this, index, defaultvalue);
166 | }
167 |
168 | public bool GetBool(const char[] membername, bool defaultvalue = false)
169 | {
170 | return Dynamic_GetBool(this, membername, defaultvalue);
171 | }
172 |
173 | public DynamicOffset SetBool(const char[] membername, bool value)
174 | {
175 | return Dynamic_SetBool(this, membername, value);
176 | }
177 |
178 | public bool GetBoolByOffset(DynamicOffset offset, bool defaultvalue = false)
179 | {
180 | return Dynamic_GetBoolByOffset(this, offset, defaultvalue);
181 | }
182 |
183 | public void SetBoolByOffset(DynamicOffset offset, bool value)
184 | {
185 | Dynamic_SetBoolByOffset(this, offset, value);
186 | }
187 |
188 | public int PushBool(bool value, const char[] name="")
189 | {
190 | return Dynamic_PushBool(this, value, name);
191 | }
192 |
193 | public bool GetBoolByIndex(int index, bool defaultvalue = false)
194 | {
195 | return Dynamic_GetBoolByIndex(this, index, defaultvalue);
196 | }
197 |
198 | public float GetFloat(const char[] membername, float defaultvalue=-1.0)
199 | {
200 | return Dynamic_GetFloat(this, membername, defaultvalue);
201 | }
202 |
203 | public DynamicOffset SetFloat(const char[] membername, float value)
204 | {
205 | return Dynamic_SetFloat(this, membername, value);
206 | }
207 |
208 | public float GetFloatByOffset(DynamicOffset offset, float defaultvalue=-1.0)
209 | {
210 | return Dynamic_GetFloatByOffset(this, offset, defaultvalue);
211 | }
212 |
213 | public void SetFloatByOffset(DynamicOffset offset, float value)
214 | {
215 | Dynamic_SetFloatByOffset(this, offset, value);
216 | }
217 |
218 | public int PushFloat(float value, const char[] name="")
219 | {
220 | return Dynamic_PushFloat(this, value, name);
221 | }
222 |
223 | public float GetFloatByIndex(int index, float defaultvalue=-1.0)
224 | {
225 | return Dynamic_GetFloatByIndex(this, index, defaultvalue);
226 | }
227 |
228 | public bool GetString(const char[] membername, char[] buffer, int length)
229 | {
230 | return Dynamic_GetString(this, membername, buffer, length);
231 | }
232 |
233 | public DynamicOffset SetString(const char[] membername, const char[] value, int length=0)
234 | {
235 | return Dynamic_SetString(this, membername, value, length);
236 | }
237 |
238 | public bool GetStringByOffset(DynamicOffset offset, char[] buffer, int length)
239 | {
240 | return Dynamic_GetStringByOffset(this, offset, buffer, length);
241 | }
242 |
243 | public void SetStringByOffset(const DynamicOffset offset, const char[] value)
244 | {
245 | Dynamic_SetStringByOffset(this, offset, value);
246 | }
247 |
248 | public int PushString(const char[] value, int length=0, const char[] name="")
249 | {
250 | return Dynamic_PushString(this, value, length, name);
251 | }
252 |
253 | public bool GetStringByIndex(int index, char[] buffer, int length)
254 | {
255 | return Dynamic_GetStringByIndex(this, index, buffer, length);
256 | }
257 |
258 | public int GetStringLength(const char[] membername)
259 | {
260 | return Dynamic_GetStringLength(this, membername);
261 | }
262 |
263 | public int GetStringLengthByOffset(DynamicOffset offset)
264 | {
265 | return Dynamic_GetStringLengthByOffset(this, offset);
266 | }
267 |
268 | public bool CompareString(const char[] membername, const char[] value, bool casesensitive=true)
269 | {
270 | return Dynamic_CompareString(this, membername, value, casesensitive);
271 | }
272 |
273 | public Dynamic GetDynamic(const char[] membername)
274 | {
275 | return Dynamic_GetDynamic(this, membername);
276 | }
277 |
278 | public DynamicOffset SetDynamic(const char[] membername, Dynamic value)
279 | {
280 | return Dynamic_SetDynamic(this, membername, value);
281 | }
282 |
283 | public Dynamic GetDynamicByOffset(DynamicOffset offset)
284 | {
285 | return Dynamic_GetDynamicByOffset(this, offset);
286 | }
287 |
288 | public void SetDynamicByOffset(DynamicOffset offset, Dynamic value)
289 | {
290 | Dynamic_SetDynamicByOffset(this, offset, value);
291 | }
292 |
293 | public int PushDynamic(Dynamic value, const char[] name="")
294 | {
295 | return Dynamic_PushDynamic(this, value, name);
296 | }
297 |
298 | public Dynamic GetDynamicByIndex(int index)
299 | {
300 | return Dynamic_GetDynamicByIndex(this, index);
301 | }
302 |
303 | public bool SetDynamicByIndex(int index, Dynamic value)
304 | {
305 | return Dynamic_SetDynamicByIndex(this, index, value);
306 | }
307 |
308 | public Handle GetHandle(const char[] membername)
309 | {
310 | return Dynamic_GetHandle(this, membername);
311 | }
312 |
313 | public DynamicOffset SetHandle(const char[] membername, Handle value)
314 | {
315 | return Dynamic_SetHandle(this, membername, value);
316 | }
317 |
318 | public Handle GetHandleByOffset(DynamicOffset offset)
319 | {
320 | return Dynamic_GetHandleByOffset(this, offset);
321 | }
322 |
323 | public void SetHandleByOffset(DynamicOffset offset, Handle value)
324 | {
325 | Dynamic_SetHandleByOffset(this, offset, value);
326 | }
327 |
328 | public int PushHandle(Handle value, const char[] name="")
329 | {
330 | return Dynamic_PushHandle(this, value, name);
331 | }
332 |
333 | public Handle GetHandleByIndex(int index)
334 | {
335 | return Dynamic_GetHandleByIndex(this, index);
336 | }
337 |
338 | public bool GetVector(const char[] membername, float value[3])
339 | {
340 | return Dynamic_GetVector(this, membername, value);
341 | }
342 |
343 | public DynamicOffset SetVector(const char[] membername, const float value[3])
344 | {
345 | return Dynamic_SetVector(this, membername, value);
346 | }
347 |
348 | public bool GetVectorByOffset(DynamicOffset offset, float[3] value)
349 | {
350 | return Dynamic_GetVectorByOffset(this, offset, value);
351 | }
352 |
353 | public void SetVectorByOffset(DynamicOffset offset, const float[3] value)
354 | {
355 | Dynamic_SetVectorByOffset(this, offset, value);
356 | }
357 |
358 | public int PushVector(const float value[3], const char[] name="")
359 | {
360 | return Dynamic_PushVector(this, value, name);
361 | }
362 |
363 | public bool GetVectorByIndex(int index, float[3] value)
364 | {
365 | return Dynamic_GetVectorByIndex(this, index, value);
366 | }
367 |
368 | public Function GetFunction(const char[] membername)
369 | {
370 | return Dynamic_GetFunction(this, membername);
371 | }
372 |
373 | public DynamicOffset SetFunction(const char[] membername, Function value)
374 | {
375 | return Dynamic_SetFunction(this, membername, value);
376 | }
377 |
378 | public Function GetFunctionByOffset(DynamicOffset offset)
379 | {
380 | return Dynamic_GetFunctionByOffset(this, offset);
381 | }
382 |
383 | public void SetFunctionByOffset(DynamicOffset offset, Function value)
384 | {
385 | Dynamic_SetFunctionByOffset(this, offset, value);
386 | }
387 |
388 | public int PushFunction(Function value, const char[] name="")
389 | {
390 | return Dynamic_PushFunction(this, value, name);
391 | }
392 |
393 | public Function GetFunctionByIndex(int index)
394 | {
395 | return Dynamic_GetFunctionByIndex(this, index);
396 | }
397 |
398 | public void HookChanges(Dynamic_HookType callback)
399 | {
400 | Dynamic_HookChanges(this, callback);
401 | }
402 |
403 | public void UnHookChanges(Dynamic_HookType callback)
404 | {
405 | Dynamic_UnHookChanges(this, callback);
406 | }
407 |
408 | public int CallbackCount()
409 | {
410 | return Dynamic_CallbackCount(this);
411 | }
412 |
413 | public DynamicOffset GetMemberOffset(const char[] membername)
414 | {
415 | return Dynamic_GetMemberOffset(this, membername);
416 | }
417 |
418 | public Dynamic_MemberType GetMemberType(DynamicOffset offset)
419 | {
420 | return Dynamic_GetMemberTypeByOffset(this, offset);
421 | }
422 |
423 | public bool GetMemberNameByIndex(int index, char[] buffer, int length)
424 | {
425 | return Dynamic_GetMemberNameByIndex(this, index, buffer, length);
426 | }
427 |
428 | public DynamicOffset GetMemberOffsetByIndex(int index)
429 | {
430 | return Dynamic_GetMemberOffsetByIndex(this, index);
431 | }
432 |
433 | public bool GetMemberNameByOffset(DynamicOffset offset, char[] buffer, int length)
434 | {
435 | return Dynamic_GetMemberNameByOffset(this, offset, buffer, length);
436 | }
437 |
438 | public bool SortMembers(SortOrder order = Sort_Ascending)
439 | {
440 | return Dynamic_SortMembers(this, order);
441 | }
442 |
443 | public ArrayList FindByMemberValue(Dynamic params)
444 | {
445 | return Dynamic_FindByMemberValue(this, params);
446 | }
447 |
448 | public void CloseHandleByOffset(DynamicOffset offset)
449 | {
450 | Handle handle = this.GetHandleByOffset(offset);
451 | delete handle;
452 | this.SetHandleByOffset(offset, null);
453 | }
454 |
455 | public void CloseHandle(const char[] membername)
456 | {
457 | DynamicOffset offset = this.GetMemberOffset(membername);
458 | if (offset == INVALID_DYNAMIC_OFFSET)
459 | return;
460 |
461 | this.CloseHandleByOffset(offset);
462 | }
463 | }
464 |
--------------------------------------------------------------------------------
/scripting/include/dynamic/methodmaps/dynamicoffset.inc:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | methodmap DynamicOffset
21 | {
22 | public DynamicOffset(int index, int cell)
23 | {
24 | return view_as(index << 16 | cell);
25 | }
26 |
27 | property int Index
28 | {
29 | public get()
30 | {
31 | return view_as(this) >>> 16;
32 | }
33 | }
34 |
35 | property int Cell
36 | {
37 | public get()
38 | {
39 | return view_as(this) & 0xFFFF;
40 | }
41 | }
42 |
43 | property bool IsValid
44 | {
45 | public get()
46 | {
47 | if (this == INVALID_DYNAMIC_OFFSET)
48 | return false;
49 | return true;
50 | }
51 | }
52 |
53 | public DynamicOffset Clone(int blocksize, int addcells)
54 | {
55 | if (addcells == 0)
56 | {
57 | return this;
58 | }
59 |
60 | int index = this.Index;
61 | int cell = this.Cell + addcells;
62 |
63 | while (cell >= blocksize)
64 | {
65 | index++;
66 | cell-=blocksize;
67 | }
68 |
69 | return DynamicOffset(index, cell);
70 | }
71 | }
--------------------------------------------------------------------------------
/scripting/include/dynamic/methodmaps/preparedquery.inc:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 | #if defined _dynamic_class_preparedquery_
20 | #endinput
21 | #endif
22 | #define _dynamic_class_preparedquery_
23 |
24 | methodmap PreparedQuery < Dynamic
25 | {
26 | public PreparedQuery()
27 | {
28 | Dynamic myclass = Dynamic(64, 0);
29 | return view_as(myclass);
30 | }
31 |
32 | public bool Compile(const char[] query)
33 | {
34 | return _Dynamic_PreparedQuery_Compile(query, this);
35 | }
36 |
37 | public bool Prepare(Database db, Dynamic parameters, char[] buffer, int buffersize)
38 | {
39 | return _Dynamic_PreparedQuery_Prepare(this, db, parameters, buffer, buffersize);
40 | }
41 |
42 | public bool Execute(Database db, Dynamic parameters, SQLQueryCallback callback=INVALID_FUNCTION, any data=0, int buffersize=512)
43 | {
44 | return _Dynamic_PreparedQuery_Execute(this, db, parameters, callback, data, buffersize);
45 | }
46 | }
--------------------------------------------------------------------------------
/scripting/include/dynamic/natives.inc:
--------------------------------------------------------------------------------
1 | /**
2 | * =============================================================================
3 | * Dynamic for SourceMod (C)2016 Matthew J Dunn. All rights reserved.
4 | * =============================================================================
5 | *
6 | * This program is free software; you can redistribute it and/or modify it under
7 | * the terms of the GNU General Public License, version 3.0, as published by the
8 | * Free Software Foundation.
9 | *
10 | * This program is distributed in the hope that it will be useful, but WITHOUT
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 | * details.
14 | *
15 | * You should have received a copy of the GNU General Public License along with
16 | * this program. If not, see .
17 | *
18 | */
19 |
20 | native int Dynamic_GetCollectionSize();
21 |
22 | native Dynamic Dynamic_Initialise(int blocksize=64, int startsize=0, bool persistent=false);
23 | native bool Dynamic_IsValid(int index, bool throwerror=false);
24 | native bool Dynamic_Dispose(int index, bool disposemembers=true);
25 | native bool Dynamic_ResetObject(int index, bool disposemembers=true, int blocksize=0, int startsize=0);
26 | native Handle Dynamic_GetOwnerPlugin(Dynamic obj);
27 |
28 | native bool Dynamic_SetName(Dynamic obj, const char[] objectname, bool replace=false);
29 | native Dynamic Dynamic_FindByName(const char[] objectname);
30 | native Dynamic Dynamic_GetParent(Dynamic obj);
31 | native bool Dynamic_GetName(Dynamic obj, char[] buffer, int length);
32 |
33 | native bool Dynamic_GetPersistence(Dynamic obj);
34 | native bool Dynamic_SetPersistence(Dynamic obj, bool value);
35 |
36 | native bool Dynamic_ReadConfig(Dynamic obj, const char[] path, bool use_valve_fs=false, int valuelength=256);
37 | native bool Dynamic_WriteConfig(Dynamic obj, const char[] path);
38 |
39 | native bool Dynamic_ReadKeyValues(Dynamic obj, const char[] path, int valuelength, Dynamic_HookType callback=INVALID_FUNCTION);
40 | native bool Dynamic_WriteKeyValues(Dynamic obj, const char[] path, const char[] basekey);
41 |
42 | native int Dynamic_GetMemberCount(Dynamic obj);
43 | native DynamicOffset Dynamic_GetMemberOffset(Dynamic obj, const char[] membername);
44 | native DynamicOffset Dynamic_GetMemberOffsetByIndex(Dynamic obj, int index);
45 | native bool Dynamic_GetMemberNameByIndex(Dynamic obj, int index, char[] buffer, int length);
46 | native bool Dynamic_GetMemberNameByOffset(Dynamic obj, DynamicOffset offset, char[] buffer, int length);
47 | native Dynamic_MemberType Dynamic_GetMemberType(Dynamic obj, const char[] membername);
48 | native Dynamic_MemberType Dynamic_GetMemberTypeByOffset(Dynamic obj, DynamicOffset offset);
49 | native bool Dynamic_SortMembers(Dynamic obj, SortOrder order);
50 | native ArrayList Dynamic_FindByMemberValue(Dynamic obj, Dynamic params);
51 |
52 | native int Dynamic_CallbackCount(Dynamic obj);
53 | native bool Dynamic_HookChanges(Dynamic obj, Dynamic_HookType callback);
54 | native bool Dynamic_UnHookChanges(Dynamic obj, Dynamic_HookType callback);
55 |
56 | native int Dynamic_GetInt(Dynamic obj, const char[] membername, int defaultvalue=-1);
57 | native DynamicOffset Dynamic_SetInt(Dynamic obj, const char[] membername, int value);
58 | native int Dynamic_GetIntByOffset(Dynamic obj, DynamicOffset offset, int defaultvalue=-1);
59 | native bool Dynamic_SetIntByOffset(Dynamic obj, DynamicOffset offset, int value);
60 | native int Dynamic_PushInt(Dynamic obj, int value, const char[] name="");
61 | native int Dynamic_GetIntByIndex(Dynamic obj, int index, int defaultvalue=-1);
62 |
63 | native float Dynamic_GetFloat(Dynamic obj, const char[] membername, float defaultvalue=-1.0);
64 | native DynamicOffset Dynamic_SetFloat(Dynamic obj, const char[] membername, float value);
65 | native float Dynamic_GetFloatByOffset(Dynamic obj, DynamicOffset offset, float defaultvalue=-1.0);
66 | native bool Dynamic_SetFloatByOffset(Dynamic obj, DynamicOffset offset, float value);
67 | native int Dynamic_PushFloat(Dynamic obj, float value, const char[] name="");
68 | native float Dynamic_GetFloatByIndex(Dynamic obj, int index, float defaultvalue=-1.0);
69 |
70 | native bool Dynamic_GetString(Dynamic obj, const char[] membername, char[] buffer, int length);
71 | native DynamicOffset Dynamic_SetString(Dynamic obj, const char[] membername, const char[] value, int length=0);
72 | native bool Dynamic_GetStringByOffset(Dynamic obj, DynamicOffset offset, char[] buffer, int length);
73 | native bool Dynamic_SetStringByOffset(Dynamic obj, DynamicOffset offset, const char[] value, int length=0);
74 | native int Dynamic_PushString(Dynamic obj, const char[] value, int length=0, const char[] name="");
75 | native bool Dynamic_GetStringByIndex(Dynamic obj, int index, char[] buffer, int length);
76 | native int Dynamic_GetStringLength(Dynamic obj, const char[] membername);
77 | native int Dynamic_GetStringLengthByOffset(Dynamic obj, DynamicOffset offset);
78 | native bool Dynamic_CompareString(Dynamic obj, const char[] membername, const char[] value, bool casesensitive=true);
79 |
80 | // This can be removed at some point in the future
81 | #pragma deprecated Use Dynamic_GetDynamic() instead
82 | native Dynamic Dynamic_GetObject(Dynamic obj, const char[] membername);
83 | #pragma deprecated Use Dynamic_SetDynamic() instead
84 | native DynamicOffset Dynamic_SetObject(Dynamic obj, const char[] membername, Dynamic value);
85 | #pragma deprecated Use Dynamic_GetDynamicByOffset() instead
86 | native Dynamic Dynamic_GetObjectByOffset(Dynamic obj, DynamicOffset offset);
87 | #pragma deprecated Use Dynamic_SetDynamicByOffset() instead
88 | native bool Dynamic_SetObjectByOffset(Dynamic obj, DynamicOffset offset, Dynamic value);
89 | #pragma deprecated Use Dynamic_PushDynamic() instead
90 | native int Dynamic_PushObject(Dynamic obj, Dynamic value, const char[] name="");
91 | #pragma deprecated Use Dynamic_GetDynamicByIndex() instead
92 | native Dynamic Dynamic_GetObjectByIndex(Dynamic obj, int index);
93 | #pragma deprecated Use Dynamic_SetDynamicByIndex() instead
94 | native bool Dynamic_SetObjectByIndex(Dynamic obj, int index, Dynamic value);
95 |
96 | native Dynamic Dynamic_GetDynamic(Dynamic obj, const char[] membername);
97 | native DynamicOffset Dynamic_SetDynamic(Dynamic obj, const char[] membername, Dynamic value);
98 | native Dynamic Dynamic_GetDynamicByOffset(Dynamic obj, DynamicOffset offset);
99 | native bool Dynamic_SetDynamicByOffset(Dynamic obj, DynamicOffset offset, Dynamic value);
100 | native int Dynamic_PushDynamic(Dynamic obj, Dynamic value, const char[] name="");
101 | native Dynamic Dynamic_GetDynamicByIndex(Dynamic obj, int index);
102 | native bool Dynamic_SetDynamicByIndex(Dynamic obj, int index, Dynamic value);
103 |
104 | native bool Dynamic_GetBool(Dynamic obj, const char[] membername, bool defaultvalue=false);
105 | native DynamicOffset Dynamic_SetBool(Dynamic obj, const char[] membername, bool value);
106 | native bool Dynamic_GetBoolByOffset(Dynamic obj, DynamicOffset offset, bool defaultvalue=false);
107 | native bool Dynamic_SetBoolByOffset(Dynamic obj, DynamicOffset offset, bool value);
108 | native int Dynamic_PushBool(Dynamic obj, bool value, const char[] name="");
109 | native bool Dynamic_GetBoolByIndex(Dynamic obj, int index, bool defaultvalue=false);
110 |
111 | native Handle Dynamic_GetHandle(Dynamic obj, const char[] membername);
112 | native DynamicOffset Dynamic_SetHandle(Dynamic obj, const char[] membername, Handle value);
113 | native Handle Dynamic_GetHandleByOffset(Dynamic obj, DynamicOffset offset);
114 | native bool Dynamic_SetHandleByOffset(Dynamic obj, DynamicOffset offset, Handle value);
115 | native int Dynamic_PushHandle(Dynamic obj, Handle value, const char[] name="");
116 | native Handle Dynamic_GetHandleByIndex(Dynamic obj, int index);
117 |
118 | native bool Dynamic_GetVector(Dynamic obj, const char[] membername, float value[3]);
119 | native DynamicOffset Dynamic_SetVector(Dynamic obj, const char[] membername, const float value[3]);
120 | native bool Dynamic_GetVectorByOffset(Dynamic obj, DynamicOffset offset, float value[3]);
121 | native bool Dynamic_SetVectorByOffset(Dynamic obj, DynamicOffset offset, const float value[3]);
122 | native int Dynamic_PushVector(Dynamic obj, const float value[3], const char[] name="");
123 | native bool Dynamic_GetVectorByIndex(Dynamic obj, int index, float value[3]);
124 |
125 | native Function Dynamic_GetFunction(Dynamic obj, const char[] membername);
126 | native DynamicOffset Dynamic_SetFunction(Dynamic obj, const char[] membername, Function value);
127 | native Function Dynamic_GetFunctionByOffset(Dynamic obj, DynamicOffset offset);
128 | native bool Dynamic_SetFunctionByOffset(Dynamic obj, DynamicOffset offset, Function value);
129 | native int Dynamic_PushFunction(Dynamic obj, Function value, const char[] name="");
130 | native Function Dynamic_GetFunctionByIndex(Dynamic obj, int index);
131 |
132 | #if !defined REQUIRE_PLUGIN
133 | public __pl_dynamic_SetNTVOptional()
134 | {
135 | MarkNativeAsOptional("Dynamic_Initialise");
136 | MarkNativeAsOptional("Dynamic_IsValid");
137 | MarkNativeAsOptional("Dynamic_Dispose");
138 | MarkNativeAsOptional("Dynamic_ResetObject");
139 | MarkNativeAsOptional("Dynamic_GetOwnerPlugin");
140 | MarkNativeAsOptional("Dynamic_SetName");
141 | MarkNativeAsOptional("Dynamic_FindByName");
142 | MarkNativeAsOptional("Dynamic_GetParent");
143 | MarkNativeAsOptional("Dynamic_GetName");
144 | MarkNativeAsOptional("Dynamic_GetPersistence");
145 | MarkNativeAsOptional("Dynamic_SetPersistence");
146 | MarkNativeAsOptional("Dynamic_ReadConfig");
147 | MarkNativeAsOptional("Dynamic_WriteConfig");
148 | MarkNativeAsOptional("Dynamic_ReadKeyValues");
149 | MarkNativeAsOptional("Dynamic_WriteKeyValues");
150 | MarkNativeAsOptional("Dynamic_GetInt");
151 | MarkNativeAsOptional("Dynamic_SetInt");
152 | MarkNativeAsOptional("Dynamic_GetIntByOffset");
153 | MarkNativeAsOptional("Dynamic_SetIntByOffset");
154 | MarkNativeAsOptional("Dynamic_PushInt");
155 | MarkNativeAsOptional("Dynamic_GetIntByIndex");
156 | MarkNativeAsOptional("Dynamic_GetBool");
157 | MarkNativeAsOptional("Dynamic_SetBool");
158 | MarkNativeAsOptional("Dynamic_GetBoolByOffset");
159 | MarkNativeAsOptional("Dynamic_SetBoolByOffset");
160 | MarkNativeAsOptional("Dynamic_PushBool");
161 | MarkNativeAsOptional("Dynamic_GetBoolByIndex");
162 | MarkNativeAsOptional("Dynamic_GetFloat");
163 | MarkNativeAsOptional("Dynamic_SetFloat");
164 | MarkNativeAsOptional("Dynamic_GetFloatByOffset");
165 | MarkNativeAsOptional("Dynamic_SetFloatByOffset");
166 | MarkNativeAsOptional("Dynamic_PushFloat");
167 | MarkNativeAsOptional("Dynamic_GetFloatByIndex");
168 | MarkNativeAsOptional("Dynamic_GetString");
169 | MarkNativeAsOptional("Dynamic_SetString");
170 | MarkNativeAsOptional("Dynamic_GetStringByOffset");
171 | MarkNativeAsOptional("Dynamic_SetStringByOffset");
172 | MarkNativeAsOptional("Dynamic_PushString");
173 | MarkNativeAsOptional("Dynamic_GetStringByIndex");
174 | MarkNativeAsOptional("Dynamic_GetStringLength");
175 | MarkNativeAsOptional("Dynamic_GetStringLengthByOffset");
176 | MarkNativeAsOptional("Dynamic_CompareString");
177 | MarkNativeAsOptional("Dynamic_GetDynamic");
178 | MarkNativeAsOptional("Dynamic_SetDynamic");
179 | MarkNativeAsOptional("Dynamic_GetDynamicByOffset");
180 | MarkNativeAsOptional("Dynamic_SetDynamicByOffset");
181 | MarkNativeAsOptional("Dynamic_PushDynamic");
182 | MarkNativeAsOptional("Dynamic_GetDynamicByIndex");
183 | MarkNativeAsOptional("Dynamic_SetDynamicByIndex");
184 | MarkNativeAsOptional("Dynamic_GetHandle");
185 | MarkNativeAsOptional("Dynamic_SetHandle");
186 | MarkNativeAsOptional("Dynamic_GetHandleByOffset");
187 | MarkNativeAsOptional("Dynamic_SetHandleByOffset");
188 | MarkNativeAsOptional("Dynamic_PushHandle");
189 | MarkNativeAsOptional("Dynamic_GetHandleByIndex");
190 | MarkNativeAsOptional("Dynamic_GetVector");
191 | MarkNativeAsOptional("Dynamic_SetVector");
192 | MarkNativeAsOptional("Dynamic_GetVectorByOffset");
193 | MarkNativeAsOptional("Dynamic_SetVectorByOffset");
194 | MarkNativeAsOptional("Dynamic_PushVector");
195 | MarkNativeAsOptional("Dynamic_GetVectorByIndex");
196 | MarkNativeAsOptional("Dynamic_GetFunction");
197 | MarkNativeAsOptional("Dynamic_SetFunction");
198 | MarkNativeAsOptional("Dynamic_GetFunctionByOffset");
199 | MarkNativeAsOptional("Dynamic_SetFunctionByOffset");
200 | MarkNativeAsOptional("Dynamic_PushFunction");
201 | MarkNativeAsOptional("Dynamic_GetFunctionByIndex");
202 | MarkNativeAsOptional("Dynamic_GetCollectionSize");
203 | MarkNativeAsOptional("Dynamic_GetMemberCount");
204 | MarkNativeAsOptional("Dynamic_HookChanges");
205 | MarkNativeAsOptional("Dynamic_UnHookChanges");
206 | MarkNativeAsOptional("Dynamic_CallbackCount");
207 | MarkNativeAsOptional("Dynamic_GetMemberOffset");
208 | MarkNativeAsOptional("Dynamic_GetMemberOffsetByIndex");
209 | MarkNativeAsOptional("Dynamic_GetMemberType");
210 | MarkNativeAsOptional("Dynamic_GetMemberTypeByOffset");
211 | MarkNativeAsOptional("Dynamic_GetMemberNameByIndex");
212 | MarkNativeAsOptional("Dynamic_GetMemberNameByOffset");
213 | MarkNativeAsOptional("Dynamic_SortMembers");
214 | MarkNativeAsOptional("Dynamic_FindByMemberValue");
215 |
216 | // These are marked as deprecated
217 | MarkNativeAsOptional("Dynamic_GetObject");
218 | MarkNativeAsOptional("Dynamic_SetObject");
219 | MarkNativeAsOptional("Dynamic_GetObjectByOffset");
220 | MarkNativeAsOptional("Dynamic_SetObjectByOffset");
221 | MarkNativeAsOptional("Dynamic_PushObject");
222 | MarkNativeAsOptional("Dynamic_GetObjectByIndex");
223 | MarkNativeAsOptional("Dynamic_SetObjectByIndex");
224 | }
225 | #endif
--------------------------------------------------------------------------------