From 09a990bb7bc3d5776b14be4c6d5ebede23cb61ab Mon Sep 17 00:00:00 2001 From: Tanasart Date: Sun, 26 Jan 2025 16:55:20 +0700 Subject: [PATCH] [Image, Image Array, Animation] Add cache button to store image data in the save file. --- PixelComposer.resource_order | 16 +-- datafiles/data/Nodes/Internal.zip | Bin 9099746 -> 9099746 bytes scripts/node_data/node_data.gml | 6 +- scripts/node_image/node_image.gml | 98 +++++++++++------- scripts/node_image/node_image.yy | 4 +- .../node_image_animated.gml | 92 +++++++++------- scripts/node_image_gif/node_image_gif.gml | 14 +-- .../node_image_sequence.gml | 46 ++++++-- .../sprite_add_functions.gml | 55 +++++++++- .../surface_functions/surface_functions.gml | 43 +++----- 10 files changed, 246 insertions(+), 128 deletions(-) diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 17d15571b..d94de7f20 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -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",}, diff --git a/datafiles/data/Nodes/Internal.zip b/datafiles/data/Nodes/Internal.zip index aac8515c8df3871b2096b1d56390209652502cf5..65220ef65d619f30e68932f0a8b2c6c9ae67a66c 100644 GIT binary patch delta 1278 zcmYk)TWm~u90%}K(;Yo6%38|I>gu`_HSV`wv^B@Ibh~bIDOIes>sl>}u4}(Nv*#bg z3;%4V3GW06$wW42r|pBJBAcDYgU&wiB#}sXl8E^J<_y~8lW%^P|NorH>5IEJTrcP> zh9Cn&;X)?9g&V_=1q0d0!ElVgNaSJ^M&mn-!S@)8amd4XOn?Vo{D6tb$B&qV0{n!@ zn1ZR8hC)oo49r9kX2FNqn1i{Phxu55g;<2eSc0V}MhQw$hGi&61uC%|{(GiBkdbHU zS3%RG>jUO+DGmk9*^<`-=1j>a0dtn*hk)smycp*4gNAC|Mq2(-$&Fri&Sp`$Fb)$(#Ypqmv1Y(2qjSoqU={d*2~TzZu-gwpEtS z4?8=2Q_q!CZHBHH)X>qqHY2B|YN%_>H}c2Z`Nl=^lz+m`(^7XQ_e8QHMy*LJXeF(p z)wG7zQWdSE^;AtiQw{w>8)zeKqRq600u-bWg{hXd(l)B2?Nm=YXeaHWUuie}MtkUY z`h)h;KH5(Q=pY@U20BcQ)I>+^6_I!-6(B(>0=bc#;X89Gbn=sdN?j9RQdoH4=D zoBB{JdASdZnX$)xxbK!mOFxSAodj~Fh$oz_j|r4WUDA(b%m|mLE!NU+y~~tA!*gq% zB)@BcZg_9G^^@n8A)QL;JpEv0UL9~6T$!I9%>8oYQk0+h+JH6ebLVQOau52byy*V{ zYk^Fe1-h<78M-3*bzj$;5qG31X;CEBl>DpkrTho{8@Ijsey8n~;#sF%E}7S5mq>2z zvdbh-_j2h@mt7!5qRTFo938hSz6=}U&X6a$8MpIg!n>D9W_R1g>GbMd-S$K&TD$F~ zk`KFWzhvqe`901xsbYJ&Xzg*{swbV9z0M2xds8>Wxcv7``QgRQ%BvSPDxVa)8`Uai z>{g>HbxGs(F|{tewN}z1C9B(&U(yrh-M8D-6e;-5 pUj4RRO-oNICF`QjW@`8->I{7yJm%_9g|flI{CqrixkGIz`vi<7+mZkP delta 1278 zcmYk)Sxi({90qWUgCiFdYHf?1Q3}&Vy3R(K)_)fO1 zvUEY%+2Nadem>h{=(=$Y9nJ4Ca_VX(x~5N%Ki>ZyUY(+&zykU|uuM%qccsEKw{Gwq?hw2$`F0Xj&B z=v(@Z4$~1jO2_CpouC#vNv+gI-%~rCq7FJuKhTfVNoVLRoul*AMHlEIb;pcGY&@CK z(5@RsP%3$K1gn^_2P3%SmPY3&O7yJ+@}!6-oUJzrlu2DSinYuLm#8P!IcmMiltIfA zYpEo^YmsjG&vNUBPb@<^)zW$N+RD5(<}|pnEInBA{>YUmKlAl5Yx29!wSMIu_fdJ# zKV#N%nKFxXQ=c+)Rr3FR-E2nOk+!5okyu;ur{ZVwAMjV)_Ub$RwpWVB{dT2f{(xO3 zxqZN{kUTfcrCS4bkrasmyIgWw+^%{*Y>7KVp5$iSE|3ZDUM-nDXqTqbtM?7sv!v)A zwAV=98?^nBsb>@nIoG6$-RYux$a$-wbY>1aFW?_e-4NsQFE{0fmv$(xUeT(2QXFVi z8*/ {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"] ?? ""); + } } \ No newline at end of file diff --git a/scripts/node_image/node_image.yy b/scripts/node_image/node_image.yy index 56033c443..bb6e7207a 100644 --- a/scripts/node_image/node_image.yy +++ b/scripts/node_image/node_image.yy @@ -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", diff --git a/scripts/node_image_animated/node_image_animated.gml b/scripts/node_image_animated/node_image_animated.gml index b69f5100d..7e22497e5 100644 --- a/scripts/node_image_animated/node_image_animated.gml +++ b/scripts/node_image_animated/node_image_animated.gml @@ -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"] ?? ""); + } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/node_image_gif/node_image_gif.gml b/scripts/node_image_gif/node_image_gif.gml index 3142f1493..3119e611d 100644 --- a/scripts/node_image_gif/node_image_gif.gml +++ b/scripts/node_image_gif/node_image_gif.gml @@ -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; } diff --git a/scripts/node_image_sequence/node_image_sequence.gml b/scripts/node_image_sequence/node_image_sequence.gml index 1b37a85d2..aba390c09 100644 --- a/scripts/node_image_sequence/node_image_sequence.gml +++ b/scripts/node_image_sequence/node_image_sequence.gml @@ -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"] ?? ""); + } } \ No newline at end of file diff --git a/scripts/sprite_add_functions/sprite_add_functions.gml b/scripts/sprite_add_functions/sprite_add_functions.gml index 1b38578c2..39919c6c6 100644 --- a/scripts/sprite_add_functions/sprite_add_functions.gml +++ b/scripts/sprite_add_functions/sprite_add_functions.gml @@ -35,4 +35,57 @@ function sprite_path_check_depth(path, noti = true) { shell_execute(path_magick, shell_cmd, self); return proxy_path; -} \ No newline at end of file +} + +#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 \ No newline at end of file diff --git a/scripts/surface_functions/surface_functions.gml b/scripts/surface_functions/surface_functions.gml index c4e2128bb..afe0c071c 100644 --- a/scripts/surface_functions/surface_functions.gml +++ b/scripts/surface_functions/surface_functions.gml @@ -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]);