[Image, Image Array, Animation] Add cache button to store image data in the save file.

This commit is contained in:
Tanasart 2025-01-26 16:55:20 +07:00
parent c135e67f5a
commit 09a990bb7b
10 changed files with 246 additions and 128 deletions

View file

@ -137,7 +137,7 @@
{"name":"io","order":7,"path":"folders/nodes/data/io.yy",},
{"name":"aseprite","order":2,"path":"folders/nodes/data/io/aseprite.yy",},
{"name":"image","order":1,"path":"folders/nodes/data/io/image.yy",},
{"name":"svg","order":7,"path":"folders/nodes/data/io/image/svg.yy",},
{"name":"svg","order":8,"path":"folders/nodes/data/io/image/svg.yy",},
{"name":"iterate","order":8,"path":"folders/nodes/data/iterate.yy",},
{"name":"feedback","order":1,"path":"folders/nodes/data/iterate/feedback.yy",},
{"name":"for_each","order":3,"path":"folders/nodes/data/iterate/for_each.yy",},
@ -902,11 +902,11 @@
{"name":"node_honey_noise","order":44,"path":"scripts/node_honey_noise/node_honey_noise.yy",},
{"name":"node_hsv_channel","order":4,"path":"scripts/node_hsv_channel/node_hsv_channel.yy",},
{"name":"node_http_request","order":29,"path":"scripts/node_http_request/node_http_request.yy",},
{"name":"node_image_gif","order":1,"path":"scripts/node_image_gif/node_image_gif.yy",},
{"name":"node_image_animated","order":1,"path":"scripts/node_image_animated/node_image_animated.yy",},
{"name":"node_image_gif","order":2,"path":"scripts/node_image_gif/node_image_gif.yy",},
{"name":"node_image_grid","order":4,"path":"scripts/node_image_grid/node_image_grid.yy",},
{"name":"node_image_sequence","order":2,"path":"scripts/node_image_sequence/node_image_sequence.yy",},
{"name":"node_image_sheet","order":3,"path":"scripts/node_image_sheet/node_image_sheet.yy",},
{"name":"node_image","order":3,"path":"scripts/node_image/node_image.yy",},
{"name":"node_image_sequence","order":3,"path":"scripts/node_image_sequence/node_image_sequence.yy",},
{"name":"node_image_sheet","order":4,"path":"scripts/node_image_sheet/node_image_sheet.yy",},
{"name":"node_interlaced","order":50,"path":"scripts/node_interlaced/node_interlaced.yy",},
{"name":"node_interpret_number","order":8,"path":"scripts/node_interpret_number/node_interpret_number.yy",},
{"name":"node_invert","order":16,"path":"scripts/node_invert/node_invert.yy",},
@ -1124,7 +1124,7 @@
{"name":"node_scatter","order":13,"path":"scripts/node_scatter/node_scatter.yy",},
{"name":"node_segment_filter","order":29,"path":"scripts/node_segment_filter/node_segment_filter.yy",},
{"name":"node_separate_color","order":42,"path":"scripts/node_separate_color/node_separate_color.yy",},
{"name":"node_sequence_anim","order":5,"path":"scripts/node_sequence_anim/node_sequence_anim.yy",},
{"name":"node_sequence_anim","order":6,"path":"scripts/node_sequence_anim/node_sequence_anim.yy",},
{"name":"node_shadow_cast","order":28,"path":"scripts/node_shadow_cast/node_shadow_cast.yy",},
{"name":"node_shadow","order":27,"path":"scripts/node_shadow/node_shadow.yy",},
{"name":"node_shape_map","order":14,"path":"scripts/node_shape_map/node_shape_map.yy",},
@ -1183,7 +1183,7 @@
{"name":"node_surface_from_buffer","order":2,"path":"scripts/node_surface_from_buffer/node_surface_from_buffer.yy",},
{"name":"node_surface_replace","order":14,"path":"scripts/node_surface_replace/node_surface_replace.yy",},
{"name":"node_surface_to_color","order":1,"path":"scripts/node_surface_to_color/node_surface_to_color.yy",},
{"name":"node_svg","order":6,"path":"scripts/node_svg/node_svg.yy",},
{"name":"node_svg","order":7,"path":"scripts/node_svg/node_svg.yy",},
{"name":"node_switch","order":9,"path":"scripts/node_switch/node_switch.yy",},
{"name":"node_terminal_trigger","order":27,"path":"scripts/node_terminal_trigger/node_terminal_trigger.yy",},
{"name":"node_text_file_read","order":4,"path":"scripts/node_text_file_read/node_text_file_read.yy",},
@ -1799,7 +1799,7 @@
{"name":"sh_skew","order":16,"path":"shaders/sh_skew/sh_skew.yy",},
{"name":"sh_sky_hosek","order":2,"path":"shaders/sh_sky_hosek/sh_sky_hosek.yy",},
{"name":"sh_sky_scattering","order":1,"path":"shaders/sh_sky_scattering/sh_sky_scattering.yy",},
{"name":"sh_slice_spritesheet_empty_scan","order":4,"path":"shaders/sh_slice_spritesheet_empty_scan/sh_slice_spritesheet_empty_scan.yy",},
{"name":"sh_slice_spritesheet_empty_scan","order":5,"path":"shaders/sh_slice_spritesheet_empty_scan/sh_slice_spritesheet_empty_scan.yy",},
{"name":"sh_smear","order":28,"path":"shaders/sh_smear/sh_smear.yy",},
{"name":"sh_solid","order":18,"path":"shaders/sh_solid/sh_solid.yy",},
{"name":"sh_spherize","order":13,"path":"shaders/sh_spherize/sh_spherize.yy",},

Binary file not shown.

View file

@ -608,7 +608,11 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static doStepBegin = function() {}
static setTrigger = function(index, tooltip = __txtx("panel_inspector_execute", "Execute"), icon = [ THEME.sequence_control, 1, COLORS._main_value_positive ], _function = undefined) {
static setTrigger = function(index,
tooltip = __txtx("panel_inspector_execute", "Execute"),
icon = [ THEME.sequence_control, 1, COLORS._main_value_positive ],
_function = undefined) {
use_trigger = true;
if(index == 1) {

View file

@ -45,8 +45,7 @@ function Node_Image(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
attributes.check_splice = true;
attributes.file_checker = true;
array_push(attributeEditors, [ "File Watcher", function() { return attributes.file_checker; },
new checkBox(function() { attributes.file_checker = !attributes.file_checker; }) ]);
array_push(attributeEditors, [ "File Watcher", function() /*=>*/ {return attributes.file_checker}, new checkBox(function() /*=>*/ { attributes.file_checker = !attributes.file_checker; }) ]);
static on_drop_file = function(path) {
inputs[0].setValue(path);
@ -91,6 +90,28 @@ function Node_Image(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
setTrigger(1, __txt("Refresh"), [ THEME.refresh_icon, 1, COLORS._main_value_positive ], function() /*=>*/ { updatePaths(path_get(getInputData(0))); triggerRender(); });
static spliceImage = function() {
if(!attributes.check_splice) return;
attributes.check_splice = false;
if(LOADING || APPENDING) return;
if(string_pos("strip", display_name) == 0) return;
var sep_pos = string_pos("strip", display_name) + 5;
var sep = string_copy(display_name, sep_pos, string_length(display_name) - sep_pos + 1);
var amo = toNumber(string_digits(sep));
if(amo == 0) return;
var ww = sprite_get_width(spr) / amo;
var hh = sprite_get_height(spr);
var _splice = nodeBuild("Node_Image_Sheet", x + w + 64, y);
_splice.inputs[0].setFrom(outputs[0], false);
_splice.inputs[1].setValue([ ww, hh ]);
_splice.inputs[2].setValue(amo);
_splice.inputs[3].setValue([ amo, 1 ]);
}
static step = function() {
var path = path_get(getInputData(0));
@ -104,52 +125,32 @@ function Node_Image(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
}
static update = function(frame = CURRENT_FRAME) {
insp2UpdateTooltip = attributes.cache_use? __txt("Remove Cache") : __txt("Cache");
insp2UpdateIcon[0] = attributes.cache_use? THEME.cache : THEME.cache_group;
insp2UpdateIcon[2] = attributes.cache_use? c_white : COLORS._main_icon;
var path = path_get(getInputData(0));
var pad = getInputData(1);
if(is_array(path)) return;
var pad = getInputData(1);
outputs[1].setValue(path);
updatePaths(path);
if(!sprite_exists(spr)) return;
var _spr = attributes.cache_use? cache_spr : spr;
if(!sprite_exists(_spr)) return;
var ww = sprite_get_width(_spr) + pad[0] + pad[2];
var hh = sprite_get_height(_spr) + pad[1] + pad[3];
var _outsurf = outputs[0].getValue();
var ww = sprite_get_width(spr) + pad[0] + pad[2];
var hh = sprite_get_height(spr) + pad[1] + pad[3];
_outsurf = surface_verify(_outsurf, ww, hh, attrDepth());
surface_set_shader(_outsurf, noone);
draw_sprite(spr, 0, pad[2], pad[1]);
surface_reset_shader();
outputs[0].setValue(_outsurf);
if(!attributes.check_splice) return;
attributes.check_splice = false;
//////////////////////////////////////////////// SPLICE ////////////////////////////////////////////////
if(LOADING || APPENDING) return;
if(string_pos("strip", display_name) == 0) return;
surface_set_shader(_outsurf, noone);
draw_sprite(_spr, 0, pad[2], pad[1]);
surface_reset_shader();
var sep_pos = string_pos("strip", display_name) + 5;
var sep = string_copy(display_name, sep_pos, string_length(display_name) - sep_pos + 1);
var amo = toNumber(string_digits(sep));
if(amo == 0) return;
var ww = sprite_get_width(spr) / amo;
var hh = sprite_get_height(spr);
var _splice = nodeBuild("Node_Image_Sheet", x + w + 64, y);
_splice.inputs[0].setFrom(outputs[0], false);
_splice.inputs[1].setValue([ ww, hh ]);
_splice.inputs[2].setValue(amo);
_splice.inputs[3].setValue([ amo, 1 ]);
spliceImage();
}
static dropPath = function(path) {
@ -159,4 +160,31 @@ function Node_Image(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
inputs[0].setValue(path);
check_directory_redirector(path);
}
////- Cache
attributes.cache_use = false;
attributes.cache_data = "";
cache_spr = noone;
static cacheData = function() {
attributes.cache_use = true;
cache_spr = spr;
attributes.cache_data = sprite_array_serialize(spr);
triggerRender();
}
static uncacheData = function() {
attributes.cache_use = false;
triggerRender();
}
setTrigger(2, __txt("Cache"), [ THEME.cache_group, 0, COLORS._main_icon ], function() /*=>*/ { if(attributes.cache_use) uncacheData() else cacheData(); });
////- Serialize
static postDeserialize = function() {
if(!attributes[$ "cache_use"] ?? 0) return;
cache_spr = sprite_array_deserialize(attributes[$ "cache_data"] ?? "");
}
}

View file

@ -5,8 +5,8 @@
"isDnD":false,
"name":"node_image",
"parent":{
"name":"io",
"path":"folders/nodes/data/io.yy",
"name":"image",
"path":"folders/nodes/data/io/image.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",

View file

@ -57,10 +57,7 @@ function Node_Image_Animated(_x, _y, _group = noone) : Node(_x, _y, _group) cons
.rejectArray();
newInput(5, nodeValue_Trigger("Set animation length to match", self, false ))
.setDisplay(VALUE_DISPLAY.button, { name: "Match length", UI : true, onClick: function() {
if(array_length(spr) == 0) return;
TOTAL_FRAMES = array_length(spr);
} });
.setDisplay(VALUE_DISPLAY.button, { name: "Match length", UI : true, onClick: function() /*=>*/ { if(array_empty(spr)) return; TOTAL_FRAMES = array_length(spr); } });
newInput(6, nodeValue_Bool("Custom frame order", self, false));
@ -83,8 +80,7 @@ function Node_Image_Animated(_x, _y, _group = noone) : Node(_x, _y, _group) cons
edit_time = 0;
attributes.file_checker = true;
array_push(attributeEditors, [ "File Watcher", function() { return attributes.file_checker; },
new checkBox(function() { attributes.file_checker = !attributes.file_checker; }) ]);
array_push(attributeEditors, [ "File Watcher", function() /*=>*/ {return attributes.file_checker}, new checkBox(function() /*=>*/ { attributes.file_checker = !attributes.file_checker; }) ]);
on_drop_file = function(_path) {
if(directory_exists(_path)) {
@ -123,7 +119,7 @@ function Node_Image_Animated(_x, _y, _group = noone) : Node(_x, _y, _group) cons
if(_path == -1) continue;
array_push(path_current, _path);
setDisplayName(filename_name_only(_path));
if(file_exists_empty(_path)) setDisplayName(filename_name_only(_path));
var ext = string_lower(filename_ext(_path));
@ -151,7 +147,7 @@ function Node_Image_Animated(_x, _y, _group = noone) : Node(_x, _y, _group) cons
setTrigger(1, __txt("Refresh"), [ THEME.refresh_icon, 1, COLORS._main_value_positive ], function() /*=>*/ { updatePaths(path_get(getInputData(0))); triggerRender(); });
static step = function() { #region
static step = function() {
var str = getInputData(2);
var _cus = getInputData(6);
@ -167,35 +163,40 @@ function Node_Image_Animated(_x, _y, _group = noone) : Node(_x, _y, _group) cons
break;
}
}
} #endregion
}
static update = function(frame = CURRENT_FRAME) { #region
static update = function(frame = CURRENT_FRAME) {
insp2UpdateTooltip = attributes.cache_use? __txt("Remove Cache") : __txt("Cache");
insp2UpdateIcon[0] = attributes.cache_use? THEME.cache : THEME.cache_group;
insp2UpdateIcon[2] = attributes.cache_use? c_white : COLORS._main_icon;
var path = path_get(getInputData(0));
if(!array_equals(path_current, path))
updatePaths(path);
if(array_length(spr) == 0) return;
var _sprs = attributes.cache_use? cache_spr : spr;
if(array_length(_sprs) == 0) return;
var _pad = getInputData(1);
var _cus = getInputData(6);
var _str = getInputData(2);
var _end = getInputData(4);
var _spd = _str? (TOTAL_FRAMES + 1) / array_length(spr) : 1 / getInputData(3);
var _spd = _str? (TOTAL_FRAMES + 1) / array_length(_sprs) : 1 / getInputData(3);
if(_spd == 0) _spd = 1;
var _frame = _cus? getInputData(7) : floor(CURRENT_FRAME / _spd);
var _len = array_length(spr);
var _len = array_length(_sprs);
var _drw = true;
var _siz = getInputData(8);
var sw = sprite_get_width(spr[0]);
var sh = sprite_get_height(spr[0]);
var sw = sprite_get_width(_sprs[0]);
var sh = sprite_get_height(_sprs[0]);
if(_siz) {
for( var i = 1, n = array_length(spr); i < n; i++ ) {
var _sw = sprite_get_width(spr[i]);
var _sh = sprite_get_height(spr[i]);
for( var i = 1, n = array_length(_sprs); i < n; i++ ) {
var _sw = sprite_get_width(_sprs[i]);
var _sh = sprite_get_height(_sprs[i]);
if(_siz == 1) {
sw = min(_sw, sw);
@ -218,35 +219,56 @@ function Node_Image_Animated(_x, _y, _group = noone) : Node(_x, _y, _group) cons
outputs[0].setValue(surfs);
switch(_end) {
case ANIMATION_END.loop :
_frame = safe_mod(_frame, _len);
break;
case ANIMATION_END.loop : _frame = safe_mod(_frame, _len); break;
case ANIMATION_END.ping :
_frame = safe_mod(_frame, _len * 2 - 2);
if(_frame >= _len)
_frame = _len * 2 - 2 - _frame;
break;
case ANIMATION_END.hold :
_frame = min(_frame, _len - 1);
break;
case ANIMATION_END.hide :
if(_frame < 0 || _frame >= _len)
_drw = false;
if(_frame >= _len) _frame = _len * 2 - 2 - _frame;
break;
case ANIMATION_END.hold : _frame = min(_frame, _len - 1); break;
case ANIMATION_END.hide : if(_frame < 0 || _frame >= _len) _drw = false; break;
}
var _spr = array_safe_get_fast(spr, _frame, noone);
var _spr = array_safe_get_fast(_sprs, _frame, noone);
if(_spr == noone) return;
var curr_w = sprite_get_width(spr[_frame]);
var curr_h = sprite_get_height(spr[_frame]);
var curr_w = sprite_get_width(_spr);
var curr_h = sprite_get_height(_spr);
var curr_x = _pad[2] + (sw - curr_w) / 2;
var curr_y = _pad[1] + (sh - curr_h) / 2;
surface_set_shader(surfs);
if(_drw) draw_sprite(spr[_frame], 0, curr_x, curr_y);
if(_drw) draw_sprite(_spr, 0, curr_x, curr_y);
surface_reset_shader();
} #endregion
}
////- Cache
attributes.cache_use = false;
attributes.cache_data = "";
cache_spr = [];
static cacheData = function() {
attributes.cache_use = true;
cache_spr = spr;
attributes.cache_data = sprite_array_serialize(spr);
triggerRender();
}
static uncacheData = function() {
attributes.cache_use = false;
triggerRender();
}
setTrigger(2, __txt("Cache"), [ THEME.cache_group, 0, COLORS._main_icon ], function() /*=>*/ { if(attributes.cache_use) uncacheData() else cacheData(); });
////- Serialize
static postDeserialize = function() {
if(!attributes[$ "cache_use"] ?? 0) return;
cache_spr = sprite_array_deserialize(attributes[$ "cache_data"] ?? "");
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -35,9 +35,8 @@ function Node_Image_gif(_x, _y, _group = noone) : Node(_x, _y, _group) construct
.setDisplay(VALUE_DISPLAY.path_load, { filter: "Animated gif|*.gif" });
newInput(1, nodeValue_Trigger("Set animation length to gif", self, false ))
.setDisplay(VALUE_DISPLAY.button, { name: "Match length", UI : true, onClick: function() {
if(!spr) return;
if(!sprite_exists(spr)) return;
.setDisplay(VALUE_DISPLAY.button, { name: "Match length", UI : true, onClick: function() /*=>*/ {
if(!spr || !sprite_exists(spr)) return;
TOTAL_FRAMES = sprite_get_number(spr);
PROJECT.animator.framerate = 12;
} });
@ -78,17 +77,12 @@ function Node_Image_gif(_x, _y, _group = noone) : Node(_x, _y, _group) construct
edit_time = 0;
attributes.file_checker = true;
array_push(attributeEditors, [ "File Watcher", function() { return attributes.file_checker; },
new checkBox(function() { attributes.file_checker = !attributes.file_checker; }) ]);
array_push(attributeEditors, [ "File Watcher", function() /*=>*/ {return attributes.file_checker}, new checkBox(function() /*=>*/ { attributes.file_checker = !attributes.file_checker; }) ]);
on_drop_file = function(path) {
inputs[0].setValue(path);
if(updatePaths(path)) {
doUpdate();
return true;
}
if(updatePaths(path)) { doUpdate(); return true; }
return false;
}

View file

@ -68,8 +68,7 @@ function Node_Image_Sequence(_x, _y, _group = noone) : Node(_x, _y, _group) cons
edit_time = 0;
attributes.file_checker = true;
array_push(attributeEditors, [ "File Watcher", function() { return attributes.file_checker; },
new checkBox(function() { attributes.file_checker = !attributes.file_checker; }) ]);
array_push(attributeEditors, [ "File Watcher", function() /*=>*/ {return attributes.file_checker}, new checkBox(function() /*=>*/ { attributes.file_checker = !attributes.file_checker; }) ]);
on_drop_file = function(path) {
if(directory_exists(path)) {
@ -110,7 +109,7 @@ function Node_Image_Sequence(_x, _y, _group = noone) : Node(_x, _y, _group) cons
if(path == -1) continue;
var ext = string_lower(filename_ext(path));
setDisplayName(filename_name_only(path));
if(file_exists_empty(path)) setDisplayName(filename_name_only(path));
edit_time = max(edit_time, file_get_modify_s(path));
switch(ext) {
@ -149,6 +148,10 @@ function Node_Image_Sequence(_x, _y, _group = noone) : Node(_x, _y, _group) cons
}
static update = function(frame = CURRENT_FRAME) {
insp2UpdateTooltip = attributes.cache_use? __txt("Remove Cache") : __txt("Cache");
insp2UpdateIcon[0] = attributes.cache_use? THEME.cache : THEME.cache_group;
insp2UpdateIcon[2] = attributes.cache_use? c_white : COLORS._main_icon;
var path = inputs[0].getValue();
if(!array_equals(path_current, path))
@ -164,14 +167,16 @@ function Node_Image_Sequence(_x, _y, _group = noone) : Node(_x, _y, _group) cons
var _ww = -1, _hh = -1;
var surfs = outputs[0].getValue();
var amo = array_length(spr);
var _sprs = attributes.cache_use? cache_spr : spr;
var amo = array_length(_sprs);
for(var i = amo; i < array_length(surfs); i++)
surface_free(surfs[i]);
array_resize(surfs, amo);
for(var i = 0; i < amo; i++) {
var _spr = spr[i];
var _spr = _sprs[i];
var _w = sprite_get_width(_spr);
var _h = sprite_get_height(_spr);
@ -193,8 +198,8 @@ function Node_Image_Sequence(_x, _y, _group = noone) : Node(_x, _y, _group) cons
ww += pad[0] + pad[2];
hh += pad[1] + pad[3];
for(var i = 0; i < array_length(spr); i++) {
var _spr = spr[i];
for(var i = 0; i < array_length(_sprs); i++) {
var _spr = _sprs[i];
switch(can) {
case CANVAS_SIZE.individual :
ww = sprite_get_width(_spr) + pad[0] + pad[2];
@ -250,4 +255,31 @@ function Node_Image_Sequence(_x, _y, _group = noone) : Node(_x, _y, _group) cons
if(!is_array(path)) path = [ path ];
inputs[0].setValue(path);
}
////- Cache
attributes.cache_use = false;
attributes.cache_data = "";
cache_spr = [];
static cacheData = function() {
attributes.cache_use = true;
cache_spr = spr;
attributes.cache_data = sprite_array_serialize(spr);
triggerRender();
}
static uncacheData = function() {
attributes.cache_use = false;
triggerRender();
}
setTrigger(2, __txt("Cache"), [ THEME.cache_group, 0, COLORS._main_icon ], function() /*=>*/ { if(attributes.cache_use) uncacheData() else cacheData(); });
////- Serialize
static postDeserialize = function() {
if(!attributes[$ "cache_use"] ?? 0) return;
cache_spr = sprite_array_deserialize(attributes[$ "cache_data"] ?? "");
}
}

View file

@ -35,4 +35,57 @@ function sprite_path_check_depth(path, noti = true) {
shell_execute(path_magick, shell_cmd, self);
return proxy_path;
}
}
#region ================================= SERIALIZE ==================================
function sprite_array_serialize(arr) { return json_stringify(__sprite_array_serialize(arr)); }
function __sprite_array_serialize(arr) {
if(!is_array(arr)) {
if(!sprite_exists(arr)) return arr;
var ww = sprite_get_width(arr);
var hh = sprite_get_height(arr);
var _srf = surface_create(ww, hh);
surface_set_target(_srf); DRAW_CLEAR draw_sprite(arr, 0, 0, 0); surface_reset_target();
var buff = buffer_create(ww * hh * 4, buffer_fixed, 1);
buffer_get_surface(buff, _srf, 0);
var comp = buffer_compress(buff, 0, buffer_get_size(buff));
var enc = buffer_base64_encode(comp, 0, buffer_get_size(comp));
surface_free(_srf);
buffer_delete(buff);
return { width: ww, height: hh, buffer: enc };
}
var _arr = array_create(array_length(arr));
for( var i = 0, n = array_length(arr); i < n; i++ )
_arr[i] = __sprite_array_serialize(arr[i]);
return _arr;
}
function sprite_array_deserialize(dat) { return __sprite_array_deserialize(json_try_parse(dat, 0)); }
function __sprite_array_deserialize(arr) {
if(!is_array(arr)) {
if(!is_struct(arr) || !struct_has(arr, "buffer")) return noone;
var buff = buffer_base64_decode(arr.buffer);
buff = buffer_decompress(buff);
var _surf = surface_create_from_buffer(arr.width, arr.height, buff);
var _spr = sprite_create_from_surface(_surf, 0, 0, arr.width, arr.height, false, false, 0, 0);
surface_free_safe(_surf);
return _spr;
}
var _arr = array_create(array_length(arr));
for( var i = 0, n = array_length(arr); i < n; i++ )
_arr[i] = __sprite_array_deserialize(arr[i]);
return _arr;
}
#endregion

View file

@ -681,53 +681,38 @@ function surface_reset_target_override() { __surface_reset_target(); winwin_draw
#region ================================= SERIALIZE ==================================
function surface_array_serialize(arr) {
INLINE
var _arr = __surface_array_serialize(arr);
return json_stringify(_arr);
}
function surface_array_serialize(arr) { return json_stringify(__surface_array_serialize(arr)); }
function __surface_array_serialize(arr) {
if(!is_array(arr)) {
if(is_surface(arr)) {
var buff = buffer_create(surface_get_width_safe(arr) * surface_get_height_safe(arr) * 4, buffer_fixed, 1);
buffer_get_surface(buff, arr, 0);
var comp = buffer_compress(buff, 0, buffer_get_size(buff));
var enc = buffer_base64_encode(comp, 0, buffer_get_size(comp));
buffer_delete(buff);
return { width: surface_get_width_safe(arr), height: surface_get_height_safe(arr), buffer: enc };
} else
return arr;
if(!is_surface(arr)) return arr;
var buff = buffer_create(surface_get_width_safe(arr) * surface_get_height_safe(arr) * 4, buffer_fixed, 1);
buffer_get_surface(buff, arr, 0);
var comp = buffer_compress(buff, 0, buffer_get_size(buff));
var enc = buffer_base64_encode(comp, 0, buffer_get_size(comp));
buffer_delete(buff);
return { width: surface_get_width_safe(arr), height: surface_get_height_safe(arr), buffer: enc };
}
var _arr = [];
var _arr = array_create(array_length(arr));
for( var i = 0, n = array_length(arr); i < n; i++ )
_arr[i] = __surface_array_serialize(arr[i]);
return _arr;
}
function surface_array_deserialize(arr, index = -1) {
INLINE
var _arr = json_try_parse(arr);
return index == -1? __surface_array_deserialize(_arr) : __surface_array_deserialize(_arr[index]);
}
function surface_array_deserialize(dat) { return __surface_array_deserialize(json_try_parse(dat, 0)); }
function __surface_array_deserialize(arr) {
if(!is_array(arr)) {
if(!is_struct(arr) || !struct_has(arr, "buffer"))
return noone;
if(!is_struct(arr) || !struct_has(arr, "buffer")) return noone;
var buff = buffer_base64_decode(arr.buffer);
buff = buffer_decompress(buff);
return surface_create_from_buffer(arr.width, arr.height, buff);
}
var _arr = [];
var _arr = array_create(array_length(arr));
for( var i = 0, n = array_length(arr); i < n; i++ )
_arr[i] = __surface_array_deserialize(arr[i]);