Skip to content

Commit

Permalink
BlockScriptSerialization: Re-generate block definition for object pro…
Browse files Browse the repository at this point in the history
…perty blocks

The drag & drop object property's blocks disappear after save & re-open
the Godot project. And, shows error:

core/variant/variant_utility.cpp:1092 - Cannot construct block from null block definition.
res://addons/block_code/ui/block_canvas/block_canvas.gd:348 - Invalid call. Nonexistent function 'set_parameter_values_on_ready' in base 'Nil'.

It is because the object property blocks are not the predefined blocks
in the catalog. So, Block Coding plugin cannot find the block definition
from the catalog when places the object property blocks into the cavas
via _block_to_ast_node() after re-open the project.

Therefore, introduce _get_obj_property_block_definition() generating
object property's getter/setter block definition for
get_block_definition(). Besides, it also needs the object property's
value type. So, pass the AST node's arguments which is a Dictionary and
may contain the "value" feild into get_block_definition(), too.

https://phabricator.endlessm.com/T35649
  • Loading branch information
starnight committed Nov 13, 2024
1 parent a0df3fd commit 9a840c2
Showing 1 changed file with 48 additions and 14 deletions.
62 changes: 48 additions & 14 deletions addons/block_code/serialization/block_script_serialization.gd
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func instantiate_block(block_definition: BlockDefinition) -> Block:


func instantiate_block_by_name(block_name: String) -> Block:
var block_definition := get_block_definition(block_name)
var block_definition := get_block_definition(block_name, {})

if block_definition == null:
push_warning("Cannot find a block definition for %s" % block_name)
Expand All @@ -79,24 +79,29 @@ func instantiate_block_by_name(block_name: String) -> Block:
return instantiate_block(block_definition)


func get_block_definition(block_name: String) -> BlockDefinition:
func get_block_definition(block_name: String, arguments: Dictionary) -> BlockDefinition:
var split := block_name.split(":", true, 1)
var block_definition: BlockDefinition

if len(split) > 1:
return _get_parameter_block_definition(split[0], split[1])

var block_definition = _get_base_block_definition(block_name)
block_definition = _get_base_block_definition(block_name)
if block_definition != null:
return block_definition

if block_definition == null:
# FIXME: This is a workaround for old-style output block references.
# These were generated ahead of time using a block name that has
# a "_" before the parameter name. Now, these parameter blocks
# are generated on demand for any block name containing a ":".
# Please remove this fallback when it is no longer necessary.
split = block_name.rsplit("_", true, 1)
return _get_parameter_block_definition(split[0], split[1])
var property_value = arguments.get("value", null)
block_definition = _get_obj_property_block_definition(block_name, property_value)
if block_definition != null:
return block_definition

return block_definition
# FIXME: This is a workaround for old-style output block references.
# These were generated ahead of time using a block name that has
# a "_" before the parameter name. Now, these parameter blocks
# are generated on demand for any block name containing a ":".
# Please remove this fallback when it is no longer necessary.
split = block_name.rsplit("_", true, 1)
return _get_parameter_block_definition(split[0], split[1])


func _get_base_block_definition(block_name: String) -> BlockDefinition:
Expand Down Expand Up @@ -133,6 +138,33 @@ func _get_parameter_block_definition(block_name: String, parameter_name: String)
return block_definition


func _get_obj_property_block_definition(block_name: String, property_value: Variant) -> BlockDefinition:
var block_definition: BlockDefinition
var variable: VariableDefinition
var property_name: String
var is_getter = true

if block_name.find("get_var_") == 0:
property_name = block_name.get_slice("get_var_", 1)
elif block_name.find("set_var_") == 0:
property_name = block_name.get_slice("set_var_", 1)
is_getter = false
else:
return null

if is_getter:
# Getter block needs the property name and variant type information by
# decoding block name
var split := property_name.rsplit("_", true, 1)
variable = VariableDefinition.new(split[0], int(split[1]))
block_definition = BlocksCatalog.get_property_getter_block_definition(variable)
else:
variable = VariableDefinition.new(property_name, typeof(property_value))
block_definition = BlocksCatalog.get_property_setter_block_definition(variable)

return block_definition


func _update_block_definitions():
_available_blocks.clear()
_available_blocks.append_array(_get_inherited_block_definitions())
Expand Down Expand Up @@ -202,14 +234,15 @@ func _tree_to_ast(tree: BlockSerializationTree) -> BlockAST:

func _block_to_ast_node(node: BlockSerialization) -> BlockAST.ASTNode:
var ast_node := BlockAST.ASTNode.new()
ast_node.data = get_block_definition(node.name)

for arg_name in node.arguments:
var argument = node.arguments[arg_name]
if argument is ValueBlockSerialization:
argument = _value_to_ast_value(argument)
ast_node.arguments[arg_name] = argument

ast_node.data = get_block_definition(node.name, ast_node.arguments)

var children: Array[BlockAST.ASTNode]
for c in node.children:
children.append(_block_to_ast_node(c))
Expand All @@ -220,14 +253,15 @@ func _block_to_ast_node(node: BlockSerialization) -> BlockAST.ASTNode:

func _value_to_ast_value(value_node: ValueBlockSerialization) -> BlockAST.ASTValueNode:
var ast_value_node := BlockAST.ASTValueNode.new()
ast_value_node.data = get_block_definition(value_node.name)

for arg_name in value_node.arguments:
var argument = value_node.arguments[arg_name]
if argument is ValueBlockSerialization:
argument = _value_to_ast_value(argument)
ast_value_node.arguments[arg_name] = argument

ast_value_node.data = get_block_definition(value_node.name, value_node.arguments)

return ast_value_node


Expand Down

0 comments on commit 9a840c2

Please sign in to comment.