-
Notifications
You must be signed in to change notification settings - Fork 26
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
BlockScriptSerialization: Re-generate block definition for object property blocks #316
Conversation
block_name = &"%s_set_%s" % [object_name, property_name] | ||
block_definition = _context.block_script.get_obj_property_block_definition(block_name, property_value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't like how we construct a string and then pass it to a function which immediately splits it back up into the 3 pieces we had here.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tried building this feature around _get_parameter_block_definition
? There's a bit of overlap here. In fact they're solving the same fundamental problem: it's a type of block where we generate a block definition when we need it, based on an identifier such as a property name.
As it exists, that function only generates the one kind of value block, which is an output parameter for another block. (It needs a base block definition so it knows what output parameters are defined). So it needs extra help, but it should be feasible to extend it similarly to what you have in get_obj_property_block_definition
, so our parameter blocks would start looking like MyType_get:property.
I think there's a few ways to make that work. I think ideally we'd have _get_base_block_definition
generate a plain MyType_get and MyType_set block for whatever type is at hand, and we'd have something in BlockDefinition that _get_parameter_block_definition
calls which would be like "give me a parameterized version of this block definition with foo set to bar".
I realize I'm asking for a fair bit of extra machinery here so I understand if we just want to land a bug fix, but I did have this case in mind when I was adding parameter block definitions. Sorry I didn't really document it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me study this more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I try some scenario as examples: the "speed" and "floor_stop_on_slope" properties
-
"Object_get:speed" will be split for
_get_parameter_block_definition()
- block_name: "Object_get"
- parameter_name: "speed". Its type is
Vector2
-
"Object_get:floor_stop_on_slope" will be split for
_get_parameter_block_definition()
- block_name: "Object_get"
- parameter_name: "floor_stop_on_slope". Its type is
boolean
Because of the different parameter_name
s, we have to generate different base block definitions having corresponding display_template
for parent_out_parameters.has(parameter_name)
dynamically, which means the object property block's logic is different from the parameter block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides, it loses the property's variant type after close the project actually. Because, the property's variant type is not saved in the resource of .tscn
. The setter block's variant type can be restored by the stored value. However, getter block does not have the value information.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the limitation of the parameter_name and the getter's variant type, I think we cannot generate blocks via _get_parameter_block_definition()
now. So, I go back to the _get_obj_property_block_definition()
in the updated commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for coming in late here, but the property doesn't need to be encoded in the scene file because it's part of the object it's being applied to. It's more work, but you can call get_property_list on the target object to determine the type. I think that would be more elegant than encoding the type in the block name. It wouldn't be that hard to get the property list once at the beginning of deserializing and then find the appropriate property as the definitions are loaded.
ea8226b
to
abc49ae
Compare
abc49ae
to
0cc6dcd
Compare
Extract the getter and setter block definition code from get_variable_block_definitions() as get_variable_getter_block_definition() and get_variable_setter_block_definition(). They can be used by more places latter.
9a840c2
to
01a44db
Compare
I encode the property's variant type into block name finally. So, after reopen the project, block coding can restore the variant type information of the property's getter block. Here is the demo video: |
Trying to get the property name from the block name like Now as discussed, reusing the
|
I don't see how adding an I came up with a 3rd option. What we really want is to look at the target node's instance, but that's not available in the serialization since it's a child of the node. However, we can find the node from the scene tree because we know that the parent
https://github.com/endlessm/godot-block-coding/tree/block-script-target adds some helpers to do it. When deserializing property block definitions, you'd do something like:
|
Another simpler possibility is that we have the
With the |
I was stuck at why I cannot |
Just to clarify a bit. Only |
… drop object property The object property's getter & setter blocks generating code is similar to get_variable_(get|set)ter_block_definition(). So, reuse them within get_property_(get|set)ter_block_definition() to generate property's blocks including the description. And, the block name will change to: "(get|set)_var_<property name>". Fixes: 89beea9 ("BlockCanvas: Implement drag & drop the node's property from Inspector") https://phabricator.endlessm.com/T35649
…ock code node and script Build the bidirectional link between the block code node and the block script. So, the block script can access this block node and the parent node later easily. https://phabricator.endlessm.com/T35649
01a44db
to
d63a843
Compare
As #316 (comment), I think having the bidirectional link between the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this makes sense to me. The only thing I'd want to see addressed is the change to pass in the block arguments when serializing. That doesn't seem necessary if you're already using the property information for the property getter block.
static func get_property_getter_block_definition(variable: VariableDefinition) -> BlockDefinition: | ||
var block_def := get_variable_getter_block_definition(variable) | ||
block_def.description = "The %s property" % variable.var_name | ||
return block_def |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit unfortunate that these property blocks will be in the Variables section, but I can't think of a better place at the moment.
@@ -28,6 +28,8 @@ const SCENE_PER_TYPE = { | |||
@export var generated_script: String | |||
@export var version: int | |||
|
|||
var block_code_node: BlockCode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A potential future improvement here would be to cache the parent properties when set so that _get_parent_node_property_info
didn't have to iterate the entire property list every time. I don't think that's worth it right now, though.
d63a843
to
f738fff
Compare
f738fff
to
8e9119b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks like it should work! 2 final nitpicks, but feel free to merge after that.
…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, visit the block code node's parent node to finding the property by _get_parent_node_property_info() to have the type. https://phabricator.endlessm.com/T35649
Godot allows drag any thing. However, if it is a property, block code script only manipulates the properties of BlockCode node's parent node. So, when drag a property, only allow drop the parent node's property. Fixes: 89beea9 ("BlockCanvas: Implement drag & drop the node's property from Inspector") https://phabricator.endlessm.com/T35649
8e9119b
to
5c3358d
Compare
Thank you guys' help! I merge this! |
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.
Fixes: 89beea9 ("BlockCanvas: Implement drag & drop the node's property from Inspector") https://phabricator.endlessm.com/T35649