forked from SirRamEsq/SmartShape2D
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Use Vector2i instead of Array[int] - Less error prone - No problems with typed arrays - Better suits the tuple type - Refactor tuple utility functions - Provide helper function for array and dictionary access with index-tuples - O(1) access for dictionaries rather than O(n) - Code cleanup - Bugfix in IndexMap.indicies_to_edges(): The function now correctly operates on the array's values instead of only its indices.
- Loading branch information
Showing
12 changed files
with
507 additions
and
390 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,135 @@ | ||
@tool | ||
extends RefCounted | ||
class_name SS2D_IndexTuple | ||
|
||
## Everything in this script should be static. | ||
## Provides utility functions for handling and storing indices of two related points using Vector2i. | ||
## | ||
## This script contains code that may referenced in multiple locations in the plugin. | ||
## Index tuples are considered equal if their elements are equal, regardless of their order: | ||
## T(X, Y) <=> T(Y, X). | ||
## | ||
## This is a simple script for a *very* simple tuple class | ||
## Some notes: | ||
## - "tuples" are just an array with two elements | ||
## - Only integer Tuples are fully supported | ||
## - Tuple(X,Y) is equal to Tuple(Y,X) | ||
## For effectively working with containers, helper functions for arrays and dictionaries are | ||
## provided that implement the above behavior. | ||
|
||
|
||
static func create_tuple(a: int, b: int) -> Array[int]: | ||
return [a, b] | ||
## Returns the second tuple element that does not equal the given value. | ||
## Returns -1 if neither element matches. | ||
static func get_other_value(t: Vector2i, value: int) -> int: | ||
if t.x == value: | ||
return t.y | ||
elif t.y == value: | ||
return t.x | ||
return -1 | ||
|
||
|
||
static func get_other_value_from_tuple(t: Array[int], value: int) -> int: | ||
if t[0] == value: | ||
return t[1] | ||
elif t[1] == value: | ||
return t[0] | ||
return -1 | ||
## Returns whether two tuples are equal. Two tuples are considered equal when both contain the same values regardless of order. | ||
static func are_equal(t1: Vector2i, t2: Vector2i) -> bool: | ||
return t1 == t2 or t1 == flip_elements(t2) | ||
|
||
|
||
static func tuples_are_equal(t1: Array[int], t2: Array[int]) -> bool: | ||
return (t1[0] == t2[0] and t1[1] == t2[1]) or (t1[0] == t2[1] and t1[1] == t2[0]) | ||
## Returns true when the tuple contains the given value. | ||
static func has(t: Vector2i, value: int) -> bool: | ||
return t.x == value or t.y == value | ||
|
||
|
||
static func find_tuple_in_array_of_tuples(tuple_array: Array, t: Array[int]) -> int: | ||
for i in range(tuple_array.size()): | ||
var other: Array[int] = [] | ||
other.assign(tuple_array[i]) | ||
if tuples_are_equal(t, other): | ||
## Searches for an equal tuple in the given array and returns the index or -1 if not found. | ||
## Incorporates the equality behavior. | ||
static func array_find(tuple_array: Array[Vector2i], t: Vector2i) -> int: | ||
for i in tuple_array.size(): | ||
if are_equal(tuple_array[i], t): | ||
return i | ||
return -1 | ||
|
||
|
||
static func is_tuple_in_array_of_tuples(tuple_array: Array, t: Array[int]) -> bool: | ||
return find_tuple_in_array_of_tuples(tuple_array, t) != -1 | ||
## Returns whether the given tuple exists in the given array. | ||
## Incorporates the equality behavior. | ||
static func array_has(tuple_array: Array[Vector2i], t: Vector2i) -> bool: | ||
return array_find(tuple_array, t) != -1 | ||
|
||
|
||
## Returns a list indices to tuples that contain the given value. | ||
static func array_find_partial(tuple_array: Array[Vector2i], value: int) -> Array[int]: | ||
var out: Array[int] = [] | ||
|
||
for i in tuple_array.size(): | ||
if tuple_array[i].x == value or tuple_array[i].y == value: | ||
out.push_back(i) | ||
|
||
return out | ||
|
||
|
||
## Returns a tuple with elements in ascending order. | ||
static func normalize_tuple(tuple: Vector2i) -> Vector2i: | ||
if tuple.x <= tuple.y: | ||
return tuple | ||
return flip_elements(tuple) | ||
|
||
|
||
## Returns a tuple with x and y components switched. | ||
static func flip_elements(tuple: Vector2i) -> Vector2i: | ||
return Vector2i(tuple.y, tuple.x) | ||
|
||
|
||
## Validates the keys of a dictionary to be correct tuple values and converts all Arrays to | ||
## corresponding Vector2i values. | ||
## Optionally also validates that values are of the given type. | ||
## Exists mostly for backwards compatibility to allow a seamless transition from Array to Vector2i tuples. | ||
static func dict_validate(dict: Dictionary, value_type: Variant = null) -> void: | ||
# TODO: Maybe don't use asserts but push_warning and return true if successful | ||
for key: Variant in dict.keys(): | ||
var value: Variant = dict[key] | ||
|
||
if value_type != null: | ||
assert(is_instance_of(value, value_type), "Incorrect value type in dictionary: " + var_to_str(value)) | ||
|
||
if key is Array: | ||
var converted := Vector2i(int(key[0]), int(key[1])) | ||
dict.erase(key) | ||
dict[converted] = value | ||
else: | ||
assert(key is Vector2i, "Invalid tuple representation: %s. Should be Vector2i." % var_to_str(key)) | ||
|
||
|
||
## Get the value in a dictionary with the given tuple as key or a default value if it does not exist. | ||
## Incorporates the equality behavior. | ||
static func dict_get(dict: Dictionary, tuple: Vector2i, default: Variant = null) -> Variant: | ||
if dict.has(tuple): | ||
return dict[tuple] | ||
return dict.get(flip_elements(tuple), default) | ||
|
||
|
||
static func dict_has(dict: Dictionary, tuple: Vector2i) -> bool: | ||
if dict.has(tuple): | ||
return true | ||
return dict.has(flip_elements(tuple)) | ||
|
||
|
||
static func dict_set(dict: Dictionary, tuple: Vector2i, value: Variant) -> void: | ||
dict[dict_get_key(dict, tuple)] = value | ||
|
||
|
||
## Removes the given entry from the dictionary. Returns true if a corresponding key existed, otherwise false. | ||
static func dict_erase(dict: Dictionary, tuple: Vector2i) -> bool: | ||
return dict.erase(dict_get_key(dict, tuple)) | ||
|
||
|
||
## Checks if there is an existing key for the given tuple or its flipped variant and returns it. | ||
## If a key does not exist, returns the tuple as it is. | ||
## Usually this function does not need to be invoked manually, as helpers for dictionary and array access exist. | ||
static func dict_get_key(dict: Dictionary, tuple: Vector2i) -> Vector2i: | ||
if not dict.has(tuple): | ||
var flipped := flip_elements(tuple) | ||
|
||
if dict.has(flipped): | ||
return flipped | ||
|
||
return tuple | ||
|
||
|
||
## Returns a list of all dictionary keys (tuples) that contain the given value. | ||
static func dict_find_partial(dict: Dictionary, value: int) -> Array[Vector2i]: | ||
var out: Array[Vector2i] = [] | ||
|
||
for t: Vector2i in dict.keys(): | ||
if t.x == value or t.y == value: | ||
out.push_back(t) | ||
|
||
static func is_tuple(thing: Variant) -> bool: | ||
if not thing is Array: | ||
return false | ||
var arr := thing as Array | ||
return arr and arr.size() == 2 | ||
return out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.