First upgrade to Godot 4.

This commit is contained in:
Patrick 2021-08-21 20:56:19 +02:00
parent 47fbd56b9a
commit 74d4a37de2
Signed by: mewin
GPG Key ID: CEDB412C39B5BC47
15 changed files with 211 additions and 191 deletions

View File

@ -18,7 +18,7 @@ class __SortBy:
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
# Packs source code into a small script object, like a lambda in other languages. # Packs source code into a small script object, like a lambda in other languages.
@ -35,11 +35,11 @@ func _init() -> void:
# @param params A list of parameter names your function takes. # @param params A list of parameter names your function takes.
# @param fn_name The name of the resulting function, defaults to "eval". # @param fn_name The name of the resulting function, defaults to "eval".
# @returns An object containing the lambda function as fn_name. # @returns An object containing the lambda function as fn_name.
static func lambda(source : String, params := [], fn_name := "eval") -> Reference: static func lambda(source : String, params := [], fn_name := "eval") -> RefCounted:
var script := GDScript.new(); var script := GDScript.new();
script.source_code = "tool\nextends Reference\nfunc {fn_name}({param_list}):\n\t{source}".format({ script.source_code = "tool\nextends Reference\nfunc {fn_name}({param_list}):\n\t{source}".format({
"source": source, "source": source,
"param_list": PoolStringArray(params).join(","), "param_list": ",".join(PackedStringArray(params)),
"fn_name": fn_name "fn_name": fn_name
}) })
var err : int = script.reload() var err : int = script.reload()
@ -63,12 +63,12 @@ static func lambda(source : String, params := [], fn_name := "eval") -> Referenc
# Example 2: # Example 2:
# func remove_negatives2(col): # func remove_negatives2(col):
# GDBAlgorithm.remove_if(col, "num < 0", ["num"]) # GDBAlgorithm.remove_if(col, "num < 0", ["num"])
static func remove_if(collection, p0, p1 = null) -> int: static func remove_if(collection, p0, p1 : Variant = null) -> int:
if p0 is String: if p0 is String:
if p1 && !p1 is Array: if p1 && !p1 is Array:
printerr("remove_if failed: invalid parameters") printerr("remove_if failed: invalid parameters")
return 0 return 0
var lmb := lambda(p0 as String, p1 as Array if p1 else []) var lmb := lambda(p0 as String, p1 if p1 is Array else [])
if !lmb: if !lmb:
return 0 # errors have already been printed return 0 # errors have already been printed
return __remove_if(collection, lmb, "eval") return __remove_if(collection, lmb, "eval")
@ -82,7 +82,7 @@ static func sort_by(arr : Array, prop_name : String, descending := false):
var comparator := __SortBy.new() var comparator := __SortBy.new()
comparator.prop_name = prop_name comparator.prop_name = prop_name
comparator.descending = descending comparator.descending = descending
arr.sort_custom(comparator, "__sort") arr.sort_custom(comparator.__sort)
################# #################
# private stuff # # private stuff #

View File

@ -11,5 +11,5 @@ const SETTING_FAVOURITE_PLACES = "favourite_places"
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")

View File

@ -6,7 +6,7 @@ extends Object
class_name GDBCoroutine class_name GDBCoroutine
class __WaitAll: class __WaitAll:
var __SIG_SEPERATOR = Reference.new() var __SIG_SEPERATOR = RefCounted.new()
var remaining_signals : Array var remaining_signals : Array
var results := [] var results := []
@ -18,7 +18,7 @@ class __WaitAll:
results.resize(remaining_signals.size()) results.resize(remaining_signals.size())
func _on_signal(p0 = null, p1 = null, p2 = null, p3 = null, p4 = null, p5 = null, p6 = null, p7 = null): func _on_signal(p0 = null, p1 = null, p2 = null, p3 = null, p4 = null, p5 = null, p6 = null, p7 = null):
var params := [p0, p1, p2, p3, p4, p5, p6, p7] var params : Array = [p0, p1, p2, p3, p4, p5, p6, p7]
assert(__SIG_SEPERATOR in params) assert(__SIG_SEPERATOR in params)
# store the parameters # store the parameters
@ -33,16 +33,16 @@ class __WaitAll:
for i in range(remaining_signals.size()): for i in range(remaining_signals.size()):
if remaining_signals[i]["object"] == params[0] && remaining_signals[i]["signal"] == params[1]: if remaining_signals[i]["object"] == params[0] && remaining_signals[i]["signal"] == params[1]:
remaining_signals.remove(i) remaining_signals.remove(i)
results[params[2]] = sig_params results[params[2] as int] = sig_params
break break
if remaining_signals.empty(): if remaining_signals.is_empty():
emit_signal("finished", results) emit_signal("finished", results)
signal finished(results) signal finished(results)
class __WaitAny: class __WaitAny:
var __SIG_SEPERATOR = Reference.new() var __SIG_SEPERATOR = RefCounted.new()
func __connect_signals(signals : Array): func __connect_signals(signals : Array):
for ele in signals: for ele in signals:
@ -72,7 +72,7 @@ class __WaitAny:
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
#! Wait for multiple signals. #! Wait for multiple signals.
@ -141,8 +141,8 @@ static func wait_for_any(objects_and_signals : Array):
obj.__connect_signals(objects_and_signals) obj.__connect_signals(objects_and_signals)
return obj return obj
static func await(res): #static func await(res):
if res is GDScriptFunctionState: # if res is GDScriptFunctionState:
return yield(res, "completed") # return yield(res, "completed")
yield(GDBUtility.get_scene_tree(), "idle_frame") # yield(GDBUtility.get_scene_tree(), "idle_frame")
return res # return res

View File

@ -9,7 +9,7 @@ class_name GDBDebug
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
static func assert_valid_num(v): static func assert_valid_num(v):

View File

@ -8,7 +8,7 @@ class_name GDBFormat
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
static func format_bytes(bytes : int) -> String: static func format_bytes(bytes : int) -> String:
@ -25,7 +25,7 @@ static func format_time(time : float) -> String:
var seconds = int(time) % 60 var seconds = int(time) % 60
return "%02d:%02d" % [minutes, seconds] return "%02d:%02d" % [minutes, seconds]
static func format_unixtime(unix_time : int, format := tr("{0year}-{0month}-{0day} {0hour}:{0minute}")) -> String: static func format_unixtime(unix_time : int, format := GDBUtility.translate("{0year}-{0month}-{0day} {0hour}:{0minute}")) -> String:
var datetime = OS.get_datetime_from_unix_time(unix_time) var datetime = OS.get_datetime_from_unix_time(unix_time)
datetime["year2"] = datetime["year"] % 100 datetime["year2"] = datetime["year"] % 100
datetime["0year"] = "%02d" % datetime["year2"] datetime["0year"] = "%02d" % datetime["year2"]
@ -38,7 +38,7 @@ static func format_unixtime(unix_time : int, format := tr("{0year}-{0month}-{0da
# return "%02d-%02d-%02d %02d:%02d" % [datetime["year"] % 100, datetime["month"], datetime["day"], datetime["hour"], datetime["minute"]] # return "%02d-%02d-%02d %02d:%02d" % [datetime["year"] % 100, datetime["month"], datetime["day"], datetime["hour"], datetime["minute"]]
return format.format(datetime) return format.format(datetime)
static func smart_format_unixtime(unix_time : int, format_date := tr("{0year}-{0month}-{0day}"), format_time := tr("{0hour}:{0minute}")) -> String: static func smart_format_unixtime(unix_time : int, format_date := GDBUtility.translate("{0year}-{0month}-{0day}"), format_time := GDBUtility.translate("{0hour}:{0minute}")) -> String:
var now = OS.get_unix_time() var now = OS.get_unix_time()
var datetime = OS.get_datetime_from_unix_time(unix_time) var datetime = OS.get_datetime_from_unix_time(unix_time)

View File

@ -19,10 +19,10 @@ class SpecialFolder:
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
static func find_all_by_name(path : String, name : String, files_only = true) -> Dictionary: static func find_all_by_name(path : String, name : String, files_only = true) -> Array:
var result = [] var result = []
__find_all_by_name(path, name, result, files_only) __find_all_by_name(path, name, result, files_only)
return result return result
@ -83,7 +83,7 @@ static func get_special_folders() -> Array:
static func replace_environment_variables(string : String) -> String: static func replace_environment_variables(string : String) -> String:
var matches := __get_envvar_regex().search_all(string) var matches := __get_envvar_regex().search_all(string)
var parts := PoolStringArray() var parts := PackedStringArray()
var pos := 0 var pos := 0
for the_match in matches: for the_match in matches:
var var_name : String = the_match.strings[-2] if !the_match.strings[-1] else the_match.strings[-1] var var_name : String = the_match.strings[-2] if !the_match.strings[-1] else the_match.strings[-1]
@ -91,7 +91,7 @@ static func replace_environment_variables(string : String) -> String:
parts.append(OS.get_environment(var_name)) parts.append(OS.get_environment(var_name))
pos = the_match.get_end() pos = the_match.get_end()
parts.append(string.substr(pos)) parts.append(string.substr(pos))
return parts.join("") return "".join(parts)
################# #################
# private stuff # # private stuff #

View File

@ -29,24 +29,24 @@ class Grid3D:
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
static func full_aabb(root : Spatial): static func full_aabb(root : Node3D):
var aabb = AABB() var aabb = AABB()
for vi in GDBUtility.find_nodes_by_type(root, VisualInstance): for vi in GDBUtility.find_nodes_by_type(root, VisualInstance3D):
var local_aabb = vi.get_aabb() var local_aabb = vi.get_aabb()
local_aabb = vi.global_transform.xform(local_aabb) local_aabb = vi.global_transform.xform(local_aabb)
aabb = aabb.merge(local_aabb) aabb = aabb.merge(local_aabb)
return aabb return aabb
static func gen_aabb(points : Array, point_transform = Transform()) -> AABB: static func gen_aabb(points : Array, point_transform = Transform3D()) -> AABB:
var aabb = AABB() var aabb = AABB()
for point in points: for point in points:
aabb = aabb.expand(point_transform.xform(point)) aabb = aabb.expand(point_transform * point)
return aabb return aabb
static func collsion_aabb(collision_object : CollisionObject) -> AABB: static func collsion_aabb(collision_object : CollisionObject3D) -> AABB:
var aabb := AABB() var aabb := AABB()
for owner_id in collision_object.get_shape_owners(): for owner_id in collision_object.get_shape_owners():
var trans = collision_object.shape_owner_get_transform(owner_id) var trans = collision_object.shape_owner_get_transform(owner_id)
@ -54,56 +54,56 @@ static func collsion_aabb(collision_object : CollisionObject) -> AABB:
var shape = collision_object.shape_owner_get_shape(owner_id, shape_id) var shape = collision_object.shape_owner_get_shape(owner_id, shape_id)
var new_aabb = shape_aabb(shape) var new_aabb = shape_aabb(shape)
if new_aabb.size: if new_aabb.size:
aabb = aabb.merge(trans.xform(new_aabb)) aabb = aabb.merge(trans * new_aabb)
return aabb return aabb
static func shape_aabb(shape : Shape) -> AABB: static func shape_aabb(shape : Shape3D) -> AABB:
if shape is BoxShape: if shape is BoxShape3D:
return AABB(-shape.extents, 2.0 * shape.extents) return AABB(-shape.extents, 2.0 * shape.extents)
elif shape is CapsuleShape: elif shape is CapsuleShape3D:
return AABB(Vector3(-shape.radius, -shape.radius - 0.5 * shape.height, -shape.radius), \ return AABB(Vector3(-shape.radius, -shape.radius - 0.5 * shape.height, -shape.radius), \
Vector3(2.0 * shape.radius, 2.0 * shape.radius + shape.height, 2.0 * shape.radius)) Vector3(2.0 * shape.radius, 2.0 * shape.radius + shape.height, 2.0 * shape.radius))
elif shape is CylinderShape: elif shape is CylinderShape3D:
return AABB(Vector3(-shape.radius, -0.5 * shape.height, -shape.radius), \ return AABB(Vector3(-shape.radius, -0.5 * shape.height, -shape.radius), \
Vector3(2.0 * shape.radius, shape.height, 2.0 * shape.radius)) Vector3(2.0 * shape.radius, shape.height, 2.0 * shape.radius))
elif shape is PlaneShape: # elif shape is PlaneShape3D:
return AABB() # return AABB()
elif shape is SphereShape: elif shape is SphereShape3D:
return AABB(-Vector3(shape.radius, shape.radius, shape.radius), 2.0 * Vector3(shape.radius, shape.radius, shape.radius)) return AABB(-Vector3(shape.radius, shape.radius, shape.radius), 2.0 * Vector3(shape.radius, shape.radius, shape.radius))
else: else:
# TODO: polygon shapes # TODO: polygon shapes
return AABB() return AABB()
static func orphan_global_transform(node : Node): static func orphan_global_transform(node : Node):
var transform : Transform var transform : Transform3D
if node is Spatial: if node is Node3D:
transform = node.transform transform = node.transform
var parent = node.get_parent() var parent = node.get_parent()
if parent != null: if parent != null:
transform = orphan_global_transform(parent) * transform transform = orphan_global_transform(parent) * transform
return transform return transform
static func voxelize_surf(mesh : ArrayMesh, surf : int, particle_size = -1.0) -> PoolVector3Array: static func voxelize_surf(mesh : ArrayMesh, surf : int, particle_size = -1.0) -> PackedVector3Array:
var arrays = mesh.surface_get_arrays(surf) var arrays = mesh.surface_get_arrays(surf)
var points = arrays[Mesh.ARRAY_VERTEX] var points = arrays[Mesh.ARRAY_VERTEX]
return PoolVector3Array(points) return PackedVector3Array(points)
static func voxelize(mesh : ArrayMesh, particle_size = -1.0) -> PoolVector3Array: static func voxelize(mesh : ArrayMesh, particle_size = -1.0) -> PackedVector3Array:
var points = PoolVector3Array() var points = PackedVector3Array()
for surf in range(mesh.get_surface_count()): for surf in range(mesh.get_surface_count()):
points.append_array(voxelize_surf(mesh, surf, particle_size)) points.append_array(voxelize_surf(mesh, surf, particle_size))
return points return points
static func transform_to(node : Node, root : Node): static func transform_to(node : Node, root : Node):
var transform = Transform() var transform = Transform3D()
var node_ = node var node_ = node
while node_ != root && node_ != null: while node_ != root && node_ != null:
if node_ is Spatial: if node_ is Node3D:
transform = transform * node_.transform transform = transform * node_.transform
node_ = node_.get_parent() node_ = node_.get_parent()
return transform return transform
static func mesh_to_grid(mesh : ArrayMesh, grid_size : float, point_transform = Transform()): static func mesh_to_grid(mesh : ArrayMesh, grid_size : float, point_transform = Transform3D()):
var aabb = AABB() var aabb = AABB()
for i in range(mesh.get_surface_count()): for i in range(mesh.get_surface_count()):
var points = mesh.surface_get_arrays(i)[Mesh.ARRAY_VERTEX] var points = mesh.surface_get_arrays(i)[Mesh.ARRAY_VERTEX]
@ -148,17 +148,17 @@ static func angle_diff(angle0 : float, angle1 : float) -> float:
################# #################
# private stuff # # private stuff #
################# #################
static func __insert_tri(a : Vector3, b : Vector3, c : Vector3, grid_origin : Vector3, grid_size : float, grid : Grid3D, point_transform : Transform): static func __insert_tri(a : Vector3, b : Vector3, c : Vector3, grid_origin : Vector3, grid_size : float, grid : Grid3D, point_transform : Transform3D):
var ray_dir = Vector3(0, 0, 1) var ray_dir = Vector3(0, 0, 1)
for x in range(grid.size.x): for x in range(grid.size.x):
for y in range(grid.size.y): for y in range(grid.size.y):
var ray_origin = grid_origin + grid_size * Vector3(x, y, 0) var ray_origin = grid_origin + grid_size * Vector3(x, y, 0)
var inters = Geometry.ray_intersects_triangle(ray_origin, ray_dir, point_transform.xform(a), point_transform.xform(b), point_transform.xform(c)) var inters = Geometry3D.ray_intersects_triangle(ray_origin, ray_dir, point_transform * a, point_transform * b, point_transform * c)
if inters != null: if inters != null:
var z = floor(0.99 * (inters.z - grid_origin.z) / grid_size) var z = floor(0.99 * (inters.z - grid_origin.z) / grid_size)
grid.set_at(x, y, z, grid.get_at(x, y, z) + 1) grid.set_at(x, y, z, grid.get_at(x, y, z) + 1)
static func __insert_surf(mesh : ArrayMesh, surf : int, grid_origin : Vector3, grid_size : float, grid : Grid3D, point_transform : Transform): static func __insert_surf(mesh : ArrayMesh, surf : int, grid_origin : Vector3, grid_size : float, grid : Grid3D, point_transform : Transform3D):
var arrays = mesh.surface_get_arrays(surf) var arrays = mesh.surface_get_arrays(surf)
if arrays.size() >= Mesh.ARRAY_INDEX - 1 && arrays[Mesh.ARRAY_INDEX].size() > 0: if arrays.size() >= Mesh.ARRAY_INDEX - 1 && arrays[Mesh.ARRAY_INDEX].size() > 0:
# index mode # index mode

View File

@ -29,9 +29,11 @@ class Graph:
func append_edge(idx0, idx1, weight := 1.0): func append_edge(idx0, idx1, weight := 1.0):
for edge in edges: for edge in edges:
if (edge.idx0 == idx0 && edge.idx1 == idx1) || \ if (edge.idx0 == idx0 && edge.idx1 == idx1) || \
(edge.idx0 == idx1 && edge.idx1 == idx0): (edge.idx0 == idx1 && edge.idx1 == idx0):
return return
edges.append(Edge.new(idx0, idx1, weight)) # TODO: why doesn't this work? bug?
assert(0)
# edges.append(Edge.new(idx0, idx1, weight))
func remove_vertex(vertex): func remove_vertex(vertex):
var idx = vertices.find(vertex) var idx = vertices.find(vertex)
@ -57,7 +59,7 @@ class Graph:
var to_remove = [] var to_remove = []
for edge in edges: for edge in edges:
if (edge.idx0 == idx0 && edge.idx1 == idx1) || \ if (edge.idx0 == idx0 && edge.idx1 == idx1) || \
(edge.idx0 == idx1 && edge.idx1 == idx0): (edge.idx0 == idx1 && edge.idx1 == idx0):
to_remove.append(edge) to_remove.append(edge)
for edge in to_remove: for edge in to_remove:
edges.erase(edge) edges.erase(edge)
@ -72,7 +74,7 @@ class Graph:
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
# generates a delaunay triangulation for the given point list # generates a delaunay triangulation for the given point list
@ -163,7 +165,7 @@ func find_path(graph : Graph, start_idx : int, end_idx : int) -> Dictionary:
queue.append(idx) queue.append(idx)
dist[start_idx] = 0.0 dist[start_idx] = 0.0
while !queue.empty(): while !queue.is_empty():
var shortest_dist = INF var shortest_dist = INF
var shortest_idx : int var shortest_idx : int
for idx in queue: for idx in queue:
@ -207,8 +209,8 @@ func find_path(graph : Graph, start_idx : int, end_idx : int) -> Dictionary:
# draws a graph onto a control # draws a graph onto a control
func dump_graph_2d(graph : Graph, control : Control) -> void: func dump_graph_2d(graph : Graph, control : Control) -> void:
var normalized_graph = graph.duplicate() var normalized_graph = graph.duplicate()
var min_xy = Vector2.INF var min_xy = Vector2(INF, INF)
var max_xy = -Vector2.INF var max_xy = -Vector2(INF, INF)
# normalize graph # normalize graph
for vertex in normalized_graph.vertices: for vertex in normalized_graph.vertices:
@ -235,18 +237,18 @@ func dump_graph_2d(graph : Graph, control : Control) -> void:
var coord0 = __img_vertex_coord(v0, img_size) var coord0 = __img_vertex_coord(v0, img_size)
var coord1 = __img_vertex_coord(v1, img_size) var coord1 = __img_vertex_coord(v1, img_size)
control.draw_line(coord0, coord1, Color.yellow, 2.0, true) control.draw_line(coord0, coord1, Color.YELLOW, 2.0)
for vertex in normalized_graph.vertices: for vertex in normalized_graph.vertices:
var coord = __img_vertex_coord(vertex, img_size) var coord = __img_vertex_coord(vertex, img_size)
control.draw_circle(coord, 5.0, Color.red) control.draw_circle(coord, 5.0, Color.RED)
################# #################
# private stuff # # private stuff #
################# #################
func __gen_super_triangle(graph : Graph, point_list : Array) -> void: func __gen_super_triangle(graph : Graph, point_list : Array) -> void:
var min_xy = Vector2.INF var min_xy = Vector2(INF, INF)
var max_xy = -Vector2.INF var max_xy = -Vector2(INF, INF)
for point in point_list: for point in point_list:
if point.x < min_xy.x: if point.x < min_xy.x:
@ -274,7 +276,7 @@ func __edge_shared(p0 : int, p1 : int, tris : Array) -> bool:
var edge_count = 0 var edge_count = 0
for tri in tris: for tri in tris:
if (p0 == tri.x || p0 == tri.y || p0 == tri.z) && \ if (p0 == tri.x || p0 == tri.y || p0 == tri.z) && \
(p1 == tri.x || p1 == tri.y || p1 == tri.z): (p1 == tri.x || p1 == tri.y || p1 == tri.z):
edge_count += 1 edge_count += 1
return edge_count > 1 return edge_count > 1

View File

@ -8,7 +8,7 @@ class_name GDBMath
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
static func angle(vec0 : Vector3, vec1 : Vector3, axis : Vector3) -> float: static func angle(vec0 : Vector3, vec1 : Vector3, axis : Vector3) -> float:
@ -30,7 +30,7 @@ static func find_perp(a : Vector3, b : Vector3, d : Vector3) -> Vector3:
var t = -t1 / (t0 - t1) var t = -t1 / (t0 - t1)
# assert(t >= 0 && t <= 1) # assert(t >= 0 && t <= 1)
var n = b.linear_interpolate(a, t).normalized() var n = b.lerp(a, t).normalized()
var an = n.angle_to(d) var an = n.angle_to(d)
assert(abs(n.dot(d)) < 0.01) assert(abs(n.dot(d)) < 0.01)
assert(abs(an - 0.5 * PI) < 0.01) assert(abs(an - 0.5 * PI) < 0.01)

View File

@ -19,7 +19,7 @@ class __State:
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
static func has_value(name : String) -> bool: static func has_value(name : String) -> bool:
@ -29,7 +29,7 @@ static func get_value(name : String, def = null, type = TYPE_NIL):
if type == TYPE_NIL && def != null: if type == TYPE_NIL && def != null:
type = typeof(def) type = typeof(def)
var val = __get_state().values.get(name, def) var val : Variant = __get_state().values.get(name, def)
if type is Object: if type is Object:
if !val is type: if !val is type:
return def return def
@ -40,9 +40,15 @@ static func get_value(name : String, def = null, type = TYPE_NIL):
TYPE_STRING: TYPE_STRING:
val = str(val) val = str(val)
TYPE_INT: TYPE_INT:
val = int(val) if val is String:
TYPE_REAL: val = val.to_int()
val = float(val) else:
val = int(val)
TYPE_FLOAT:
if val is String:
val = val.to_float()
else:
val = float(val)
TYPE_BOOL: TYPE_BOOL:
val = bool(val) val = bool(val)
_: _:
@ -58,7 +64,8 @@ static func set_value(name : String, value) -> void:
# save next frame (in case multiple values are changed) # save next frame (in case multiple values are changed)
__get_state().settings_changed = true __get_state().settings_changed = true
yield(GDBUtility.get_scene_tree(), "idle_frame") # await GDBUtility.get_scene_tree().process_frame
# TODO: cannot make this a coroutine (bug?!)
if __get_state().settings_changed: if __get_state().settings_changed:
store_to_file() store_to_file()
__get_state().settings_changed = false __get_state().settings_changed = false
@ -95,7 +102,13 @@ static func load_from_file() -> void:
return # nothing to load return # nothing to load
in_file.open(__get_state().settings_file_name, File.READ) in_file.open(__get_state().settings_file_name, File.READ)
__load_data(parse_json(in_file.get_as_text()))
var json := JSON.new()
if json.parse(in_file.get_as_text()) != OK:
printerr("Error parsing settings file, invalid json!")
printerr("at line {}: {}".format([json.get_error_line(), json.get_error_message()]))
return
__load_data(json.get_data())
static func store_to_file() -> void: static func store_to_file() -> void:
var out_file = File.new() var out_file = File.new()
@ -109,17 +122,15 @@ static func set_disable_default_settings(disable : bool) -> void:
static func is_disable_default_settings() -> bool: static func is_disable_default_settings() -> bool:
return __get_state().disable_default_settings return __get_state().disable_default_settings
static func connect_static(sig_name : String, receiver : Object, method : String, binds := []) -> int: static func setting_changed() -> Signal:
return __get_state().connect(sig_name, receiver, method, binds) return __get_state().setting_changed
static func disconnect_static(sig_name : String, receiver : Object, method : String) -> void:
__get_state().disconnect(sig_name, receiver, method)
################# #################
# private stuff # # private stuff #
################# #################
static func __save_data(): static func __save_data():
return to_json(__get_state().values) var json := JSON.new()
return json.stringify(__get_state().values)
static func __load_data(data : Dictionary): static func __load_data(data : Dictionary):
for name in data: for name in data:

View File

@ -8,7 +8,7 @@ class_name GDBUtility
################ ################
# public stuff # # public stuff #
################ ################
func _init() -> void: func _init():
assert(0, "This class should not be instantiated.") assert(0, "This class should not be instantiated.")
static func find_node_filter(root : Node, object : Object, method : String, bfs := false) -> Node: static func find_node_filter(root : Node, object : Object, method : String, bfs := false) -> Node:
@ -118,14 +118,17 @@ static func find_parent_with_type(root : Node, tp) -> Node:
return find_parent_with_type(parent, tp) return find_parent_with_type(parent, tp)
static func find_treeitem_with_metadata(root : TreeItem, metadata, column := 0) -> TreeItem: static func find_treeitem_with_metadata(root : TreeItem, metadata, column := 0) -> TreeItem:
while root: assert(0)
if root.get_metadata(column) == metadata: # TODO: rewrite
return root
var in_children := find_treeitem_with_metadata(root.get_children(), metadata, column)
if in_children:
return in_children
root = root.get_next()
return null return null
# while root:
# if root.get_metadata(column) == metadata:
# return root
# var in_children := find_treeitem_with_metadata(root.get_children(), metadata, column)
# if in_children:
# return in_children
# root = root.get_next()
# return null
static func hide_properties(properties : Array, names_to_hide : Array) -> void: static func hide_properties(properties : Array, names_to_hide : Array) -> void:
for i in range(properties.size() - 1, -1, -1): for i in range(properties.size() - 1, -1, -1):
@ -140,7 +143,7 @@ static func type_name(type : int) -> String:
return "bool" return "bool"
TYPE_INT: TYPE_INT:
return "int" return "int"
TYPE_REAL: TYPE_FLOAT:
return "float" return "float"
TYPE_STRING: TYPE_STRING:
return "String" return "String"
@ -154,14 +157,14 @@ static func type_name(type : int) -> String:
return "Transform2D" return "Transform2D"
TYPE_PLANE: TYPE_PLANE:
return "Plane" return "Plane"
TYPE_QUAT: TYPE_QUATERNION:
return "Quat" return "Quat"
TYPE_AABB: TYPE_AABB:
return "AABB" return "AABB"
TYPE_BASIS: TYPE_BASIS:
return "Basis" return "Basis"
TYPE_TRANSFORM: TYPE_TRANSFORM3D:
return "Transform" return "Transform3D"
TYPE_COLOR: TYPE_COLOR:
return "Color" return "Color"
TYPE_NODE_PATH: TYPE_NODE_PATH:
@ -175,11 +178,15 @@ static func type_name(type : int) -> String:
TYPE_ARRAY: TYPE_ARRAY:
return "Array" return "Array"
TYPE_RAW_ARRAY: TYPE_RAW_ARRAY:
return "PoolByteArray" return "PackedByteArray"
TYPE_INT_ARRAY: TYPE_INT32_ARRAY:
return "PoolIntArray" return "PackedInt32Array"
TYPE_REAL_ARRAY: TYPE_INT64_ARRAY:
return "PoolRealArray" return "PackedInt64Array"
TYPE_FLOAT32_ARRAY:
return "PackedFloat32Array"
TYPE_FLOAT64_ARRAY:
return "PackedFloat64Array"
TYPE_STRING_ARRAY: TYPE_STRING_ARRAY:
return "PoolStringArray" return "PoolStringArray"
TYPE_VECTOR2_ARRAY: TYPE_VECTOR2_ARRAY:
@ -201,7 +208,7 @@ static func format_type(type : Dictionary, none_name := "void") -> String:
return type_name(tp) return type_name(tp)
static func format_method_signature(method : Dictionary, format := "{return} {name}({args})") -> String: static func format_method_signature(method : Dictionary, format := "{return} {name}({args})") -> String:
var args := PoolStringArray() var args := PackedStringArray()
var rettype := "void" var rettype := "void"
if method.has("return"): if method.has("return"):
rettype = format_type(method["return"]) rettype = format_type(method["return"])
@ -218,7 +225,7 @@ static func format_method_signature(method : Dictionary, format := "{return} {na
return format.format({ return format.format({
"return": rettype, "return": rettype,
"name": method["name"], "name": method["name"],
"args": args.join(", ") "args": ", ".join(args)
}) })
static func format_signal_signature(sig : Dictionary) -> String: static func format_signal_signature(sig : Dictionary) -> String:
@ -228,8 +235,8 @@ static func get_type_property_list(type : Dictionary) -> Array:
match type["type"]: match type["type"]:
TYPE_VECTOR2: TYPE_VECTOR2:
return [ return [
{"name": "x", "type": TYPE_REAL}, {"name": "x", "type": TYPE_FLOAT},
{"name": "y", "type": TYPE_REAL} {"name": "y", "type": TYPE_FLOAT}
] ]
TYPE_RECT2: TYPE_RECT2:
return [ return [
@ -239,9 +246,9 @@ static func get_type_property_list(type : Dictionary) -> Array:
] ]
TYPE_VECTOR3: TYPE_VECTOR3:
return [ return [
{"name": "x", "type": TYPE_REAL}, {"name": "x", "type": TYPE_FLOAT},
{"name": "y", "type": TYPE_REAL}, {"name": "y", "type": TYPE_FLOAT},
{"name": "z", "type": TYPE_REAL} {"name": "z", "type": TYPE_FLOAT}
] ]
TYPE_TRANSFORM2D: TYPE_TRANSFORM2D:
return [ return [
@ -252,17 +259,17 @@ static func get_type_property_list(type : Dictionary) -> Array:
TYPE_PLANE: TYPE_PLANE:
return [ return [
{"name": "normal", "type": TYPE_VECTOR3}, {"name": "normal", "type": TYPE_VECTOR3},
{"name": "x", "type": TYPE_REAL}, {"name": "x", "type": TYPE_FLOAT},
{"name": "y", "type": TYPE_REAL}, {"name": "y", "type": TYPE_FLOAT},
{"name": "z", "type": TYPE_REAL}, {"name": "z", "type": TYPE_FLOAT},
{"name": "d", "type": TYPE_REAL} {"name": "d", "type": TYPE_FLOAT}
] ]
TYPE_QUAT: TYPE_QUATERNION:
return [ return [
{"name": "x", "type": TYPE_REAL}, {"name": "x", "type": TYPE_FLOAT},
{"name": "y", "type": TYPE_REAL}, {"name": "y", "type": TYPE_FLOAT},
{"name": "z", "type": TYPE_REAL}, {"name": "z", "type": TYPE_FLOAT},
{"name": "w", "type": TYPE_REAL} {"name": "w", "type": TYPE_FLOAT}
] ]
TYPE_AABB: TYPE_AABB:
return [ return [
@ -276,20 +283,20 @@ static func get_type_property_list(type : Dictionary) -> Array:
{"name": "y", "type": TYPE_VECTOR3}, {"name": "y", "type": TYPE_VECTOR3},
{"name": "z", "type": TYPE_VECTOR3} {"name": "z", "type": TYPE_VECTOR3}
] ]
TYPE_TRANSFORM: TYPE_TRANSFORM3D:
return [ return [
{"name": "basis", "type": TYPE_BASIS}, {"name": "basis", "type": TYPE_BASIS},
{"name": "origin", "type": TYPE_VECTOR3} {"name": "origin", "type": TYPE_VECTOR3}
] ]
TYPE_COLOR: TYPE_COLOR:
return [ return [
{"name": "r", "type": TYPE_REAL}, {"name": "r", "type": TYPE_FLOAT},
{"name": "g", "type": TYPE_REAL}, {"name": "g", "type": TYPE_FLOAT},
{"name": "b", "type": TYPE_REAL}, {"name": "b", "type": TYPE_FLOAT},
{"name": "a", "type": TYPE_REAL}, {"name": "a", "type": TYPE_FLOAT},
{"name": "h", "type": TYPE_REAL}, {"name": "h", "type": TYPE_FLOAT},
{"name": "s", "type": TYPE_REAL}, {"name": "s", "type": TYPE_FLOAT},
{"name": "v", "type": TYPE_REAL}, {"name": "v", "type": TYPE_FLOAT},
{"name": "r8", "type": TYPE_INT}, {"name": "r8", "type": TYPE_INT},
{"name": "g8", "type": TYPE_INT}, {"name": "g8", "type": TYPE_INT},
{"name": "b8", "type": TYPE_INT}, {"name": "b8", "type": TYPE_INT},
@ -304,7 +311,7 @@ static func get_property_type(obj : Object, property : String) -> int:
return typeof(obj.get(property)) # TODO return typeof(obj.get(property)) # TODO
static func get_method_arg_types(obj : Object, method : String) -> Array: static func get_method_arg_types(obj : Object, method : String) -> Array:
var methods := obj.get_method_list() var methods : Array = obj.get_method_list()
var types := [] var types := []
for ele in methods: for ele in methods:
if ele["name"] == method: if ele["name"] == method:
@ -319,7 +326,7 @@ static func get_scene_tree() -> SceneTree:
static func wait_frames(nframes : int) -> void: static func wait_frames(nframes : int) -> void:
var tree := get_scene_tree() var tree := get_scene_tree()
for i in range(max(1, nframes)): # yield at least once so this always returns a GDScriptFunctionState for i in range(max(1, nframes)): # yield at least once so this always returns a GDScriptFunctionState
yield(tree, "idle_frame") await tree.process_frame
static func disconnect_all(sender : Object, receiver : Object, signal_name := "") -> void: static func disconnect_all(sender : Object, receiver : Object, signal_name := "") -> void:
if signal_name == "": if signal_name == "":
@ -348,14 +355,15 @@ static func control_is_in_front_of(front : Control, back : Control) -> bool:
var front_popup : bool = find_parent_with_type(front, Popup) != null var front_popup : bool = find_parent_with_type(front, Popup) != null
var back_popup : bool = find_parent_with_type(back, Popup) != null var back_popup : bool = find_parent_with_type(back, Popup) != null
if front_popup && !back_popup: # TODO: this part maybe needs to be reimplemented
return true # if front_popup && !back_popup:
elif !front_popup && back_popup: # return true
return false # elif !front_popup && back_popup:
elif front_popup && back_popup: # return false
return popup_is_in_front_of(front, back) # elif front_popup && back_popup:
else: # return popup_is_in_front_of(front as Popup, back)
return back.is_greater_than(front) # else:
return back.is_greater_than(front)
static func popup_is_in_front_of(front : Popup, back : Popup) -> bool: static func popup_is_in_front_of(front : Popup, back : Popup) -> bool:
return back.is_greater_than(front) # no idea?! return back.is_greater_than(front) # no idea?!

View File

@ -1,4 +1,4 @@
extends Reference extends RefCounted
class_name GDB_Entity class_name GDB_Entity
@ -8,58 +8,56 @@ var _properties := [].duplicate()
var _property_ids := [].duplicate() var _property_ids := [].duplicate()
class _CommonWrapperProperty extends GDB_Property: class _CommonWrapperProperty extends GDB_Property:
var object : WeakRef func _init(val, sig : Signal = Signal(), flags := 0):
func _init(object_ : Object, val, sig_name := "", flags := 0) -> void: super.set_type(typeof(val))
self.object = weakref(object_) super.set_value(val)
.set_type(typeof(val)) super.set_flags(flags)
.set_value(val)
.set_flags(flags)
if sig_name != "": if !sig.is_null():
object_.connect(sig_name, self, "_on_object_value_changed") sig.connect(self._on_object_value_changed)
func _on_object_value_changed(p0 = null, p1 = null, p2 = null, p3 = null) -> void: func _on_object_value_changed(p0 = null, p1 = null, p2 = null, p3 = null) -> void:
var obj : Object = self.object.get_ref() _value = self.get_value()
if obj: # shouldn't actually be null, who called the handler then? value_changed.emit()
_value = obj.get(self.member)
emit_signal("value_changed")
class _WrapperProperty extends _CommonWrapperProperty: class _WrapperProperty extends _CommonWrapperProperty:
var object : WeakRef
var member : String var member : String
func _init(object_ : Object, member_ : String, sig_name : String, flags : int) \ func _init(object_ : Object, member_ : String, sig : Signal, flags : int):
.(object_, object_.get(member), sig_name, flags) -> void: super(object_.get(member), sig, flags)
self.object = object_
self.member = member_ self.member = member_
.set_name(member_.capitalize()) super.set_name(member_.capitalize())
func get_value(): func get_value():
var obj : Object = self.object.get_ref() var obj : Object = self.object.get_ref()
if obj: if obj:
return obj.get(self.member) return obj.get(self.member)
return .get_value() return super.get_value()
func set_value(value) -> void: func set_value(value) -> void:
var obj : Object = self.object.get_ref() var obj : Object = self.object.get_ref()
if obj: if obj:
obj.set(self.member, value) obj.set(self.member, value)
.set_value(obj.get(self.member)) super.set_value(obj.get(self.member))
else: else:
.set_value(value) super.set_value(value)
class _ArrayWrapperProperty extends _WrapperProperty: class _ArrayWrapperProperty extends _WrapperProperty:
func _init(object_ : Object, member_ : String, sig_name_added : String, sig_name_removed : String, flags : int) \ func _init(object_ : Object, member_ : String, sig_added : Signal = Signal(), sig_removed : Signal = Signal(), flags := 0):
.(object_, member_, "", flags) -> void: super(object_, member_, Signal(), flags)
if sig_name_added != "": if !sig_added.is_null():
object_.connect(sig_name_added, self, "_on_object_value_added") sig_added.connect(self._on_object_value_added)
if sig_name_removed != "": if !sig_removed.is_null():
object_.connect(sig_name_added, self, "_on_object_value_removed") sig_removed.connect(self._on_object_value_removed)
func _on_object_value_added(value, p0 = null, p1 = null, p2 = null, p3 = null) -> void: func _on_object_value_added(value, p0 = null, p1 = null, p2 = null, p3 = null) -> void:
var obj : Object = self.object.get_ref() var obj : Object = self.object.get_ref()
if obj: if obj:
_value = obj.get(self.member) _value = obj.get(self.member)
emit_signal("value_changed") value_changed.emit()
emit_signal("value_added", value) value_added.emit(value)
func _on_object_value_removed(value, p0 = null, p1 = null, p2 = null, p3 = null) -> void: func _on_object_value_removed(value, p0 = null, p1 = null, p2 = null, p3 = null) -> void:
var obj : Object = self.object.get_ref() var obj : Object = self.object.get_ref()
@ -69,29 +67,29 @@ class _ArrayWrapperProperty extends _WrapperProperty:
emit_signal("value_removed", value) emit_signal("value_removed", value)
class _GetSetWrapperProperty extends _CommonWrapperProperty: class _GetSetWrapperProperty extends _CommonWrapperProperty:
var getter := "" var getter := Callable()
var setter := "" var setter := Callable()
func _init(object_ : Object, getter_ : String, setter_ := "", sig_name := "", flags := 0) \ func _init(getter_ : Callable, setter_ := Callable(), sig : Signal = Signal(), flags := 0):
.(object_, object.call(getter_), sig_name, flags) -> void: super(getter_.call(), sig, flags)
self.getter = getter_ self.getter = getter_
self.setter = setter_ self.setter = setter_
func get_value(): func get_value():
var obj : Object = self.object.get_ref() var obj : Object = self.object.get_ref()
if obj: if obj:
return obj.call(self.getter) return self.getter.call()
return .get_value() return super.get_value()
func set_value(value) -> void: func set_value(value) -> void:
if !self.setter: if self.setter.is_null():
return return
var obj : Object = self.object.get_ref() var obj : Object = self.object.get_ref()
if obj: if obj:
obj.call(self.setter, value) self.setter.call(value)
.set_value(obj.call(self.getter)) super.set_value(self.getter.call())
else: else:
.set_value(value) super.set_value(value)
################ ################
# public stuff # # public stuff #
@ -199,14 +197,14 @@ static func is_valid_entity(object : Object) -> bool:
return object != null \ return object != null \
&& object.has_method("get_properties") && object.has_method("get_properties")
static func make_property(object : Object, member : String, sig_name := "", flags := 0) -> GDB_Property: static func make_property(object : Object, member : String, sig := Signal(), flags := 0) -> GDB_Property:
return _WrapperProperty.new(object, member, sig_name, flags) return _WrapperProperty.new(object, member, sig, flags)
static func make_getset_property(object : Object, getter : String, setter := "", sig_name := "", flags := 0) -> GDB_Property: static func make_getset_property(getter : Callable, setter := Callable(), sig := Signal(), flags := 0) -> GDB_Property:
return _GetSetWrapperProperty.new(object, getter, setter, sig_name, flags) return _GetSetWrapperProperty.new(getter, setter, sig, flags)
static func make_array_property(object : Object, member : String, sig_name_added := "", sig_name_removed := "", array_type := TYPE_NIL, flags := 0) -> GDB_Property: static func make_array_property(object : Object, member : String, sig_added := Signal(), sig_removed := Signal(), array_type := TYPE_NIL, flags := 0) -> GDB_Property:
var prop := _ArrayWrapperProperty.new(object, member, sig_name_added, sig_name_removed, flags) var prop := _ArrayWrapperProperty.new(object, member, sig_added, sig_removed, flags)
prop.set_content_type(array_type) prop.set_content_type(array_type)
return prop return prop
@ -217,21 +215,21 @@ static func make_entity_title_property(entity : Object) -> Object:
if property: if property:
return property return property
if entity.get("title") is String: if entity.get("title") is String:
var sig_name := "" var sig := Signal()
if entity.has_signal("title_changed"): if entity.has_signal("title_changed"):
sig_name = "title_changed" sig = entity.title_changed
return make_property(entity, "title", sig_name) return make_property(entity, "title", sig)
if entity.has_method("get_title"): if entity.has_method("get_title"):
var setter := "" var setter := Callable()
var sig_name := "" var sig := Signal()
var flags := 0 var flags := 0
if entity.has_method("set_title"): if entity.has_method("set_title"):
setter = "set_title" setter = entity.set_title
else: else:
flags |= GDB_Property.FLAG_READONLY flags |= GDB_Property.FLAG_READONLY
if entity.has_signal("title_changed"): if entity.has_signal("title_changed"):
sig_name = "title_changed" sig = entity.title_changed
return make_getset_property(entity, "get_title", setter, sig_name, flags) return make_getset_property(entity.get_title, setter, sig, flags)
return null return null

View File

@ -1,4 +1,4 @@
extends Reference extends RefCounted
class_name GDB_Property class_name GDB_Property
@ -26,7 +26,7 @@ func get_name() -> String:
func set_name(name : String) -> void: func set_name(name : String) -> void:
if _name != name: if _name != name:
_name = name _name = name
emit_signal("name_changed") name_changed.emit()
func get_icon() -> Texture: func get_icon() -> Texture:
return _icon return _icon
@ -34,7 +34,7 @@ func get_icon() -> Texture:
func set_icon(icon : Texture) -> void: func set_icon(icon : Texture) -> void:
if _icon != icon: if _icon != icon:
_icon = icon _icon = icon
emit_signal("icon_changed") icon_changed.emit()
func get_value(): func get_value():
return _value return _value
@ -42,7 +42,7 @@ func get_value():
func set_value(value) -> void: func set_value(value) -> void:
if value != _value: if value != _value:
_value = value _value = value
emit_signal("value_changed") value_changed.emit()
func get_type() -> int: func get_type() -> int:
return _type return _type
@ -50,7 +50,7 @@ func get_type() -> int:
func set_type(type : int) -> void: func set_type(type : int) -> void:
if type != _type: if type != _type:
_type = type _type = type
emit_signal("type_changed") type_changed.emit()
func get_content_type() -> int: func get_content_type() -> int:
return _content_type return _content_type
@ -58,7 +58,7 @@ func get_content_type() -> int:
func set_content_type(type : int) -> void: func set_content_type(type : int) -> void:
if type != _content_type: if type != _content_type:
_content_type = type _content_type = type
emit_signal("type_changed") type_changed.emit()
func get_flags() -> int: func get_flags() -> int:
return _flags return _flags
@ -66,7 +66,7 @@ func get_flags() -> int:
func set_flags(flags : int) -> void: func set_flags(flags : int) -> void:
if flags != _flags: if flags != _flags:
_flags = flags _flags = flags
emit_signal("flags_changed") flags_changed.emit()
################ ################
# static stuff # # static stuff #
@ -97,7 +97,7 @@ static func is_prop_value_valid(property : Object, value) -> bool:
return value is bool return value is bool
TYPE_INT: TYPE_INT:
return value is int return value is int
TYPE_REAL: TYPE_FLOAT:
return value is float return value is float
TYPE_STRING: TYPE_STRING:
return value is String return value is String

View File

@ -2,7 +2,8 @@ extends Node
class_name GDB_DataAdapter class_name GDB_DataAdapter
var data setget _set_data var data : Variant:
set = _set_data
########### ###########
# setters # # setters #

View File

@ -1,7 +1,7 @@
# wrapps not reference-counted object in a reference # wrapps not reference-counted object in a reference
# useful for example if you want to store a type that extends Node outside of the tree # useful for example if you want to store a type that extends Node outside of the tree
extends Reference extends RefCounted
class_name GDB_ReferenceWrapper class_name GDB_ReferenceWrapper