1- --[[
2- Copyright 2012 Alexandru-Mihai Maftei
1+ --[[ vON 1.1.1
2+
3+ Copyright 2012-2013 Alexandru-Mihai Maftei
34 aka Vercas
45
56 You may use this for any purpose as long as:
1011 If you modify the code for any purpose, the above obligations still apply.
1112
1213 Instead of copying this code over for sharing, rather use the link:
13- https://dl.dropbox.com/u/1217587/GMod/Lua/von.lua
14+ https://dl.dropbox.com/u/1217587/GMod/Lua/von%20for%20GMOD.lua
15+
16+ The author may not be held responsible for any damage or losses directly or indirectly caused by
17+ the use of vON.
1418
1519 If you disagree with the above, don't use the code.
1620
2125 Suggested an excellent new way of deserializing strings.
2226 Lead me to finding an extreme flaw in string parsing.
2327 - pennerlord Provided some performance tests to help me improve the code.
28+ - Chessnut Reported bug with handling of nil values when deserializing array components.
2429
2530-----------------------------------------------------------------------------------------------------------------------------
2631
3035 - boolean
3136 - string
3237 - nil
38+ - Entity
39+ - Player
40+ - Vector
41+ - Angle
3342
3443 These are the native Lua types one would normally serialize.
44+ + Some very common GMod Lua types.
3545
3646-----------------------------------------------------------------------------------------------------------------------------
3747
3848 New in this version:
39- - Added errors on (de)serialization when passwing the wrong data type.
40- - Removed two redundant arguments in the serialization functable.
49+ - Fixed problem with handling of nils in array tables.
4150--]]
4251
4352local _deserialize , _serialize , _d_meta , _s_meta , d_findVariable , s_anyVariable
44- local sub , gsub , find , insert , concat , error , tonumber , tostring , type , next = string.sub , string.gsub , string.find , table.insert , table.concat , error , tonumber , tostring , type , next
53+ local sub , gsub , find , insert , concat , error , tonumber , tostring , type , next , getEnt , getPly = string.sub , string.gsub , string.find , table.insert , table.concat , error , tonumber , tostring , type , next , Entity , player . GetByID
4554
4655-- This is kept away from the table for speed.
4756function d_findVariable (s , i , len , lastType )
@@ -88,6 +97,26 @@ function d_findVariable(s, i, len, lastType)
8897 lastType = " table"
8998 typeRead = true
9099
100+ -- n means a number will follow. Base 10... :C
101+ elseif c == " e" then
102+ lastType = " Entity"
103+ typeRead = true
104+
105+ -- n means a number will follow. Base 10... :C
106+ elseif c == " p" then
107+ lastType = " Player"
108+ typeRead = true
109+
110+ -- n means a number will follow. Base 10... :C
111+ elseif c == " v" then
112+ lastType = " Vector"
113+ typeRead = true
114+
115+ -- n means a number will follow. Base 10... :C
116+ elseif c == " a" then
117+ lastType = " Angle"
118+ typeRead = true
119+
91120 -- If no type has been found, attempt to deserialize the last type read.
92121 elseif lastType then
93122 val , i = _deserialize [lastType ](s , i , len )
@@ -126,7 +155,7 @@ _deserialize = {
126155-- Well, tables are very loose...
127156-- The first table doesn't have to begin and end with { and }.
128157 [" table" ] = function (s , i , len , unnecessaryEnd )
129- local ret , numeric , i , c , lastType , val , ind , expectValue , key = {}, true , i or 1
158+ local ret , numeric , i , c , lastType , val , ind , expectValue , key = {}, true , i or 1 , nil , nil , nil , 1
130159 -- Locals, locals, locals, locals, locals, locals, locals, locals and locals.
131160
132161 -- Keep looping.
@@ -144,7 +173,7 @@ _deserialize = {
144173 end
145174
146175 -- Cache the character.
147- c = sub (s ,i , i )
176+ c = sub (s , i , i )
148177 -- print(i, "table char:", c, tostring(unnecessaryEnd))
149178
150179 -- If it's the end of a table definition, return.
@@ -164,7 +193,9 @@ _deserialize = {
164193 -- Find a variable and it's value
165194 val , i , lastType = d_findVariable (s , i , len , lastType )
166195 -- Add it to the table.
167- ret [# ret + 1 ] = val
196+ ret [ind ] = val
197+
198+ ind = ind + 1
168199
169200 -- Otherwise, if it's the key:value component...
170201 else
@@ -259,6 +290,103 @@ _deserialize = {
259290 error (" vON: String definition started... Found no end." )
260291 end
261292 end
293+ end ,
294+
295+
296+ -- Entities are stored simply by the ID. They're meant to be transfered, not stored anyway.
297+ -- Exactly like a number definition, except it begins with "e".
298+ [" Entity" ] = function (s , i , len )
299+ local i , a = i or 1
300+ -- Locals, locals, locals, locals
301+
302+ a = find (s , " [;:}~]" , i )
303+
304+ if a then
305+ return getEnt (tonumber (sub (s , i , a - 1 ))), a - 1
306+ end
307+
308+ error (" vON: Entity ID definition started... Found no end." )
309+ end ,
310+
311+
312+ -- Exactly like a entity definition, except it begins with "p".
313+ [" Player" ] = function (s , i , len )
314+ local i , a = i or 1
315+ -- Locals, locals, locals, locals
316+
317+ a = find (s , " [;:}~]" , i )
318+
319+ if a then
320+ return getEnt (tonumber (sub (s , i , a - 1 ))), a - 1
321+ end
322+
323+ error (" vON: Player ID definition started... Found no end." )
324+ end ,
325+
326+
327+ -- A pair of 3 numbers separated by a comma (,).
328+ [" Vector" ] = function (s , i , len )
329+ local i , a , x , y , z = i or 1
330+ -- Locals, locals, locals, locals
331+
332+ a = find (s , " ," , i )
333+
334+ if a then
335+ x = tonumber (sub (s , i , a - 1 ))
336+ i = a + 1
337+ end
338+
339+ a = find (s , " ," , i )
340+
341+ if a then
342+ y = tonumber (sub (s , i , a - 1 ))
343+ i = a + 1
344+ end
345+
346+ a = find (s , " [;:}~]" , i )
347+
348+ if a then
349+ z = tonumber (sub (s , i , a - 1 ))
350+ end
351+
352+ if x and y and z then
353+ return Vector (x , y , z ), a - 1
354+ end
355+
356+ error (" vON: Vector definition started... Found no end." )
357+ end ,
358+
359+
360+ -- A pair of 3 numbers separated by a comma (,).
361+ [" Angle" ] = function (s , i , len )
362+ local i , a , p , y , r = i or 1
363+ -- Locals, locals, locals, locals
364+
365+ a = find (s , " ," , i )
366+
367+ if a then
368+ p = tonumber (sub (s , i , a - 1 ))
369+ i = a + 1
370+ end
371+
372+ a = find (s , " ," , i )
373+
374+ if a then
375+ y = tonumber (sub (s , i , a - 1 ))
376+ i = a + 1
377+ end
378+
379+ a = find (s , " [;:}~]" , i )
380+
381+ if a then
382+ r = tonumber (sub (s , i , a - 1 ))
383+ end
384+
385+ if p and y and r then
386+ return Angle (p , y , r ), a - 1
387+ end
388+
389+ error (" vON: Angle definition started... Found no end." )
262390 end
263391}
264392
@@ -375,6 +503,82 @@ _serialize = {
375503-- Fastest.
376504 [" nil" ] = function (data , mustInitiate , isNumeric , isKey , isLast )
377505 return " @"
506+ end ,
507+
508+
509+ -- Same as numbers, except they start with "e" instead of "n".
510+ [" Entity" ] = function (data , mustInitiate , isNumeric , isKey , isLast )
511+ data = data :EntIndex ()
512+
513+ if mustInitiate then
514+ if isKey or isLast then
515+ return " e" .. data
516+ else
517+ return " e" .. data .. " ;"
518+ end
519+ end
520+
521+ if isKey or isLast then
522+ return " e" .. data
523+ else
524+ return " e" .. data .. " ;"
525+ end
526+ end ,
527+
528+
529+ -- Same as entities, except they start with "e" instead of "n".
530+ [" Player" ] = function (data , mustInitiate , isNumeric , isKey , isLast )
531+ data = data :EntIndex ()
532+
533+ if mustInitiate then
534+ if isKey or isLast then
535+ return " p" .. data
536+ else
537+ return " p" .. data .. " ;"
538+ end
539+ end
540+
541+ if isKey or isLast then
542+ return " p" .. data
543+ else
544+ return " p" .. data .. " ;"
545+ end
546+ end ,
547+
548+
549+ -- 3 numbers separated by a comma.
550+ [" Vector" ] = function (data , mustInitiate , isNumeric , isKey , isLast )
551+ if mustInitiate then
552+ if isKey or isLast then
553+ return " v" .. data .x .. " ," .. data .y .. " ," .. data .z
554+ else
555+ return " v" .. data .x .. " ," .. data .y .. " ," .. data .z .. " ;"
556+ end
557+ end
558+
559+ if isKey or isLast then
560+ return " v" .. data .x .. " ," .. data .y .. " ," .. data .z
561+ else
562+ return " v" .. data .x .. " ," .. data .y .. " ," .. data .z .. " ;"
563+ end
564+ end ,
565+
566+
567+ -- 3 numbers separated by a comma.
568+ [" Angle" ] = function (data , mustInitiate , isNumeric , isKey , isLast )
569+ if mustInitiate then
570+ if isKey or isLast then
571+ return " a" .. data .p .. " ," .. data .y .. " ," .. data .r
572+ else
573+ return " a" .. data .p .. " ," .. data .y .. " ," .. data .r .. " ;"
574+ end
575+ end
576+
577+ if isKey or isLast then
578+ return " a" .. data .p .. " ," .. data .y .. " ," .. data .r
579+ else
580+ return " a" .. data .p .. " ," .. data .y .. " ," .. data .r .. " ;"
581+ end
378582 end
379583}
380584
@@ -401,4 +605,4 @@ _s_meta = {
401605von = {}
402606
403607von .deserialize = setmetatable (_deserialize ,_d_meta )
404- von .serialize = setmetatable (_serialize ,_s_meta )
608+ von .serialize = setmetatable (_serialize ,_s_meta )
0 commit comments