Skip to content

T35591 more block definitions #199

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 17 commits into from
Aug 23, 2024
Merged

T35591 more block definitions #199

merged 17 commits into from
Aug 23, 2024

Conversation

manuq
Copy link
Contributor

@manuq manuq commented Aug 16, 2024

Add target node class to the definition for class-specific blocks. For
example, "On body entered / exited" block is specific to a node that
inherits RigidBody2D.

https://phabricator.endlessm.com/T35591
@manuq
Copy link
Contributor Author

manuq commented Aug 16, 2024

Here is more porting to the new block definitions. Compared with @wnbaum PR, this is using resource files, not through code like in f390ae8#diff-d355da8c634915f2c506c52aaf96eba422696b3c4b7cf0362804bd673b3a4767R431-R438

@starnight
Copy link
Contributor

Should we transform the data type of raw_input, before assign to _line_edit.text? It shows error with Godot 4.3:

res://addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd:65 - Invalid assignment of property or key 'text' with value of type 'float' on a base object of type 'LineEdit'.

@manuq
Copy link
Contributor Author

manuq commented Aug 19, 2024

Should we transform the data type of raw_input, before assign to _line_edit.text? It shows error with Godot 4.3:

res://addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd:65 - Invalid assignment of property or key 'text' with value of type 'float' on a base object of type 'LineEdit'.

Yes, thanks for pointing @starnight. I'll do it. The original PR has this in 0946f37 but that commit doesn't work well in isolation.

@manuq
Copy link
Contributor Author

manuq commented Aug 19, 2024

I migrated the property blocks and the custom blocks. But now I have to change the tests.

As defined by the target class in the resource file.
@manuq manuq force-pushed the T35591-more-block-definitions branch from 703e5d1 to 16eac33 Compare August 20, 2024 20:05
Copy link
Contributor

@dylanmccall dylanmccall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read through all this and it looks good to me! It would be nice to make the InputMap stuff happen without the hack in blocks_catalog, but I don't feel like we need to do that here. (And I was going to mess around with that type of thing in #191). This already lands us a significant upgrade from the previous setup :)

Comment on lines +39 to +43
static func get_blocks_by_class(_class_name: String):
if not _class_name in _by_class_name:
return []
var block_definitions = _by_class_name[_class_name] as Dictionary
return block_definitions.values()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat! Is the aim for this to replace the setup_custom_blocks thing we have right now (like with SimpleCharacter)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately no. See 028fa10 how I ported the custom blocks. Do you think they should be defined in resource files and added automatically to the catalog?

Copy link
Contributor

@dylanmccall dylanmccall Aug 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that made sense to me once I got to the later commits :) I think that would be very clever if custom blocks were defined in resource files, but I can see how that's a tangent from the purpose of this branch. I'm tempted to play with that in another branch after I've done some more pressing things. A start would be to make BlocksCatalog._BLOCKS_PATH a list and solve from there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dylanmccall you made me think that the ResourceLoader is already loading these resource files, so we are actually loading them twice using DirAccess. In fact, the DirAccess docs say "use ResourceLoader to access imported resources". So maybe a better idea would be:

  • Add a custom extension to these resource files like .block or .blockdef.
  • Add a ResourceFormatLoader that can handle that extension and add the block definitions to the catalog as they load.

Then custom resource files can be added to the user project without caring about the filesystem path.

Copy link
Member

@dbnicholson dbnicholson Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we had a custom extension it would also help later for translation since we likely need a custom translation parser that matches by file extension. That said, I think we should punt for the moment and try to get this work landed.

b = Util.instantiate_block(block_name)
b = Util.instantiate_block_by_name(block_name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While we're here (already changing most references to b), can we switch away from the single-letter variable name, maybe in a commit right before this one? I will find this nicer to read if we change b to block, especially now that there's much less else going on here :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! It was bugging me as well.

Comment on lines -143 to +142
return serialize_props(["color", "scope"])
return serialize_props(["scope"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hooray!

@manuq
Copy link
Contributor Author

manuq commented Aug 21, 2024

I read through all this and it looks good to me! It would be nice to make the InputMap stuff happen without the hack in blocks_catalog, but I don't feel like we need to do that here. (And I was going to mess around with that type of thing in #191). This already lands us a significant upgrade from the previous setup :)

Thanks for taking a deep look @dylanmccall . Now it should also work and tests are passing again. This is because the last commit which is basically @wnbaum 0946f37 plus some of 073eddd (the raw_input_to_code_string(input)).

@manuq
Copy link
Contributor Author

manuq commented Aug 21, 2024

Should we transform the data type of raw_input, before assign to _line_edit.text? It shows error with Godot 4.3:

res://addons/block_code/ui/blocks/utilities/parameter_input/parameter_input.gd:65 - Invalid assignment of property or key 'text' with value of type 'float' on a base object of type 'LineEdit'.

Adressed in commit 8d18e33

@manuq
Copy link
Contributor Author

manuq commented Aug 21, 2024

@starnight @dylanmccall @dbnicholson I think this is ready for a final review. Compared with the original PR #147:

  • This uses resource files for the per-class blocks like Area2D "on body entered / exited". For this, a new field @export var target_node_class: String was added to the BlockDefinition.
  • Like the original PR, defines custom blocks in each "Simple" class script.
  • The "is input actioned" block is defined in code too because the options need to be fed according to the running project. Maybe as a follow-up we can have a resource file and change the options dynamically?
  • The "get / set variable" blocks are defined in code too. And since these are per BlockScriptSerialization, I'm not adding them to the catalog. Because the whole point of a catalog is to have a unique name for the block that can be instantiated. But since I'm not adding them to the catalog, they end up serialized in the old way. I need to work on this as a follow-up. At least they still work, so there are no regressions.
  • The old serialization is not removed yet because of the above item.
  • The last remaining thing serialized is "scope". I need to look carefully to the original PR to see if this was addressed or not.

@starnight
Copy link
Contributor

starnight commented Aug 21, 2024

Thank you @manuq! It is a big code refactoring.

However, I notice if I add BlockCode under SimpleCharater and SimpleScoring node, it shows error:

Cannot get class 'SimpleCharacter'.
Cannot get class 'SimpleScoring'.

@manuq
Copy link
Contributor Author

manuq commented Aug 21, 2024

Thank you @manuq! It is a big code refactoring.

However, I notice if I add BlockCode under SimpleCharater and SimpleScoring node, it shows error:

Cannot get class 'SimpleCharacter'.
Cannot get class 'SimpleScoring'.

I see it now, thanks. It seems that the block catalog is trying to add their blocks too early. If I switch to another BlockCode and then back to the SimpleCharacter one, I see the custom blocks.

@manuq
Copy link
Contributor Author

manuq commented Aug 21, 2024

Thank you @manuq! It is a big code refactoring.
However, I notice if I add BlockCode under SimpleCharater and SimpleScoring node, it shows error:

Cannot get class 'SimpleCharacter'.
Cannot get class 'SimpleScoring'.

I see it now, thanks. It seems that the block catalog is trying to add their blocks too early. If I switch to another BlockCode and then back to the SimpleCharacter one, I see the custom blocks.

This is now fixed with the 2 last fixups. And the picker logic for custom blocks is much cleaner now! Because the _get_subclasses(_class_name) utility now handles custom classes. For example for SimpleCharacter it will get:

["SimpleCharacter", "CharacterBody2D", "PhysicsBody2D", "CollisionObject2D", "Node2D", "CanvasItem", "Node", "Object"]

This would welcome a unit test.

@manuq
Copy link
Contributor Author

manuq commented Aug 21, 2024

I just redid the Pong example with the new blocks in the PR. While doing it, I've found that there is a hack adding suffix "__nil__" in some parameter inputs in the original PR. I don't quite understand why that was needed in the original PR, but removing it makes things work again. So I appended another fixup.

Copy link
Member

@dbnicholson dbnicholson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All looks good to me besides some nitpicks. Feel free to squash and merge when you're ready!

_:
return "%s" % input
return ""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is unnecessary since the _ case will catch everything.

Copy link
Contributor Author

@manuq manuq Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the same when looking at @wnbaum branch. But if I remove this line, the syntax parser complains for the function saying "Not all code paths return a value.". So I understand why he added it.

@@ -50,7 +50,7 @@ static func instantiate_block_by_name(block_name: StringName) -> Block:
return instantiate_block(block_definition)


static func _get_subclasses(_class_name: String) -> Array[String]:
static func _get_builtin_subclasses(_class_name: String) -> Array[String]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick. These aren't subclasses (classes that inherit this class), they're parent or inherited classes (what this class inherits from).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh of course! Good catch, I'll rename the function.

manuq added 11 commits August 23, 2024 08:36
For this, the previous instantiate_block is renamed to
instantiate_block_by_name.
And remove them from the category factory.

Also add a default value for speed in the characterbody2d_move block.

https://phabricator.endlessm.com/T35591
And change the body type from NODE_PATH to OBJECT, as in previous
definitions.

https://phabricator.endlessm.com/T35591
Port the property setter/changer/getter blocks to the new block
definition.

These are not loaded from resource files, they are defined in code.

https://phabricator.endlessm.com/T35591
Add a way in the blocks catalog to add custom blocks. Port SimpleScoring
and SimpleCharacter to the new block definitions. Change the picker
logic to instantiate these blocks.

https://phabricator.endlessm.com/T35591
And split obtaining the inputmap action names to a inner function.

https://phabricator.endlessm.com/T35591
Using the new block definition. These are the only blocks that are not
stored in the catalog. Instead, they are dynamically generated when the
BlockScriptSerialization changes.

Also: Move constant for the builtin category properties to the
constants.gd script.

Also: Finally remove the preloaded scene blocks from the
category_factory.gd script. The single place where those scenes are now
instantiated is the ui/util.gd script.

https://phabricator.endlessm.com/T35591
@manuq manuq force-pushed the T35591-more-block-definitions branch from 64efb30 to 9dec121 Compare August 23, 2024 11:38
@manuq manuq merged commit aa80f0c into main Aug 23, 2024
3 checks passed
@manuq manuq deleted the T35591-more-block-definitions branch August 23, 2024 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants