Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
dicksonlaw583 committed Aug 6, 2018
0 parents commit 2762f8f
Show file tree
Hide file tree
Showing 279 changed files with 4,980 additions and 0 deletions.
771 changes: 771 additions & 0 deletions GetSet2.yyp

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Universal Getter + Setter (GMS 2.x)

## Overview

This GML extension allows you to reach into deeply nested arrays and data structures in one line. It also adds the ability to use negative index numbers to count backwards from the end on arrays, lists and grids, similar to Python and Ruby.

## Examples

```
var json = @'{ "a": [1, 2, { "b": 3 }]}',
json_data = json_decode(json);
show_message(Get(json_data, "a", 2, "b")); //3
show_message(Get(json_data, "a", -2)); //2
```

```
var nested_array = [[1, 1], [4, 4], [9, 9]];
Set(nested_array, -1, 1, 16);
show_message(Get(nested_array, 2, 0)); //9
show_message(Get(nested_array, 2, 1)); //16
```

## Functions

- `Get(array_or_ds, ...)`: Search the array or data structure recursively using the indexes in order, then return the value found there.
- `Set(array_or_ds, ..., newvalue)`: Search the array or data structure recursively using the indexes in order, then set the value there to the new value.
- `Pos(i, j)`: (legacy holdover from GMS 1.4 version) Return a 2-entry array containing `i` and `j` in that order. For use as a position index in a 2D array or grid.

### Position Index Format

- 1D array: Real number
- 2D array: 2-entry array of real numbers in `[i, j]` form
- Map: String
- List: Real number
- Grid: 2-entry array of real numbers in `[i, j]` form
- Stack: The special value `stack_top`
- Queue: The special value `queue_head` (note that this cannot be the last index in `Set`)
- Priority Queue: The special value `pq_min` for the minimum entry, or `pq_max` for the maximum entry (note that these cannot be the last index in `Set()`)

## Contribution Procedures

- Fork this repository.
- Open the project in GameMaker Studio 2.x and make your additions/changes to the main GML file in the extension `UniversalGetSet`.
- Add the corresponding tests for new/changed functionality to the `UniversalGetSet_test` script group.
- Run the project to test your additions.
- Open a pull request.

## License

The 3 main scripts (`Get`, `Set`, `Pos`) are hereby released into the public domain.

The tests for the main scripts are written using [GMAssert](https://github.com/dicksonlaw583/gmassert) and [GMSugar](https://github.com/dicksonlaw583/gmsugar).
236 changes: 236 additions & 0 deletions extensions/UniversalGetSet/UniversalGetSet.gml
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
#define Get
/// @description Get(array_or_ds, ...)
/// @param array_or_ds
/// @param ...
{
var result = argument[0];
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;
}
} 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];
}
break;
case "arraynumber":
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;
}
}
return result;
}

#define Set
/// @description Set(array_or_ds, ..., value)
/// @param array_or_ds
/// @param ...
/// @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;
}
} 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];
}
break;
case "arraynumber":
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;
}
}
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;
}
} 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);
}
target[@ k] = new_value;
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[@ k0, k1] = new_value;
break;
default:
show_error("Invalid index " + string(k) + " (" + string(i) + ")", true);
break;
}
}

#define Pos
/// @description Pos(x, y)
/// @param x
/// @param y
{
var pos = array_create(2);
pos[0] = argument0;
pos[1] = argument1;
return pos;
}

Loading

0 comments on commit 2762f8f

Please sign in to comment.