Skip to content

Commit

Permalink
Merge pull request #1 from YellowAfterlife/master
Browse files Browse the repository at this point in the history
Reorganized Get/Set/Pos implementations to be faster
  • Loading branch information
dicksonlaw583 committed Aug 16, 2018
2 parents 4c496bc + 15454ac commit 5c586e5
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 204 deletions.
330 changes: 130 additions & 200 deletions extensions/UniversalGetSet/UniversalGetSet.gml
Original file line number Diff line number Diff line change
@@ -1,236 +1,166 @@
#define Get
/// @description Get(array_or_ds, ...)
/// @description Get(array_or_ds, ...indexes)
/// @param array_or_ds
/// @param ...
/// @param ...indexes
{
var result = argument[0];
for (var i = 1; i < argument_count; i++) {
for (var i = 1; i < argument_count; ++i) {
var k = argument[i];
if (is_int32(k) || is_int64(k)) {
k = real(k);
}
switch (typeof(result)+typeof(k)) {
case "numbernumber":
if (k < 0) {
k += ds_list_size(result);
}
result = result[| k];
break;
case "numberstring":
result = result[? k];
break;
case "numberarray":
if (array_length_1d(k) == 1) {
k = k[0];
switch (k) {
case 0:
result = ds_priority_find_min(result);
break;
case 1:
result = ds_priority_find_max(result);
break;
case 2:
result = ds_stack_top(result);
break;
case 3:
result = ds_queue_head(result);
break;
default:
show_error("Invalid index " + string(k) + " (" + string(i) + ")", true);
break;
}
if (is_array(k)) {
if (array_length_1d(k) > 0) {
var k0, k1;
if (k[0] == global.g_Pos_tag) {
k0 = k[1];
k1 = k[2];
ds_stack_push(global.g_Pos_pool, k);
} else show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
if (is_array(result)) {
if (k0 < 0) k0 += array_height_2d(result);
if (k1 < 0) k1 += array_length_2d(result, k0);
result = result[k0, k1];
} else {
var k0 = k[0],
k1 = k[1];
if (k0 < 0) {
k0 += ds_grid_width(result);
}
if (k1 < 0) {
k1 += ds_grid_height(result);
}
result = result[# k0, k1];
if (k0 < 0) k0 += ds_grid_width(result);
if (k1 < 0) k1 += ds_grid_height(result);
result = result[#k0, k1];
}
break;
case "arraynumber":
if (k < 0) {
k += array_length_1d(result);
} else {
if (is_array(result)) {
show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
} else switch (k) {
case stack_top: result = ds_stack_top(result); break;
case queue_head: result = ds_queue_head(result); break;
case pq_min: result = ds_priority_find_min(result); break;
case pq_max: result = ds_priority_find_max(result); break;
default: show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
}
}
} else if (is_string(k)) {
result = result[?k];
} else {
if (is_array(result)) {
if (k < 0) k += array_length_1d(result);
result = result[k];
break;
case "arrayarray":
var k0 = k[0],
k1 = k[1];
if (k0 < 0) {
k0 += array_height_2d(result);
}
if (k1 < 0) {
k1 += array_length_2d(result, k0);
}
result = result[k0, k1];
break;
default:
show_error("Invalid index " + string(k) + " (" + string(i) + ")", true);
break;
} else {
if (k < 0) k += ds_list_size(result);
result = result[|k];
}
}
}
return result;
}

#define Set
/// @description Set(array_or_ds, ..., value)
/// @description Set(array_or_ds, ...indexes, value)
/// @param array_or_ds
/// @param ...
/// @param value
/// @param ...indexes
/// @param value
{
var target = argument[0];
for (var i = 1; i < argument_count-2; i++) {
var k = argument[i];
if (is_int32(k) || is_int64(k)) {
k = real(k);
}
switch (typeof(target)+typeof(k)) {
case "numbernumber":
if (k < 0) {
k += ds_list_size(target);
}
target = target[| k];
break;
case "numberstring":
target = target[? k];
break;
case "numberarray":
if (array_length_1d(k) == 1) {
k = k[0];
switch (k) {
case 0:
target = ds_priority_find_min(target);
break;
case 1:
target = ds_priority_find_max(target);
break;
case 2:
target = ds_stack_top(target);
break;
case 3:
target = ds_queue_head(target);
break;
default:
show_error("Invalid index " + string(k) + " (" + string(i) + ")", true);
break;
}
var i, k, k0, k1;
var n = argument_count - 2;
for (i = 1; i < n; ++i) {
k = argument[i];
if (is_array(k)) {
if (array_length_1d(k) > 0) {
if (k[0] == global.g_Pos_tag) {
k0 = k[1];
k1 = k[2];
ds_stack_push(global.g_Pos_pool, k);
} else show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
if (is_array(target)) {
if (k0 < 0) k0 += array_height_2d(target);
if (k1 < 0) k1 += array_length_2d(target, k0);
target = target[k0, k1];
} else {
var k0 = k[0],
k1 = k[1];
if (k0 < 0) {
k0 += ds_grid_width(target);
}
if (k1 < 0) {
k1 += ds_grid_height(target);
}
target = target[# k0, k1];
if (k0 < 0) k0 += ds_grid_width(target);
if (k1 < 0) k1 += ds_grid_height(target);
target = target[#k0, k1];
}
break;
case "arraynumber":
if (k < 0) {
k += array_length_1d(target);
} else {
if (is_array(target)) {
show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
} else switch (k) {
case stack_top: target = ds_stack_top(target); break;
case queue_head: target = ds_queue_head(target); break;
case pq_min: target = ds_priority_find_min(target); break;
case pq_max: target = ds_priority_find_max(target); break;
default: show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
}
}
} else if (is_string(k)) {
target = target[?k];
} else {
if (is_array(target)) {
if (k < 0) k += array_length_1d(target);
target = target[k];
break;
case "arrayarray":
var k0 = k[0],
k1 = k[1];
if (k0 < 0) {
k0 += array_height_2d(target);
}
if (k1 < 0) {
k1 += array_length_2d(target, k0);
}
target = target[k0, k1];
break;
default:
show_error("Invalid index " + string(k) + " (" + string(i) + ")", true);
break;
} else {
if (k < 0) k += ds_list_size(target);
target = target[|k];
}
}
}
var new_value = argument[argument_count-1];
k = argument[argument_count-2];
if (is_int32(k) || is_int64(k)) {
k = real(k);
}
switch (typeof(target)+typeof(k)) {
case "numbernumber":
if (k < 0) {
k += ds_list_size(target);
}
target[| k] = new_value;
break;
case "numberstring":
target[? k] = new_value;
break;
case "numberarray":
if (array_length_1d(k) == 1) {
k = k[0];
switch (k) {
case 0:
show_error("Cannot set minimum of priority queue.", true);
break;
case 1:
show_error("Cannot set maximum of priority queue.", true);
break;
case 2:
ds_stack_pop(target);
ds_stack_push(target, new_value);
break;
case 3:
show_error("Cannot set head of queue.", true);
break;
default:
show_error("Invalid index " + string(k) + " (" + string(i) + ")", true);
break;
}
var new_value = argument[n + 1];
k = argument[n];
if (is_array(k)) {
if (array_length_1d(k) > 0) {
if (k[0] == global.g_Pos_tag) {
k0 = k[1];
k1 = k[2];
ds_stack_push(global.g_Pos_pool, k);
} else show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
if (is_array(target)) {
if (k0 < 0) k0 += array_height_2d(target);
if (k1 < 0) k1 += array_length_2d(target, k0);
target[@k0, k1] = new_value;
} else {
var k0 = k[0],
k1 = k[1];
if (k0 < 0) {
k0 += ds_grid_width(target);
}
if (k1 < 0) {
k1 += ds_grid_height(target);
}
target[# k0, k1] = new_value;
}
break;
case "arraynumber":
if (k < 0) {
k += array_length_1d(target);
if (k0 < 0) k0 += ds_grid_width(target);
if (k1 < 0) k1 += ds_grid_height(target);
target[#k0, k1] = new_value;
}
target[@ k] = new_value;
break;
case "arrayarray":
var k0 = k[0],
k1 = k[1];
if (k0 < 0) {
k0 += array_height_2d(target);
} else {
if (is_array(target)) {
show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
} else switch (k) {
case stack_top: ds_stack_pop(target); ds_stack_push(target, new_value); break;
case queue_head: show_error("Cannot set head of queue.", true); break;
case pq_min: show_error("Cannot set minimum of priority queue.", true); break;
case pq_max: show_error("Cannot set maximum of priority queue.", true); break;
default: show_error("Invalid index `" + string(k) + "` [" + string(i) + "]", 1);
}
if (k1 < 0) {
k1 += array_length_2d(target, k0);
}
target[@ k0, k1] = new_value;
break;
default:
show_error("Invalid index " + string(k) + " (" + string(i) + ")", true);
break;
}
} else if (is_string(k)) {
target[?k] = new_value;
} else {
if (is_array(target)) {
if (k < 0) k += array_length_1d(target);
target[@k] = new_value;
} else {
if (k < 0) k += ds_list_size(target);
target[|k] = new_value;
}
}
return new_value;
}

#define Pos
/// @description Pos(x, y)
/// @param x
/// @param y
/// @param y
gml_pragma("global", @'{
stack_top = [];
queue_head = [];
pq_min = [];
pq_max = [];
global.g_Pos_tag = [];
global.g_Pos_pool = ds_stack_create()
}');
{
var pos = array_create(2);
pos[0] = argument0;
pos[1] = argument1;
return pos;
// VD: Once 2.2 is out, can pop and check if it's undefined
// As for now, https://bugs.yoyogames.com/view.php?id=29747
if (ds_stack_empty(global.g_Pos_pool)) return [global.g_Pos_tag, argument0, argument1];
var r = ds_stack_pop(global.g_Pos_pool);
r[@1] = argument0;
r[@2] = argument1;
return r;
}

Loading

0 comments on commit 5c586e5

Please sign in to comment.