Skip to content

Commit

Permalink
Decouple block type from block variant
Browse files Browse the repository at this point in the history
And use Variant.Type enum for the Value block variant.

This means we stick to GDScript variants for the values represented by
Value blocks:
- A constant like "viewport width"
- A property like "rotation"
- A parameter like A in "A + B"
- The resulting value of "A + B"

The slots that can contain Value blocks also have a matching variant
type now.

Unfortunately there is no way to convert the native Variant.Type enum to
string, so still we need dictionaries to go back and forth the string
formatting.

Previously there was a custom NODE type, although unused. This is now
replaced by NODE_PATH, which is the same thing that Godot does in the
PackedScene resource when exporting a property of type Node.

Also: improve readability of drag manager and use a constant for the
minimum slot distance.
  • Loading branch information
manuq committed Jun 18, 2024
1 parent 3050f2e commit 4d7445a
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 100 deletions.
61 changes: 33 additions & 28 deletions addons/block_code/drag_manager/drag_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ signal block_modified
@export var picker_path: NodePath
@export var block_canvas_path: NodePath

const Constants = preload("res://addons/block_code/ui/constants.gd")

var drag_offset: Vector2
var dragging: Block = null

Expand Down Expand Up @@ -39,38 +41,41 @@ func _process(_delta):
var closest_snap_point: SnapPoint = null
var closest_dist: float = INF
var snap_points: Array[Node] = get_tree().get_nodes_in_group("snap_point")
for n in snap_points:
if n is SnapPoint:
var snap_point: SnapPoint = n as SnapPoint
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:
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
for snap_point in snap_points:
if not snap_point is SnapPoint:
push_error('Warning: a node in group "snap_point"snap is not of class SnapPoint.')
continue
if snap_point.block == null:
push_error("Warning: a snap point does not reference it's parent block.")
continue
if not snap_point.block.on_canvas:
# We only snap to blocks on the canvas:
continue
if dragging.block_type != snap_point.block_type:
# We only snap to the same block type:
continue
if dragging.block_type == Types.BlockType.VALUE and not Types.can_cast(dragging.variant_type, snap_point.variant_type):
# We only snap Value blocks to snaps that can cast to same variant:
continue
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 <= Constants.MINIMUM_SNAP_DISTANCE and 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_snap_point != previewing_snap_point:
_update_preview(closest_snap_point)

# TODO: make sure dragging.block_type is the same as snap_point type


func _update_preview(snap_point: SnapPoint):
previewing_snap_point = snap_point
Expand Down
51 changes: 33 additions & 18 deletions addons/block_code/types/types.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,49 @@ extends Node

enum BlockType {
NONE,
EXECUTE,
ENTRY,
# Parameters
STRING,
INT,
FLOAT,
VECTOR2,
BOOL,
COLOR,
NODE
EXECUTE,
VALUE,
}

const VARIANT_TYPE_TO_STRING: Dictionary = {
TYPE_STRING: "STRING",
TYPE_INT: "INT",
TYPE_FLOAT: "FLOAT",
TYPE_BOOL: "BOOL",
TYPE_VECTOR2: "VECTOR2",
TYPE_COLOR: "COLOR",
TYPE_NODE_PATH: "NODE_PATH",
TYPE_NIL: "NIL",
}

const STRING_TO_VARIANT_TYPE: Dictionary = {
"STRING": TYPE_STRING,
"INT": TYPE_INT,
"FLOAT": TYPE_FLOAT,
"BOOL": TYPE_BOOL,
"VECTOR2": TYPE_VECTOR2,
"COLOR": TYPE_COLOR,
"NODE_PATH": TYPE_NODE_PATH,
"NIL": TYPE_NIL,
}

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)"],
[TYPE_INT, TYPE_FLOAT, "float(%s)"],
[TYPE_FLOAT, TYPE_INT, "int(%s)"],
[TYPE_INT, TYPE_STRING, "str(%s)"],
[TYPE_FLOAT, TYPE_STRING, "str(%s)"],
]

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


class CastGraphEdge:
var to: BlockType
var to: Variant.Type
var cast_format: String

func _init(p_to: BlockType, p_cast_format: String):
func _init(p_to: Variant.Type, p_cast_format: String):
to = p_to
cast_format = p_cast_format

Expand All @@ -56,7 +71,7 @@ static var dist: Dictionary
const INT_MAX: int = 1000000000


static func dijkstra(source: BlockType):
static func dijkstra(source: Variant.Type):
prev = {}
dist = {}

Expand Down Expand Up @@ -86,7 +101,7 @@ static func dijkstra(source: BlockType):
queue.update_priority(v, alt)


static func can_cast(type: BlockType, parent_type: BlockType) -> bool:
static func can_cast(type: Variant.Type, parent_type: Variant.Type) -> bool:
if type == parent_type:
return true

Expand All @@ -96,7 +111,7 @@ static func can_cast(type: BlockType, parent_type: BlockType) -> bool:
return false


static func cast(val: String, type: BlockType, parent_type: BlockType):
static func cast(val: String, type: Variant.Type, parent_type: Variant.Type):
if type == parent_type:
return val

Expand Down
1 change: 1 addition & 0 deletions addons/block_code/ui/blocks/entry_block/entry_block.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ extends StatementBlock


func _ready():
block_type = Types.BlockType.ENTRY
super()


Expand Down
5 changes: 4 additions & 1 deletion addons/block_code/ui/blocks/entry_block/entry_block.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@
script = ExtResource("2_3ik8h")
block_name = "entry_block"
label = "EntryBlock"
block_type = 2
block_type = 1

[node name="Background" parent="VBoxContainer/TopMarginContainer" index="0"]
show_top = false
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ extends Block

@export var block_format: String = ""
@export var statement: String = ""
@export var variant_type: Variant.Type

@onready var _panel := $Panel
@onready var _hbox := %HBoxContainer
Expand All @@ -15,6 +16,7 @@ var param_input_strings: Dictionary # Only loaded from serialized
func _ready():
super()

block_type = Types.BlockType.VALUE
var new_panel = _panel.get_theme_stylebox("panel").duplicate()
new_panel.bg_color = color
new_panel.border_color = color.darkened(0.2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ static func format_string(parent_block: Block, attach_to: Node, string: String)
var split := param.split(": ")
var param_name := split[0]
var param_type_str := split[1]
var param_type := Types.BlockType.get(param_type_str)
var param_type: Variant.Type = Types.STRING_TO_VARIANT_TYPE[param_type_str]

var param_input: ParameterInput = preload("res://addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.tscn").instantiate()
param_input.name = "ParameterInput%d" % start # Unique path
param_input.placeholder = param_name
param_input.block_type = param_type
param_input.variant_type = param_type
param_input.block = parent_block
param_input.text_modified.connect(func(): parent_block.modified.emit())
attach_to.add_child(param_input)
Expand All @@ -115,7 +115,7 @@ static func format_string(parent_block: Block, attach_to: Node, string: String)
var new_block: Block = preload("res://addons/block_code/ui/blocks/parameter_block/parameter_block.tscn").instantiate()
new_block.block_format = param_name
new_block.statement = param_name
new_block.block_type = param_type
new_block.variant_type = param_type
new_block.color = parent_block.color
param_input.block_type = Types.BlockType.NONE
param_input.snap_point.block_type = Types.BlockType.NONE # Necessary because already called ready
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ signal text_modified

@export var block_path: NodePath

@export var block_type: Types.BlockType = Types.BlockType.STRING
@export var variant_type: Variant.Type = TYPE_STRING
@export var block_type: Types.BlockType = Types.BlockType.VALUE

var block: Block

Expand Down Expand Up @@ -41,6 +42,7 @@ func _ready():
block = get_node_or_null(block_path)
snap_point.block = block
snap_point.block_type = block_type
snap_point.variant_type = variant_type

# Do something with block_type to restrict input

Expand All @@ -50,16 +52,16 @@ func get_snapped_block() -> Block:


func get_string() -> String:
var snapped_block: Block = get_snapped_block()
var snapped_block: ParameterBlock = get_snapped_block() as ParameterBlock
if snapped_block:
var generated_string = snapped_block.get_parameter_string()
return Types.cast(generated_string, snapped_block.block_type, block_type)
return Types.cast(generated_string, snapped_block.variant_type, variant_type)

var text: String = get_plain_text()

if block_type == Types.BlockType.STRING:
if variant_type == TYPE_STRING:
text = "'%s'" % text.replace("\\", "\\\\").replace("'", "\\'")
if block_type == Types.BlockType.VECTOR2:
elif variant_type == TYPE_VECTOR2:
text = "Vector2(%s)" % text

return text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ extends MarginContainer

@export var block_type: Types.BlockType = Types.BlockType.EXECUTE

## Only used when block_type is a [enum Types.BlockType.VALUE].
@export var variant_type: Variant.Type

var block: Block


Expand Down
1 change: 1 addition & 0 deletions addons/block_code/ui/constants.gd
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ const KNOB_H = 5.0
const KNOB_Z = 5.0
const CONTROL_MARGIN = 20.0
const OUTLINE_WIDTH = 3.0
const MINIMUM_SNAP_DISTANCE = 80.0
Loading

0 comments on commit 4d7445a

Please sign in to comment.