diff --git a/addons/block_code/block_code_plugin.gd b/addons/block_code/block_code_plugin.gd index ff960f1c..759a9881 100644 --- a/addons/block_code/block_code_plugin.gd +++ b/addons/block_code/block_code_plugin.gd @@ -3,7 +3,6 @@ extends EditorPlugin const MainPanelScene := preload("res://addons/block_code/ui/main_panel.tscn") const MainPanel = preload("res://addons/block_code/ui/main_panel.gd") -const Types = preload("res://addons/block_code/types/types.gd") const TxUtils := preload("res://addons/block_code/translation/utils.gd") const ScriptWindow := preload("res://addons/block_code/ui/script_window/script_window.tscn") @@ -39,8 +38,6 @@ func _init(): func _enter_tree(): - Types.init_cast_graph() - editor_inspector = EditorInterface.get_inspector() main_panel = MainPanelScene.instantiate() diff --git a/addons/block_code/drag_manager/drag.gd b/addons/block_code/drag_manager/drag.gd index 102b38c0..ce0a03d4 100644 --- a/addons/block_code/drag_manager/drag.gd +++ b/addons/block_code/drag_manager/drag.gd @@ -128,8 +128,8 @@ func _snaps_to(node: Node) -> bool: if _block.definition.type != _snap_point.block_type: return false - if _block.definition.type == Types.BlockType.VALUE and not Types.can_cast(_block.definition.variant_type, _snap_point.variant_type): - # We only snap Value blocks to snaps that can cast to same variant: + if _block.definition.type == Types.BlockType.VALUE and not Types.has_relationship(_block.definition.variant_type, _snap_point.variant_type): + # We only snap Value blocks to snaps if their types have a relationship: return false # Check if any parent node is this node diff --git a/addons/block_code/types/types.gd b/addons/block_code/types/types.gd index e1768560..12a0875a 100644 --- a/addons/block_code/types/types.gd +++ b/addons/block_code/types/types.gd @@ -36,147 +36,14 @@ const STRING_TO_VARIANT_TYPE: Dictionary = { "STRING_NAME": TYPE_STRING_NAME, } -const cast_relationships = [ - [TYPE_INT, TYPE_FLOAT, "float(%s)"], - [TYPE_FLOAT, TYPE_INT, "int(%s)"], - [TYPE_INT, TYPE_STRING, "str(%s)"], - [TYPE_FLOAT, TYPE_STRING, "str(%s)"], - [TYPE_COLOR, TYPE_STRING, "str(%s)"], - [TYPE_VECTOR2, TYPE_STRING, "str(%s)"], - [TYPE_VECTOR2, TYPE_BOOL, "%s"], - [TYPE_VECTOR3, TYPE_STRING, "str(%s)"], - [TYPE_VECTOR3, TYPE_BOOL, "%s"], -] - -# Directed graph, edges are CastGraphEdge -static var cast_graph: Dictionary - - -class CastGraphEdge: - var to: Variant.Type - var cast_format: String - - func _init(p_to: Variant.Type, p_cast_format: String): - to = p_to - cast_format = p_cast_format - - -static func init_cast_graph(): - cast_graph = {} - - for rel in cast_relationships: - if not cast_graph.has(rel[0]): - cast_graph[rel[0]] = [] - - if not cast_graph.has(rel[1]): - cast_graph[rel[1]] = [] - - var edges: Array = cast_graph[rel[0]] - - edges.append(CastGraphEdge.new(rel[1], rel[2])) - - -# Graph recursive utils -static var prev: Dictionary -static var dist: Dictionary -const INT_MAX: int = 1000000000 - - -static func dijkstra(source: Variant.Type): - prev = {} - dist = {} - - var queue := PriorityQueue.new() - - dist[source] = 0 - queue.push(source, 0) - - for v in cast_graph.keys(): - if v != source: - dist[v] = INT_MAX - prev[v] = null - queue.push(v, INT_MAX) - - while not queue.is_empty(): - var u = queue.pop() - - if !cast_graph.has(u): - continue - - for edge in cast_graph[u]: - var v = edge.to - var alt = dist[u] + 1 - if alt < dist[v]: - dist[v] = alt - prev[v] = CastGraphEdge.new(u, edge.cast_format) - queue.update_priority(v, alt) +const types_relationships = { + TYPE_INT: [TYPE_FLOAT], + TYPE_FLOAT: [TYPE_INT], + TYPE_BOOL: [TYPE_STRING, TYPE_INT, TYPE_FLOAT, TYPE_VECTOR2, TYPE_VECTOR3, TYPE_COLOR, TYPE_NODE_PATH, TYPE_OBJECT, TYPE_NIL, TYPE_STRING_NAME], +} -static func can_cast(type: Variant.Type, parent_type: Variant.Type) -> bool: +static func has_relationship(type: Variant.Type, parent_type: Variant.Type) -> bool: if type == parent_type: return true - - if cast_graph.has(type) and cast_graph.has(parent_type): - dijkstra(type) - return dist[parent_type] < INT_MAX - return false - - -static func cast(val: String, type: Variant.Type, parent_type: Variant.Type): - if type == parent_type: - return val - - if cast_graph.has(type) and cast_graph.has(parent_type): - dijkstra(type) - if dist[parent_type] < INT_MAX: - var prev_edge = prev[parent_type] - var cast_string = "%s" - while prev_edge: - cast_string %= prev_edge.cast_format - if prev.has(prev_edge.to): - prev_edge = prev[prev_edge.to] - else: - prev_edge = null - - return cast_string % val - - return null - - -# TODO: replace with max heap -class PriorityQueue: - var data: Array = [] - - func _init(): - data = [] - - func push(element, priority): - data.append([element, priority]) - _sort() - - func _sort(): - data.sort_custom(func(a, b): a[1] < b[1]) - - func pop(): - if data.size() > 0: - return data.pop_front()[0] - return null - - func peek(): - if data.size() > 0: - return data[0][0] - return null - - func is_empty(): - return data.size() == 0 - - func update_priority(element, priority): - var found_pair = null - for pair in data: - if pair[0] == element: - found_pair = pair - break - - if found_pair: - found_pair[1] = priority - _sort() + return type in types_relationships.get(parent_type, [])