Skip to content

Commit

Permalink
Merge pull request #32 from endlessm/refactor-block-types
Browse files Browse the repository at this point in the history
Type casting
  • Loading branch information
manuq authored Jun 14, 2024
2 parents 77ddcc3 + c82d8ea commit f01b3fd
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 17 deletions.
2 changes: 2 additions & 0 deletions addons/block_code/block_code_plugin.gd
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const DISABLED_CLASSES := [


func _enter_tree():
Types.init_cast_graph()

main_panel = MainPanel.instantiate()
main_panel.undo_redo = get_undo_redo()

Expand Down
33 changes: 17 additions & 16 deletions addons/block_code/drag_manager/drag_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,23 @@ func _process(_delta):
if snap_point.block == null:
push_error("Warning: a snap point does not reference it's parent block.")
continue
if snap_point.block.on_canvas and snap_point.block_type == dragging.block_type:
var snap_global_pos: Vector2 = snap_point.get_global_rect().position
var temp_dist: float = dragging_global_pos.distance_to(snap_global_pos)
if temp_dist < closest_dist:
# Check if any parent node is this node
var is_child: bool = false
var parent = snap_point
while parent is SnapPoint:
if parent.block == dragging:
is_child = true

parent = parent.block.get_parent()

if not is_child:
closest_dist = temp_dist
closest_snap_point = snap_point
if snap_point.block.on_canvas:
if Types.can_cast(dragging.block_type, snap_point.block_type):
var snap_global_pos: Vector2 = snap_point.get_global_rect().position
var temp_dist: float = dragging_global_pos.distance_to(snap_global_pos)
if temp_dist < closest_dist:
# Check if any parent node is this node
var is_child: bool = false
var parent = snap_point
while parent is SnapPoint:
if parent.block == dragging:
is_child = true

parent = parent.block.get_parent()

if not is_child:
closest_dist = temp_dist
closest_snap_point = snap_point

if closest_dist > 80.0:
closest_snap_point = null
Expand Down
140 changes: 140 additions & 0 deletions addons/block_code/types/types.gd
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,143 @@ enum BlockType {
COLOR,
NODE
}

const cast_relationships = [
[BlockType.INT, BlockType.FLOAT, "float(%s)"],
[BlockType.FLOAT, BlockType.INT, "int(%s)"],
[BlockType.INT, BlockType.STRING, "str(%s)"],
[BlockType.FLOAT, BlockType.STRING, "str(%s)"],
]

# Directed graph, edges are CastGraphEdge
static var cast_graph: Dictionary


class CastGraphEdge:
var to: BlockType
var cast_format: String

func _init(p_to: BlockType, 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: BlockType):
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)


static func can_cast(type: BlockType, parent_type: BlockType) -> 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: BlockType, parent_type: BlockType):
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()
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ func get_snapped_block() -> Block:
func get_string() -> String:
var snapped_block: Block = get_snapped_block()
if snapped_block:
return snapped_block.get_parameter_string()
var generated_string = snapped_block.get_parameter_string()
return Types.cast(generated_string, snapped_block.block_type, block_type)

var text: String = get_plain_text()

Expand Down

0 comments on commit f01b3fd

Please sign in to comment.