Skip to content

Decouple block type from block variant #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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: node %s in group "snap_point" is not of class SnapPoint.' % snap_point)
continue
if snap_point.block == null:
push_error("Warning: snap point %s does not reference it's parent block." % snap_point)
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

## When block_type is [enum Types.BlockType.VALUE], the type of the value that can be used at this snap point.
@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
Loading