From 0b06c472be7e7b0b8702214af12e30ad9f3c658c Mon Sep 17 00:00:00 2001 From: Juju Adams Date: Fri, 27 Oct 2023 12:23:48 +0100 Subject: [PATCH 1/2] Improves performance of SnapBufferWriteBinary() in 2023.8 --- .../SnapBufferWriteBinary.gml | 179 +++++++++++++++++- 1 file changed, 175 insertions(+), 4 deletions(-) diff --git a/scripts/SnapBufferWriteBinary/SnapBufferWriteBinary.gml b/scripts/SnapBufferWriteBinary/SnapBufferWriteBinary.gml index 0fba11a..a8b692f 100644 --- a/scripts/SnapBufferWriteBinary/SnapBufferWriteBinary.gml +++ b/scripts/SnapBufferWriteBinary/SnapBufferWriteBinary.gml @@ -5,7 +5,7 @@ /// @param struct/array The data to be encoded. Can contain structs, arrays, strings, and numbers. N.B. Will not encode ds_list, ds_map etc. /// @param [alphabetizeStructs=false] Whether to alphabetize struct variable names. Incurs a performance penalty is set to /// -/// @jujuadams 2022-10-30 +/// @jujuadams 2023-10-27 /* 0x00 - terminator @@ -23,6 +23,177 @@ */ function SnapBufferWriteBinary(_buffer, _value, _alphabetizeStructs = false) +{ + //Determine if we need to use the legacy codebase by checking against struct_foreach() + static _useLegacy = undefined; + if (_useLegacy == undefined) + { + try + { + struct_foreach({}, function() {}); + _useLegacy = false; + } + catch(_error) + { + _useLegacy = true; + } + } + + if (_useLegacy) + { + return __SnapBufferWriteBinaryLegacy(_buffer, _value, _alphabetizeStructs); + } + else + { + with(method_get_self(__SnapBufferWriteBinaryStructIteratorMethod())) + { + __buffer = _buffer; + __alphabetizeStructs = _alphabetizeStructs; + } + + return __SnapBufferWriteBinary(_buffer, _value, _alphabetizeStructs); + } +} + +//We have to use this weird workaround because you can't static_get() a function you haven't run before +function __SnapBufferWriteBinaryStructIteratorMethod() +{ + static _method = method( + { + __buffer: undefined, + __alphabetizeStructs: false, + }, + function(_name, _value) + { + if (!is_string(_name)) show_error("SNAP:\nKeys must be strings\n ", true); + + buffer_write(__buffer, buffer_string, _name); + __SnapBufferWriteBinary(__buffer, _value, __alphabetizeStructs); + } + ); + + return _method; +} + +function __SnapBufferWriteBinary(_buffer, _value, _alphabetizeStructs) +{ + static _structIteratorMethod = __SnapBufferWriteBinaryStructIteratorMethod(); + + if (is_method(_value)) //Implicitly also a struct so we have to check this first + { + buffer_write(_buffer, buffer_u8, 0x03); //Convert all methods to strings + buffer_write(_buffer, buffer_string, string(_value)); + } + else if (is_struct(_value)) + { + var _struct = _value; + var _count = variable_struct_names_count(_struct); + + buffer_write(_buffer, buffer_u8, 0x01); //Struct + buffer_write(_buffer, buffer_u64, _count); + + if (_count > 0) + { + if (_alphabetizeStructs) + { + var _names = variable_struct_get_names(_struct); + array_sort(_names, true); + var _i = 0; + repeat(_count) + { + var _name = _names[_i]; + if (!is_string(_name)) show_error("SNAP:\nKeys must be strings\n ", true); + + buffer_write(_buffer, buffer_string, _name); + __SnapBufferWriteBinary(_buffer, _struct[$ _name], _alphabetizeStructs); + + ++_i; + } + } + else + { + struct_foreach(_struct, _structIteratorMethod); + } + } + } + else if (is_array(_value)) + { + var _array = _value; + var _count = array_length(_array); + + buffer_write(_buffer, buffer_u8, 0x02); ///Array + buffer_write(_buffer, buffer_u64, _count); + + var _i = 0; + repeat(_count) + { + __SnapBufferWriteBinary(_buffer, _array[_i], _alphabetizeStructs); + ++_i; + } + } + else if (is_string(_value)) + { + buffer_write(_buffer, buffer_u8, 0x03); //String + buffer_write(_buffer, buffer_string, _value); + } + else if (is_real(_value)) + { + if (_value == 0) + { + buffer_write(_buffer, buffer_u8, 0x05); // + } + else if (_value == 1) + { + buffer_write(_buffer, buffer_u8, 0x06); // + } + else + { + buffer_write(_buffer, buffer_u8, 0x04); //f64 + buffer_write(_buffer, buffer_f64, _value); + } + } + else if (is_bool(_value)) + { + buffer_write(_buffer, buffer_u8, _value? 0x06 : 0x05); // or + } + else if (is_undefined(_value)) + { + buffer_write(_buffer, buffer_u8, 0x07); // + } + else if (is_int32(_value)) + { + buffer_write(_buffer, buffer_u8, 0x08); //s32 + buffer_write(_buffer, buffer_s32, _value); + } + else if (is_int64(_value)) + { + buffer_write(_buffer, buffer_u8, 0x09); //u64 + buffer_write(_buffer, buffer_u64, _value); + } + else if (is_ptr(_value)) + { + buffer_write(_buffer, buffer_u8, 0x0A); //pointer + buffer_write(_buffer, buffer_u64, int64(_value)); + } + else if (typeof(_value) == "ref") // is_ref() doesn't exist as of 2022-10-23 + { + buffer_write(_buffer, buffer_u8, 0x0B); //instance ID reference + buffer_write(_buffer, buffer_u64, int64(real(_value))); //Serialize the numeric part of the reference + } + else + { + show_message("Datatype \"" + typeof(_value) + "\" not supported"); + } + + return _buffer; +} + + + + + +//Legacy version for LTS use +function __SnapBufferWriteBinaryLegacy(_buffer, _value, _alphabetizeStructs) { if (is_method(_value)) //Implicitly also a struct so we have to check this first { @@ -47,7 +218,7 @@ function SnapBufferWriteBinary(_buffer, _value, _alphabetizeStructs = false) if (!is_string(_name)) show_error("SNAP:\nKeys must be strings\n ", true); buffer_write(_buffer, buffer_string, string(_name)); - SnapBufferWriteBinary(_buffer, _struct[$ _name], _alphabetizeStructs); + __SnapBufferWriteBinaryLegacy(_buffer, _struct[$ _name], _alphabetizeStructs); ++_i; } @@ -63,7 +234,7 @@ function SnapBufferWriteBinary(_buffer, _value, _alphabetizeStructs = false) var _i = 0; repeat(_count) { - SnapBufferWriteBinary(_buffer, _array[_i], _alphabetizeStructs); + __SnapBufferWriteBinaryLegacy(_buffer, _array[_i], _alphabetizeStructs); ++_i; } } @@ -122,4 +293,4 @@ function SnapBufferWriteBinary(_buffer, _value, _alphabetizeStructs = false) } return _buffer; -} +} \ No newline at end of file From bac2cfa8e9c7a86df225714c802f59afa9142580 Mon Sep 17 00:00:00 2001 From: Juju Adams Date: Fri, 27 Oct 2023 12:26:08 +0100 Subject: [PATCH 2/2] 6.0.1 --- README.md | 2 +- options/windows/options_windows.yy | 2 +- scripts/__SnapSystem/__SnapSystem.gml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9f0c02e..0b77b93 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

-

SNAP 6.0.0

+

SNAP 6.0.1

Data format converters for GameMaker Studio 2022 LTS by Juju Adams

diff --git a/options/windows/options_windows.yy b/options/windows/options_windows.yy index e600f70..a42bb0a 100644 --- a/options/windows/options_windows.yy +++ b/options/windows/options_windows.yy @@ -4,7 +4,7 @@ "name": "Windows", "option_windows_display_name": "SNAP", "option_windows_executable_name": "${project_name}.exe", - "option_windows_version": "6.0.0.0", + "option_windows_version": "6.0.1.0", "option_windows_company_info": "@jujuadams", "option_windows_product_info": "SNAP", "option_windows_copyright_info": "@jujuadams 2023", diff --git a/scripts/__SnapSystem/__SnapSystem.gml b/scripts/__SnapSystem/__SnapSystem.gml index 28f6e38..d7ed707 100644 --- a/scripts/__SnapSystem/__SnapSystem.gml +++ b/scripts/__SnapSystem/__SnapSystem.gml @@ -1,5 +1,5 @@ // Feather disable all -#macro __SNAP_VERSION "6.0.0" -#macro __SNAP_DATE "2023-10-21" +#macro __SNAP_VERSION "6.0.1" +#macro __SNAP_DATE "2023-10-27" show_debug_message("SNAP: Welcome to SNAP by @jujuadams! This is version " + __SNAP_VERSION + ", " + __SNAP_DATE);