progressive loader

This commit is contained in:
Tanasart 2024-11-24 17:39:17 +07:00
parent c7457c644d
commit e4e98b4524
45 changed files with 544 additions and 275 deletions

View file

@ -345,6 +345,7 @@
{"name":"Obj_FirebaseREST_Listener_On_Firestore","order":1,"path":"objects/Obj_FirebaseREST_Listener_On_Firestore/Obj_FirebaseREST_Listener_On_Firestore.yy",},
{"name":"Obj_FirebaseREST_Listener_Once_Firestore","order":4,"path":"objects/Obj_FirebaseREST_Listener_Once_Firestore/Obj_FirebaseREST_Listener_Once_Firestore.yy",},
{"name":"oRigidbody","order":13,"path":"objects/oRigidbody/oRigidbody.yy",},
{"name":"project_loader","order":4,"path":"objects/project_loader/project_loader.yy",},
{"name":"rotator_Rotator","order":3,"path":"objects/rotator_Rotator/rotator_Rotator.yy",},
{"name":"slider_Slider","order":1,"path":"objects/slider_Slider/slider_Slider.yy",},
{"name":"__3d_particle","order":1,"path":"scripts/__3d_particle/__3d_particle.yy",},

View file

@ -819,6 +819,7 @@
{"id":{"name":"Obj_FirebaseREST_Listener_On_Firestore","path":"objects/Obj_FirebaseREST_Listener_On_Firestore/Obj_FirebaseREST_Listener_On_Firestore.yy",},},
{"id":{"name":"Obj_FirebaseREST_Listener_Once_Firestore","path":"objects/Obj_FirebaseREST_Listener_Once_Firestore/Obj_FirebaseREST_Listener_Once_Firestore.yy",},},
{"id":{"name":"oRigidbody","path":"objects/oRigidbody/oRigidbody.yy",},},
{"id":{"name":"project_loader","path":"objects/project_loader/project_loader.yy",},},
{"id":{"name":"rotator_Rotator","path":"objects/rotator_Rotator/rotator_Rotator.yy",},},
{"id":{"name":"slider_Slider","path":"objects/slider_Slider/slider_Slider.yy",},},
{"id":{"name":"rm_main","path":"rooms/rm_main/rm_main.yy",},},

View file

@ -1,8 +1,15 @@
/// @description
event_inherited();
ds_map_destroy(discord_map);
ds_map_destroy(nicknames);
ds_map_destroy(attachment);
surface_free(clip_surf);
run_in(1, function() /*=>*/ {
ds_map_destroy(discord_map);
ds_map_destroy(nicknames);
ds_map_destroy(attachment);
surface_free(clip_surf);
sp_recent.free();
sp_sample.free();
sp_contest.free();
sp_news.free();
});

View file

@ -3,9 +3,9 @@
"%Name":"o_dialog_splash",
"eventList":[
{"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
{"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":1,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
{"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":62,"eventType":7,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
{"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":64,"eventType":8,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
{"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":1,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
],
"managed":true,
"name":"o_dialog_splash",

View file

@ -4,7 +4,7 @@ winManStep();
//print("===== Step start =====");
if(PROJECT.active && !PROJECT.safeMode) { //node step
if(!LOADING && PROJECT.active && !PROJECT.safeMode) { //node step
PROJECT.step();
LIVE_UPDATE = false;
@ -143,4 +143,7 @@ if(PROJECT.active && !PROJECT.safeMode) { //node step
buffer_delete(_l_cols);
}
}
// var _s = gc_get_stats();
// if(_s.objects_touched) print($"{string_lead_zero(_s.objects_touched, 7, " ")}, {string_lead_zero(_s.objects_collected, 7, " ")}, {string_lead_zero(_s.traversal_time, 6, " ")}");
#endregion

View file

@ -136,54 +136,56 @@ _FILE_DROPPED = false;
NodeTopoSort();
}
if(!PROJECT.safeMode) array_foreach(PROJECT.allNodes, function(_node) /*=>*/ { if(!_node.active) return; _node.stepBegin(); });
if(!LOADING) {
if(!PROJECT.safeMode) array_foreach(PROJECT.allNodes, function(_node) /*=>*/ { if(!_node.active) return; _node.stepBegin(); });
if(LIVE_UPDATE)
Render();
else if(!PROJECT.safeMode) {
UPDATE_RENDER_ORDER = false;
if(PROJECT.active) {
PROJECT.animator.is_simulating = false;
if(LIVE_UPDATE)
Render();
else if(!PROJECT.safeMode) {
UPDATE_RENDER_ORDER = false;
if(PROGRAM_ARGUMENTS._run) {
if(PROJECT != noone && PROJECT.path != "") {
exportAll();
PROGRAM_ARGUMENTS._run = false;
}
} else if(IS_PLAYING || IS_RENDERING) {
if(PROJECT.animator.frame_progress) {
__addon_preAnim();
if(IS_FIRST_FRAME)
ResetAllNodesRender();
if(IS_CMD) Render(false);
else Render(true);
__addon_postAnim();
}
PROJECT.animator.frame_progress = false;
if(PROJECT.active) {
PROJECT.animator.is_simulating = false;
} else {
if(UPDATE & RENDER_TYPE.full)
Render();
if(PROGRAM_ARGUMENTS._run) {
if(PROJECT != noone && PROJECT.path != "") {
exportAll();
PROGRAM_ARGUMENTS._run = false;
}
} else if(IS_PLAYING || IS_RENDERING) {
if(PROJECT.animator.frame_progress) {
__addon_preAnim();
if(IS_FIRST_FRAME)
ResetAllNodesRender();
if(IS_CMD) Render(false);
else Render(true);
__addon_postAnim();
}
PROJECT.animator.frame_progress = false;
else if(UPDATE & RENDER_TYPE.partial)
Render(true);
} else {
if(UPDATE & RENDER_TYPE.full)
Render();
else if(UPDATE & RENDER_TYPE.partial)
Render(true);
}
}
}
}
if(PROGRAM_ARGUMENTS._rendering && PROGRAM_ARGUMENTS._run == false && array_empty(PROGRAM_ARGUMENTS._exporting)) {
log_console($"Export {CLI_EXPORT_AMOUNT} {CLI_EXPORT_AMOUNT > 1? "files" : "file"} completed");
if(PROGRAM_ARGUMENTS._persist) {
PROGRAM_ARGUMENTS._rendering = false;
cli_wait();
} else
game_end();
if(PROGRAM_ARGUMENTS._rendering && PROGRAM_ARGUMENTS._run == false && array_empty(PROGRAM_ARGUMENTS._exporting)) {
log_console($"Export {CLI_EXPORT_AMOUNT} {CLI_EXPORT_AMOUNT > 1? "files" : "file"} completed");
if(PROGRAM_ARGUMENTS._persist) {
PROGRAM_ARGUMENTS._rendering = false;
cli_wait();
} else
game_end();
}
}
UPDATE = RENDER_TYPE.none;

View file

@ -0,0 +1,28 @@
load_process = 0;
load_step = 0;
load_total = 0;
create_list = [];
if(struct_has(content, "version")) {
var _v = content.version;
PROJECT.version = _v;
LOADING_VERSION = _v;
if(PREFERENCES.notify_load_version && floor(_v) != floor(SAVE_VERSION)) {
var warn = $"File version mismatch : loading file version {_v} to Pixel Composer {SAVE_VERSION}";
log_warning("LOAD", warn);
}
} else {
var warn = $"File version mismatch : loading old format to Pixel Composer {SAVE_VERSION}";
log_warning("LOAD", warn);
}
printIf(log, $" > Load meta : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
load_process = 1;
load_delay = 50_000;
load_noti = new notification(NOTI_TYPE.log, noti_status($"Loading {path}..."));
load_noti.progress = 0;
array_append(STATS_PROGRESS, load_noti);
node_length = 0;

View file

@ -0,0 +1,189 @@
switch(load_process) {
case 1 :
if(!struct_has(content, "nodes")) {
log_warning("LOAD", "Cannot read node data.");
instance_destroy();
break;
}
var _node_list = content.nodes;
var _t = get_timer();
var _skp = false;
try {
if(load_step == 0) {
load_total = array_length(_node_list);
create_list = array_create(array_length(_node_list));
}
for(; load_step < load_total; load_step++) {
var _node = nodeLoad(_node_list[load_step]);
if(_node) create_list[node_length++] = _node;
var _ts = get_timer() - _t;
if(load_step < load_total - 1 && _ts > load_delay) {
_skp = true;
break;
}
}
} catch(e) {
log_warning("LOAD", exception_print(e));
}
load_noti.progress = lerp(0, .75, load_step / load_total);
if(_skp) break;
array_resize(create_list, node_length);
PROJECT.deserialize(content);
printIf(log, $" > Load nodes : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
load_process = 2;
load_step = 0;
// break;
// case 2 :
ds_queue_clear(CONNECTION_CONFLICT);
try {
array_foreach(create_list, function(node) /*=>*/ {return node.loadGroup()} );
} catch(e) {
log_warning("LOAD, group", exception_print(e));
return false;
}
printIf(log, $" > Load group : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
load_process = 3;
// break;
// case 3 :
try {
array_foreach(create_list, function(node) /*=>*/ {return node.postDeserialize()} );
} catch(e) {
log_warning("LOAD, deserialize", exception_print(e));
}
printIf(log, $" > Deserialize: {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
load_process = 4;
// break;
// case 4 :
// var _skp = false;
// var _t = get_timer();
try {
for(; load_step < node_length; load_step++) {
create_list[load_step].applyDeserialize();
// var _ts = get_timer() - _t;
// if(load_step < node_length - 1 && _ts > load_delay) {
// _skp = true;
// break;
// }
}
} catch(e) {
log_warning("LOAD, apply deserialize", exception_print(e));
}
// load_noti.progress = lerp(.75, .9, load_step / node_length);
// if(_skp) break;
load_noti.progress = .9;
printIf(log, $" > Apply deserialize : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
load_process = 5;
load_step = 0;
// break;
// case 5 :
try {
array_foreach(create_list, function(node) /*=>*/ {return node.preConnect()} );
array_foreach(create_list, function(node) /*=>*/ {return node.connect()} );
array_foreach(create_list, function(node) /*=>*/ {return node.postConnect()} );
} catch(e) {
log_warning("LOAD, connect", exception_print(e));
}
printIf(log, $" > Connect : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
if(!ds_queue_empty(CONNECTION_CONFLICT)) {
var pass = 0;
try {
while(++pass < 4 && !ds_queue_empty(CONNECTION_CONFLICT)) {
var size = ds_queue_size(CONNECTION_CONFLICT);
log_message("LOAD", $"[Connect] {size} Connection conflict(s) detected (pass: {pass})");
repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).connect();
repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).postConnect();
Render();
}
if(!ds_queue_empty(CONNECTION_CONFLICT))
log_warning("LOAD", "Some connection(s) is unsolved. This may caused by render node not being update properly, or image path is broken.");
} catch(e) {
log_warning("LOAD, connect solver", exception_print(e));
}
}
load_noti.progress = 0.92;
printIf(log, $" > Conflict : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
load_process = 6;
// break;
// case 6 :
try {
array_foreach(create_list, function(node) { node.postLoad(); } );
} catch(e) {
log_warning("LOAD, connect", exception_print(e));
}
printIf(log, $" > Post load : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
try {
array_foreach(create_list, function(node) { node.clearInputCache(); } );
} catch(e) {
log_warning("LOAD, connect", exception_print(e));
}
load_noti.progress = 0.95;
printIf(log, $" > Clear cache : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
load_process = 7;
// break;
// case 7 :
RENDER_ALL_REORDER
LOADING = false;
PROJECT.modified = false;
if(!IS_CMD) PANEL_MENU.setNotiIcon(THEME.noti_icon_file_load);
refreshNodeMap();
printIf(log, $" > Refresh map : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
if(struct_has(content, "timelines") && !array_empty(content.timelines.contents))
PROJECT.timelines.deserialize(content.timelines);
printIf(log, $" > Timeline : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
if(!IS_CMD) {
PANEL_GRAPH.toCenterNode();
PANEL_GRAPH.connection_draw_update = true;
}
log_message("FILE", $"load {path} completed in {(get_timer() - t0) / 1000} ms", THEME.noti_icon_file_load);
log_console("Loaded project: " + path);
printIf(log, $"========== Load {array_length(PROJECT.allNodes)} nodes completed in {(get_timer() - t0) / 1000} ms ==========");
if((PROJECT.load_layout || PREFERENCES.save_layout) && struct_has(content, "layout"))
LoadPanelStruct(content.layout.panel);
array_remove(STATS_PROGRESS, load_noti);
instance_destroy();
}

View file

@ -0,0 +1,36 @@
{
"$GMObject":"",
"%Name":"project_loader",
"eventList":[
{"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
{"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":3,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
],
"managed":true,
"name":"project_loader",
"overriddenProperties":[],
"parent":{
"name":"project",
"path":"folders/functions/project.yy",
},
"parentObjectId":null,
"persistent":false,
"physicsAngularDamping":0.1,
"physicsDensity":0.5,
"physicsFriction":0.2,
"physicsGroup":1,
"physicsKinematic":false,
"physicsLinearDamping":0.1,
"physicsObject":false,
"physicsRestitution":0.1,
"physicsSensor":false,
"physicsShape":1,
"physicsShapePoints":[],
"physicsStartAwake":true,
"properties":[],
"resourceType":"GMObject",
"resourceVersion":"2.0",
"solid":false,
"spriteId":null,
"spriteMaskId":null,
"visible":true,
}

View file

@ -340,4 +340,8 @@ function areaBox(_onModify, _unit = noone) : widget() constructor {
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -122,9 +122,10 @@ function array_exists(arr, val) {
self.__temp_val = val;
if(!is_array(arr)) return false;
return array_any(arr, function(_val, _ind) {
return isEqual(_val, self.__temp_val);
});
var _a = array_any(arr, function(_val, _ind) { return isEqual(_val, self.__temp_val); });
self.__temp_val = 0;
return _a;
}
function array_overlap(arr0, arr1) {
@ -134,9 +135,10 @@ function array_overlap(arr0, arr1) {
if(!is_array(arr0)) return false;
if(!is_array(arr1)) return false;
return array_any(arr0, function(_val, _ind) {
return array_exists(self.__temp_arr, _val);
});
var _a = array_any(arr0, function(_val, _ind) { return array_exists(self.__temp_arr, _val); });
self.__temp_arr = 0;
return _a;
}
function array_empty(arr) { INLINE return is_array(arr) && array_length(arr) == 0; }
@ -148,7 +150,10 @@ function array_find(arr, val) {
self.__temp_val = val;
if(!is_array(arr)) return -1;
return array_find_index(arr, function(_val, _ind) { return isEqual(_val, self.__temp_val); });
var _a = array_find_index(arr, function(_val, _ind) { return isEqual(_val, self.__temp_val); });
self.__temp_val = 0;
return _a;
}
function array_find_string(arr, val) {
@ -156,7 +161,10 @@ function array_find_string(arr, val) {
self.__temp_val = string_lower(val);
if(!is_array(arr)) return -1;
return array_find_index(arr, function(_val, _ind) { return string_lower(_val) == self.__temp_val; });
var _a = array_find_index(arr, function(_val, _ind) { return string_lower(_val) == self.__temp_val; });
self.__temp_val = 0;
return _a;
}
function array_remove(arr, val) {

View file

@ -13,12 +13,12 @@ function buttonGradient(_onApply, dialog = noone) : widget() constructor {
hover_index = 0;
function apply(value) { #region
function apply(value) {
if(!interactable) return;
onApply(value);
} #endregion
}
static trigger = function() { #region
static trigger = function() {
var dialog = dialogCall(o_dialog_gradient, WIN_W / 2, WIN_H / 2);
dialog.setDefault(current_gradient.clone());
dialog.onApply = apply;
@ -27,9 +27,9 @@ function buttonGradient(_onApply, dialog = noone) : widget() constructor {
if(parentDialog)
parentDialog.addChildren(dialog);
} #endregion
}
static triggerSingle = function(_index) { #region
static triggerSingle = function(_index) {
edit_color_index = _index;
var dialog = dialogCall(o_dialog_color_selector, WIN_W / 2, WIN_H / 2);
@ -37,18 +37,18 @@ function buttonGradient(_onApply, dialog = noone) : widget() constructor {
dialog.selector.onApply = editColor;
dialog.onApply = editColor;
dialog.interactable = interactable;
} #endregion
}
function editColor(col) { #region
function editColor(col) {
if(edit_color_index == -1) return;
edit_color_index.value = col;
apply(current_gradient);
} #endregion
}
static drawParam = function(params) { return draw(params.x, params.y, params.w, params.h, params.data, params.m); }
static draw = function(_x, _y, _w, _h, _gradient, _m) { #region
static draw = function(_x, _y, _w, _h, _gradient, _m) {
x = _x;
y = _y;
w = _w;
@ -252,10 +252,10 @@ function buttonGradient(_onApply, dialog = noone) : widget() constructor {
resetFocus();
return h;
} #endregion
}
static clone = function() { #region
static clone = function() {
var cln = new buttonGradient(onApply, parentDialog);
return cln;
} #endregion
}
}

View file

@ -155,4 +155,15 @@ function controlPointBox(_onModify) : widget() constructor {
return cln;
}
static free = function() {
tbCx.free();
tbCy.free();
tbFx.free();
tbFy.free();
tbW.free();
tbH.free();
rot.free();
sW.free();
}
}

View file

@ -120,4 +120,8 @@ function cornerBox(_onModify, _unit = noone) : widget() constructor {
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -610,4 +610,8 @@ function curveBox(_onModify) : widget() constructor {
var cln = new curveBox(onModify);
return cln;
}
static free = function() {
surface_free_safe(curve_surface);
}
}

View file

@ -1,5 +1,4 @@
function folderArrayBox(_arr, _onApply) : widget() constructor {
onApply = _onApply;
array = _arr;
editing = noone;
@ -101,4 +100,8 @@ function folderArrayBox(_arr, _onApply) : widget() constructor {
return cln;
}
static free = function() {
tb_edit.free();
}
}

View file

@ -44,7 +44,7 @@
LATEST_VERSION = 1_18_00_0;
VERSION = 1_18_04_0;
SAVE_VERSION = 1_18_04_0;
VERSION_STRING = MAC? "1.18.003m" : "1.18.5.004";
VERSION_STRING = MAC? "1.18.003m" : "1.18.5.005";
BUILD_NUMBER = 1_18_04_1;
HOTKEYS = ds_map_create();

View file

@ -78,7 +78,7 @@ function LOAD_PATH(path, readonly = false, safe_mode = false) {
}
function LOAD_AT(path, params = new __loadParams()) {
static log = false;
static log = 0;
CALL("load");
@ -122,7 +122,7 @@ function LOAD_AT(path, params = new __loadParams()) {
printIf(log, $" > Create temp : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
var _load_content;
var content;
var _ext = filename_ext_raw(path);
var s;
@ -139,146 +139,10 @@ function LOAD_AT(path, params = new __loadParams()) {
buffer_delete(bf);
_load_content = json_try_parse(s);
content = json_try_parse(s);
printIf(log, $" > Load struct : {(get_timer() - t1) / 1000} ms");
printIf(log, $" > Load struct : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
if(struct_has(_load_content, "version")) {
var _v = _load_content.version;
PROJECT.version = _v;
LOADING_VERSION = _v;
if(PREFERENCES.notify_load_version && floor(_v) != floor(SAVE_VERSION)) {
var warn = $"File version mismatch : loading file version {_v} to Pixel Composer {SAVE_VERSION}";
log_warning("LOAD", warn);
}
} else {
var warn = $"File version mismatch : loading old format to Pixel Composer {SAVE_VERSION}";
log_warning("LOAD", warn);
}
printIf(log, $" > Load meta : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
var create_list = [];
if(struct_has(_load_content, "nodes")) {
try {
var _node_list = _load_content.nodes;
for(var i = 0, n = array_length(_node_list); i < n; i++) {
var _node = nodeLoad(_node_list[i]);
if(_node) array_push(create_list, _node);
}
} catch(e) {
log_warning("LOAD", exception_print(e));
}
}
PROJECT.deserialize(_load_content);
ds_queue_clear(CONNECTION_CONFLICT);
try {
array_foreach(create_list, function(node) /*=>*/ {return node.loadGroup()} );
} catch(e) {
log_warning("LOAD, group", exception_print(e));
return false;
}
printIf(log, $" > Load group : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
try {
array_foreach(create_list, function(node) /*=>*/ {return node.postDeserialize()} );
} catch(e) {
log_warning("LOAD, deserialize", exception_print(e));
}
printIf(log, $" > Deserialize: {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
try {
array_foreach(create_list, function(node) /*=>*/ {return node.applyDeserialize()} );
} catch(e) {
log_warning("LOAD, apply deserialize", exception_print(e));
}
printIf(log, $" > Apply deserialize : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
try {
array_foreach(create_list, function(node) /*=>*/ {return node.preConnect()} );
array_foreach(create_list, function(node) /*=>*/ {return node.connect()} );
array_foreach(create_list, function(node) /*=>*/ {return node.postConnect()} );
} catch(e) {
log_warning("LOAD, connect", exception_print(e));
}
printIf(log, $" > Connect : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
if(!ds_queue_empty(CONNECTION_CONFLICT)) {
var pass = 0;
try {
while(++pass < 4 && !ds_queue_empty(CONNECTION_CONFLICT)) {
var size = ds_queue_size(CONNECTION_CONFLICT);
log_message("LOAD", $"[Connect] {size} Connection conflict(s) detected (pass: {pass})");
repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).connect();
repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).postConnect();
Render();
}
if(!ds_queue_empty(CONNECTION_CONFLICT))
log_warning("LOAD", "Some connection(s) is unsolved. This may caused by render node not being update properly, or image path is broken.");
} catch(e) {
log_warning("LOAD, connect solver", exception_print(e));
}
}
printIf(log, $" > Conflict : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
try {
array_foreach(create_list, function(node) { node.postLoad(); } );
} catch(e) {
log_warning("LOAD, connect", exception_print(e));
}
printIf(log, $" > Post load : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
try {
array_foreach(create_list, function(node) { node.clearInputCache(); } );
} catch(e) {
log_warning("LOAD, connect", exception_print(e));
}
printIf(log, $" > Clear cache : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
RENDER_ALL_REORDER
LOADING = false;
PROJECT.modified = false;
log_message("FILE", "load " + path, THEME.noti_icon_file_load);
log_console("Loaded project: " + path);
if(!IS_CMD) PANEL_MENU.setNotiIcon(THEME.noti_icon_file_load);
refreshNodeMap();
printIf(log, $" > Refresh map : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
if(struct_has(_load_content, "timelines") && !array_empty(_load_content.timelines.contents))
PROJECT.timelines.deserialize(_load_content.timelines);
printIf(log, $" > Timeline : {(get_timer() - t1) / 1000} ms"); t1 = get_timer();
if(!IS_CMD) run_in(1, PANEL_GRAPH.toCenterNode);
printIf(log, $"========== Load {array_length(PROJECT.allNodes)} nodes completed in {(get_timer() - t0) / 1000} ms ==========");
if((PROJECT.load_layout || PREFERENCES.save_layout) && struct_has(_load_content, "layout"))
LoadPanelStruct(_load_content.layout.panel);
return true;
return instance_create(0, 0, project_loader, { path, content, log, params, t0, t1 });
}
function __EXPORT_ZIP() { exportPortable(PROJECT); }

View file

@ -136,4 +136,8 @@ function matrixGrid(_type, _size, _onModify, _unit = noone) : widget() construct
var cln = new matrixGrid(type, size, onModify, unit);
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -283,6 +283,9 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con
return _newAtl;
}
if(is_instanceof(_outSurf, SurfaceAtlas)) _outSurf.surface.surface = _output;
else _outSurf = _output;
return _outSurf;
}

View file

@ -279,10 +279,11 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
static exitGroup = function() {}
static onAdd = function(_node) {}
static add = function(_node) {
array_push(getNodeList(), _node);
var list = _node.group == noone? PANEL_GRAPH.nodes_list : _node.group.getNodeList();
array_remove(list, _node);
var list = _node.group == noone? project.nodes : _node.group.getNodeList();
if(NOT_LOAD) array_remove(list, _node);
recordAction(ACTION_TYPE.group_added, self, _node);
_node.group = self;

View file

@ -36,8 +36,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
manual_ungroupable = true;
destroy_when_upgroup = false;
var l = _group == noone? PROJECT.nodes : _group.getNodeList();
array_push(l, self);
if(NOT_LOAD) array_push(_group == noone? project.nodes : _group.getNodeList(), self);
active_index = -1;
active_range = [ 0, TOTAL_FRAMES - 1 ];
@ -451,6 +450,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
inputs = _in;
refreshNodeDisplay();
}
static refreshDynamicDisplay = function() {
@ -1265,15 +1265,17 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
getJunctionList();
setJunctionIndex();
__preDraw_data.force = true;
} run_in(1, function() /*=>*/ { refreshNodeDisplay(); });
__preDraw_data = { _x: undefined, _y: undefined, _s: undefined, _p: undefined, sp: undefined };
__preDraw_data = { _x: undefined, _y: undefined, _s: undefined, _p: undefined, sp: undefined, force: false };
static preDraw = function(_x, _y, _s) {
var xx = x * _s + _x;
var yy = y * _s + _y;
var _upd = __preDraw_data._x != xx || __preDraw_data._y != yy || __preDraw_data._s != _s ||
var _upd = __preDraw_data._x != xx || __preDraw_data._y != yy || __preDraw_data._s != _s || __preDraw_data.force ||
__preDraw_data._p != previewable || __preDraw_data.sp != show_parameter
__preDraw_data._x = xx;
@ -1282,6 +1284,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
__preDraw_data._p = previewable;
__preDraw_data.sp = show_parameter;
__preDraw_data.force = false;
if(!_upd) {
if(SHOW_PARAM) h = h_param;
onPreDraw(_x, _y, _s, _iy, _oy);
@ -1356,7 +1360,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static getColor = function() { INLINE return attributes.color == -1? color : attributes.color; }
static drawNodeBase = function(xx, yy, _s) {
draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, getColor(), (.25 + .5 * renderActive) * (.25 + .75 * isHighlightingInGraph()));
draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, getColor(), .75 * (.25 + .75 * isHighlightingInGraph()));
}
static drawNodeOverlay = function(xx, yy, _mx, _my, _s) {}
@ -1409,7 +1413,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
if(_panel && _panel.node_hovering == self) ba = .1;
draw_sprite_stretched_ext(THEME.node_bg, 2, xx, yy, w * _s, nh, cc, ba);
var cc = COLORS._main_text;
var cc = renderActive? COLORS._main_text : COLORS._main_text_sub;
if(PREFERENCES.node_show_render_status && !rendered)
cc = isRenderable()? COLORS._main_value_positive : COLORS._main_value_negative;
@ -1424,7 +1428,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
if(icon) {
tx += _s * 6;
draw_sprite_ui_uniform(icon, 0, round(tx) + 1, round(yy + nh / 2) + 1, _s, c_black, 1);
draw_sprite_ui_uniform(icon, 0, round(tx), round(yy + nh / 2), _s, c_white, 1);
draw_sprite_ui_uniform(icon, 0, round(tx), round(yy + nh / 2), _s, cc, 1);
tx += _s * 12;
tw -= _s * (12 + 6);
}
@ -2481,25 +2485,27 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static preApplyDeserialize = function() {}
static postApplyDeserialize = function() {}
static loadGroup = function(context = noone) {
static loadGroup = function(ctx = noone) {
if(load_group == noone) {
if(context != noone) context.add(self);
} else {
if(APPENDING) load_group = GetAppendID(load_group);
if(ds_map_exists(PROJECT.nodeMap, load_group)) {
if(struct_has(PROJECT.nodeMap[? load_group], "add"))
PROJECT.nodeMap[? load_group].add(self);
else {
var txt = $"Group load failed. Node ID {load_group} is not a group.";
throw(txt);
}
} else {
var txt = $"Group load failed. Can't find node ID {load_group}";
throw(txt);
}
if(ctx) ctx.add(self);
else array_push(project.nodes, self);
onLoadGroup();
return;
}
if(APPENDING) load_group = GetAppendID(load_group);
if(ds_map_exists(PROJECT.nodeMap, load_group)) {
var _grp = PROJECT.nodeMap[? load_group];
if(struct_has(_grp, "add"))
_grp.add(self);
else
throw($"Group load failed. Node ID {load_group} is not a group.");
} else
throw($"Group load failed. Can't find node ID {load_group}");
onLoadGroup();
}
@ -2528,11 +2534,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
/////=========== CLEAN UP ===========
static cleanUp = function() {
for( var i = 0; i < array_length(inputs); i++ )
inputs[i].cleanUp();
for( var i = 0; i < array_length(outputs); i++ )
outputs[i].cleanUp();
for( var i = 0; i < array_length(inputs); i++ ) { inputs[i].cleanUp(); delete inputs[i]; }
for( var i = 0; i < array_length(outputs); i++ ) { outputs[i].cleanUp(); delete outputs[i]; }
for( var i = 0, n = array_length(temp_surface); i < n; i++ )
surface_free(temp_surface[i]);
@ -2762,5 +2765,5 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
} run_in(1, function() /*=>*/ { checkGroup(); });
static toString = function() { return $"Node [{internalName}]: {node_id}"; }
static toString = function() { return $"Node [{internalName}] [{instanceof(self)}]: {node_id}"; }
}

View file

@ -378,6 +378,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
}
} setDropKey();
mapWidget = noone;
mappedJunc = noone;
mapped_vec4 = false;
@ -994,7 +995,12 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
editWidget.side_button = display_data.side_button;
editWidgetRaw = editWidget;
if(editWidget) graphWidget = editWidget.clone();
if(editWidget) {
graphWidget = editWidget.clone();
editWidget.attributes = attributes;
graphWidget.attributes = attributes;
}
for( var i = 0, n = array_length(animator.values); i < n; i++ ) {
animator.values[i].ease_in_type = key_inter;
@ -1755,6 +1761,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
node.refreshNodeDisplay();
PROJECT.modified = true;
if(PANEL_GRAPH) PANEL_GRAPH.connection_draw_update = true;
RENDER_ALL_REORDER
@ -2374,7 +2381,13 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
}
}
static cleanUp = function() {}
static cleanUp = function() {
if(editWidget) editWidget.free();
if(mapWidget) mapWidget.free();
express_edit.free();
if(bypass_junc) { bypass_junc.cleanUp(); delete bypass_junc; }
}
static toString = function() { return (connect_type == CONNECT_TYPE.input? "Input" : "Output") + $" junction {index} of [{name}]: {node}"; }

View file

@ -1,9 +1,10 @@
#region notification
globalvar STATUSES, WARNING, ERRORS;
globalvar STATUSES, WARNING, ERRORS, STATS_PROGRESS;
STATUSES = ds_list_create();
WARNING = ds_list_create();
ERRORS = ds_list_create();
STATS_PROGRESS = [];
#endregion
#region classes
@ -28,6 +29,8 @@
self.tooltip = "";
self.icon_end = noone;
self.progress = noone;
self.amount = 1;
self.time = $"{string_lead_zero(current_hour, 2)}:{string_lead_zero(current_minute, 2)}.{string_lead_zero(current_second, 2)}";

View file

@ -134,7 +134,10 @@ function paddingBox(_onModify, _unit = noone) : widget() constructor {
static clone = function() {
var cln = new paddingBox(onModify, unit);
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -2703,6 +2703,17 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor {
}
tooltip_overlay = {};
if(LOADING) {
draw_set_color(CDEF.main_dkblack);
draw_set_alpha(0.3);
draw_rectangle(0, 0, w, h, false);
draw_set_alpha(1);
gpu_set_tex_filter(true);
draw_sprite_ext(THEME.loading, 0, w / 2, h / 2, 1, 1, current_time / 2, COLORS._main_icon);
gpu_set_tex_filter(false);
}
}
//// ============ Action ============

View file

@ -485,6 +485,10 @@ function Panel_Menu() : PanelContent() constructor {
draw_sprite_stretched_ext(THEME.s_box_r2, 0, nx0, ny0 - nh / 2, nw, nh, cc, ev / 2);
gpu_set_blendmode(bm_normal);
var _prg = noone;
for( var i = 0, n = array_length(STATS_PROGRESS); i < n; i++ ) _prg = max(_prg, STATS_PROGRESS[i].progress);
if(_prg > noone) draw_sprite_stretched_ext(THEME.s_box_r2, 0, nx0, ny0 - nh / 2, nw * clamp(_prg, 0, 1), nh, COLORS._main_value_positive, .5);
if(noti_icon_show > 0)
draw_sprite_ui(noti_icon, 0, nx0 + nw - ui(16), ny0,,,,, noti_icon_show);

View file

@ -139,8 +139,6 @@ function Panel_Notification() : PanelContent() constructor {
var bx = _w - ui(0) - bw;
var by = yy + ui(0) + ui(1);
// draw_sprite_stretched_ext(THEME.s_box_r2, 0, bx, by, bw, bh, CDEF.main_dkblack, 0.75);
draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_accent);
draw_text(bx + bw / 2, by + bh / 2, noti.amount);
}
@ -153,8 +151,6 @@ function Panel_Notification() : PanelContent() constructor {
return hh;
});
function drawContent(panel) {
draw_clear_alpha(COLORS.panel_bg_clear, 0);

View file

@ -85,7 +85,10 @@ function pathAnchorBox(_onModify) : widget() constructor {
static clone = function() {
var cln = new pathAnchorBox(onModify);
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -209,12 +209,16 @@
array_foreach(allNodes, function(_node) {
_node.active = false;
_node.cleanUp();
delete _node;
});
ds_map_destroy(nodeMap);
ds_map_destroy(nodeNameMap);
gc_collect();
run_in_s(1, function() /*=>*/ { gc_collect(); gc_enable(true); });
ds_stack_clear(UNDO_STACK);
}
static toString = function() { return $"ProjectObject [{path}]"; }

View file

@ -141,4 +141,8 @@ function quarternionBox(_onModify) : widget() constructor {
var cln = new quarternionBox(onModify);
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -125,4 +125,8 @@ function rangeBox(_type, _onModify) : widget() constructor {
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -17,7 +17,7 @@ enum RENDER_TYPE {
global.getvalue_hit = 0;
#endregion
function ResetAllNodesRender() { #region
function ResetAllNodesRender() {
LOG_IF(global.FLAG.render == 1, $"XXXXXXXXXXXXXXXXXXXX RESETTING ALL NODES [frame {CURRENT_FRAME}] XXXXXXXXXXXXXXXXXXXX");
array_foreach(PROJECT.allNodes, function(_node) {
@ -29,9 +29,9 @@ function ResetAllNodesRender() { #region
return;
});
} #endregion
}
function NodeTopoSort() { #region
function NodeTopoSort() {
LOG_IF(global.FLAG.render == 1, $"======================= RESET TOPO =======================")
var amo = array_length(PROJECT.allNodes);
@ -46,9 +46,9 @@ function NodeTopoSort() { #region
__topoSort(PROJECT.nodeTopo, PROJECT.nodes);
LOG_IF(global.FLAG.render == 1, $"+++++++ Topo Sort Completed: {array_length(PROJECT.nodeTopo)}/{amo} nodes sorted in {(get_timer() - _t) / 1000} ms +++++++");
} #endregion
}
function NodeListSort(_nodeList) { #region
function NodeListSort(_nodeList) {
array_foreach(_nodeList, function(node) {
node.clearTopoSorted();
return 0;
@ -57,9 +57,9 @@ function NodeListSort(_nodeList) { #region
var _arr = [];
__topoSort(_arr, _nodeList);
return _arr;
} #endregion
}
function __sortNode(_arr, _node) { #region
function __sortNode(_arr, _node) {
if(_node.topoSorted) return;
var _parents = [];
@ -86,9 +86,9 @@ function __sortNode(_arr, _node) { #region
// print($" > Adding > {_node.name}");
}
} #endregion
}
function __topoSort(_arr, _nodeArr) { #region
function __topoSort(_arr, _nodeArr) {
var _root = [];
var _leftOver = [];
var _global = _nodeArr == PROJECT.nodes;
@ -129,9 +129,11 @@ function __topoSort(_arr, _nodeArr) { #region
if(!_leftOver[i].topoSorted)
array_insert(_arr, 0, _leftOver[i]);
}
} #endregion
__temp_nodeList = [];
}
function __nodeLeafList(_arr) { #region
function __nodeLeafList(_arr) {
var nodes = [];
var nodeNames = [];
@ -148,9 +150,9 @@ function __nodeLeafList(_arr) { #region
LOG_LINE_IF(global.FLAG.render == 1, $"Push node {nodeNames} to queue");
return nodes;
} #endregion
}
function __nodeIsRenderLeaf(_node) { #region
function __nodeIsRenderLeaf(_node) {
if(is_undefined(_node)) { LOG_IF(global.FLAG.render == 1, $"Skip undefiend [{_node}]"); return false; }
if(!is_instanceof(_node, Node)) { LOG_IF(global.FLAG.render == 1, $"Skip non-node [{_node}]"); return false; }
@ -166,9 +168,9 @@ function __nodeIsRenderLeaf(_node) { #region
if(_node.inline_context != noone && _node.inline_context.managedRenderOrder) return false;
return true;
} #endregion
}
function Render(partial = false, runAction = false) { #region
function Render(partial = false, runAction = false) {
LOG_END();
LOG_BLOCK_START();
@ -274,18 +276,18 @@ function Render(partial = false, runAction = false) { #region
LOG_END();
} #endregion
}
function __renderListReset(arr) { #region
function __renderListReset(arr) {
for( var i = 0; i < array_length(arr); i++ ) {
arr[i].setRenderStatus(false);
if(struct_has(arr[i], "nodes"))
__renderListReset(arr[i].nodes);
}
} #endregion
}
function RenderList(arr) { #region
function RenderList(arr) {
LOG_BLOCK_START();
LOG_IF(global.FLAG.render == 1, $"=============== RENDER LIST START [{array_length(arr)}] ===============");
var queue = ds_queue_create();
@ -348,4 +350,4 @@ function RenderList(arr) { #region
LOG_END();
ds_queue_destroy(queue);
} #endregion
}

View file

@ -123,7 +123,10 @@ function rotator(_onModify, _step = -1) : widget() constructor {
static clone = function() {
var cln = new rotator(onModify, valStep);
return cln;
}
static free = function() {
tb_value.free();
}
}

View file

@ -464,4 +464,11 @@ function rotatorRandom(_onModify) : widget() constructor {
var cln = new rotatorRandom(onModify);
return cln;
}
static free = function() {
tb_min_0.free();
tb_max_0.free();
tb_min_1.free();
tb_max_1.free();
}
}

View file

@ -131,4 +131,9 @@ function rotatorRange(_onModify) : widget() constructor {
var cln = new rotatorRange(onModify);
return cln;
}
static free = function() {
tb_min.free();
tb_max.free();
}
}

View file

@ -170,4 +170,8 @@ function scrollPane(_w, _h, ondraw) : widget() constructor {
}
}
}
static free = function() {
surface_free(surface);
}
}

View file

@ -89,4 +89,9 @@ function sliderRange(_step, _int, _range, _onModify) : widget() constructor {
return cln;
}
static free = function() {
tb_value_min.free();
tb_value_max.free();
}
}

View file

@ -1,9 +1,9 @@
function string_lead_zero(val, digit) {
function string_lead_zero(val, digit, _pad = "0") {
var len = string_length(string(val));
var zer = digit - len;
var ss = "";
repeat(zer) ss += "0";
repeat(zer) ss += _pad;
ss += string(val);
return ss;

View file

@ -1036,4 +1036,8 @@ function textArea(_input, _onModify) : textInput(_input, _onModify) constructor
var cln = new textArea(input, onModify);
return cln;
}
static free = function() {
surface_free_safe(text_surface);
}
}

View file

@ -849,4 +849,8 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor {
var cln = new textBox(input, onModify);
return cln;
}
static free = function() {
surface_free_safe(text_surface);
}
}

View file

@ -119,4 +119,8 @@ function transformBox(_onModify) : widget() constructor {
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -180,4 +180,8 @@ function vectorBox(_size, _onModify, _unit = noone) : widget() constructor {
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -165,4 +165,8 @@ function vectorRangeBox(_size, _type, _onModify, _unit = noone) : widget() const
return cln;
}
static free = function() {
for( var i = 0, n = array_length(tb); i < n; i++ ) tb[i].free();
}
}

View file

@ -105,6 +105,8 @@ function widget() constructor {
static drawParam = function(params) {}
static draw = function() {}
static free = function() {}
}
function widgetParam(x, y, w, h, data, display_data = {}, m = mouse_ui, rx = 0, ry = 0) constructor {