Skip to content

Commit af6cdd8

Browse files
authored
Merge pull request #393 from endlessm/localized-properties
Localized properties
2 parents fdf00e3 + e800b5e commit af6cdd8

File tree

16 files changed

+313
-173
lines changed

16 files changed

+313
-173
lines changed

addons/block_code/code_generation/block_definition.gd

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@
22
extends Resource
33

44
const Types = preload("res://addons/block_code/types/types.gd")
5+
const VariableDefinition = preload("res://addons/block_code/code_generation/variable_definition.gd")
56

67
const FORMAT_STRING_PATTERN = "\\[(?<out_parameter>[^\\]]+)\\]|\\{const (?<const_parameter>[^}]+)\\}|\\{(?!const )(?<in_parameter>[^}]+)\\}|(?<label>[^\\{\\[]+)"
8+
const PROPERTY_SETTER_NAME_PATTERN = "(?<class_name>[^\\s]*)_set_(?<property_name>[^\\s]+)"
9+
const PROPERTY_SETTER_NAME_FORMAT = &"%s_set_%s"
10+
const PROPERTY_CHANGER_NAME_PATTERN = "(?<class_name>[^\\s]*)_change_(?<property_name>[^\\s]+)"
11+
const PROPERTY_CHANGER_NAME_FORMAT = &"%s_change_%s"
12+
const PROPERTY_GETTER_NAME_PATTERN = "(?<class_name>[^\\s]*)_get_(?<property_name>[^\\s]+)"
13+
const PROPERTY_GETTER_NAME_FORMAT = &"%s_get_%s"
14+
const VARIABLE_SETTER_NAME_FORMAT = &"set_var_%s"
15+
const VARIABLE_GETTER_NAME_FORMAT = &"get_var_%s"
716

817
@export var name: StringName
918

@@ -32,6 +41,9 @@ const FORMAT_STRING_PATTERN = "\\[(?<out_parameter>[^\\]]+)\\]|\\{const (?<const
3241
## [codeblock]
3342
## say {salute: STRING} | {fancy: BOOL}
3443
## [/codeblock]
44+
## If [member property_name] is set, this template is assumed to be a format
45+
## string with a `%s` placeholder; in this case, any literal `%` signs must
46+
## be escaped as `%%`.
3547
@export var display_template: String
3648

3749
## Template for the generated GDScript code. This must be valid GDScript. The
@@ -67,8 +79,16 @@ const FORMAT_STRING_PATTERN = "\\[(?<out_parameter>[^\\]]+)\\]|\\{const (?<const
6779
## Empty except for blocks that have a defined scope.
6880
var scope: String
6981

82+
## Optional property name, for localizing it. Only relevant for property setters, changers and
83+
## getters.
84+
var property_name: String
85+
7086
static var _display_template_regex := RegEx.create_from_string(FORMAT_STRING_PATTERN)
7187

88+
static var property_setter_regex := RegEx.create_from_string(PROPERTY_SETTER_NAME_PATTERN)
89+
static var property_changer_regex := RegEx.create_from_string(PROPERTY_CHANGER_NAME_PATTERN)
90+
static var property_getter_regex := RegEx.create_from_string(PROPERTY_GETTER_NAME_PATTERN)
91+
7292

7393
func _init(
7494
p_name: StringName = &"",
@@ -194,3 +214,81 @@ static func _parse_parameter_format(parameter_format: String) -> Dictionary:
194214

195215
static func has_category(block_definition, category: String) -> bool:
196216
return block_definition.category == category
217+
218+
219+
static func new_property_setter(_class_name: String, property: Dictionary, category: String, default_value: Variant) -> Resource:
220+
var type_string: String = Types.VARIANT_TYPE_TO_STRING[property.type]
221+
var block_definition: Resource = new(
222+
PROPERTY_SETTER_NAME_FORMAT % [_class_name, property.name],
223+
_class_name,
224+
Engine.tr("Set the %s property") % property.name,
225+
category,
226+
Types.BlockType.STATEMENT,
227+
TYPE_NIL,
228+
Engine.tr("set %%s to {value: %s}") % type_string,
229+
"%s = {value}" % property.name,
230+
{"value": default_value},
231+
)
232+
block_definition.property_name = property.name
233+
return block_definition
234+
235+
236+
static func new_property_changer(_class_name: String, property: Dictionary, category: String, default_value: Variant) -> Resource:
237+
var type_string: String = Types.VARIANT_TYPE_TO_STRING[property.type]
238+
var block_definition: Resource = new(
239+
PROPERTY_CHANGER_NAME_FORMAT % [_class_name, property.name],
240+
_class_name,
241+
Engine.tr("Change the %s property") % property.name,
242+
category,
243+
Types.BlockType.STATEMENT,
244+
TYPE_NIL,
245+
Engine.tr("change %%s by {value: %s}") % type_string,
246+
"%s += {value}" % property.name,
247+
{"value": default_value},
248+
)
249+
block_definition.property_name = property.name
250+
return block_definition
251+
252+
253+
static func new_property_getter(_class_name: String, property: Dictionary, category: String) -> Resource:
254+
var block_definition: Resource = new(
255+
PROPERTY_GETTER_NAME_FORMAT % [_class_name, property.name],
256+
_class_name,
257+
Engine.tr("The %s property") % property.name,
258+
category,
259+
Types.BlockType.VALUE,
260+
property.type,
261+
"%s",
262+
"%s" % property.name,
263+
)
264+
block_definition.property_name = property.name
265+
return block_definition
266+
267+
268+
static func new_variable_setter(variable: VariableDefinition) -> Resource:
269+
var _type_string: String = Types.VARIANT_TYPE_TO_STRING[variable.var_type]
270+
var block_definition: Resource = new(
271+
VARIABLE_SETTER_NAME_FORMAT % variable.var_name,
272+
"",
273+
Engine.tr("Set the %s variable") % variable.var_name,
274+
"Variables",
275+
Types.BlockType.STATEMENT,
276+
TYPE_NIL,
277+
Engine.tr("set %s to {value: %s}") % [variable.var_name, _type_string],
278+
"%s = {value}" % variable.var_name,
279+
)
280+
return block_definition
281+
282+
283+
static func new_variable_getter(variable: VariableDefinition) -> Resource:
284+
var block_definition: Resource = new(
285+
VARIABLE_GETTER_NAME_FORMAT % variable.var_name,
286+
"",
287+
Engine.tr("The %s variable") % variable.var_name,
288+
"Variables",
289+
Types.BlockType.VALUE,
290+
variable.var_type,
291+
"%s" % variable.var_name,
292+
"%s",
293+
)
294+
return block_definition

addons/block_code/code_generation/blocks_catalog.gd

Lines changed: 24 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -132,54 +132,18 @@ static func _add_property_definitions(_class_name: String, property_list: Array[
132132
# Setter
133133
var block_definition: BlockDefinition
134134
if block_settings.get("has_setter", true):
135-
block_definition = (
136-
BlockDefinition
137-
. new(
138-
&"%s_set_%s" % [_class_name, property.name],
139-
_class_name,
140-
"Set the %s property" % property.name,
141-
block_settings.category,
142-
Types.BlockType.STATEMENT,
143-
TYPE_NIL,
144-
"set %s to {value: %s}" % [property.name.capitalize().to_lower(), type_string],
145-
"%s = {value}" % property.name,
146-
{"value": block_settings.get("default_set", _FALLBACK_SET_FOR_TYPE[property.type])},
147-
)
148-
)
135+
var default_value: Variant = block_settings.get("default_set", _FALLBACK_SET_FOR_TYPE[property.type])
136+
block_definition = BlockDefinition.new_property_setter(_class_name, property, block_settings.category, default_value)
149137
_catalog[block_definition.name] = block_definition
150138

151139
# Changer
152140
if block_settings.get("has_change", true):
153-
block_definition = (
154-
BlockDefinition
155-
. new(
156-
&"%s_change_%s" % [_class_name, property.name],
157-
_class_name,
158-
"Change the %s property" % property.name,
159-
block_settings.category,
160-
Types.BlockType.STATEMENT,
161-
TYPE_NIL,
162-
"change %s by {value: %s}" % [property.name.capitalize().to_lower(), type_string],
163-
"%s += {value}" % property.name,
164-
{"value": block_settings.get("default_change", _FALLBACK_CHANGE_FOR_TYPE[property.type])},
165-
)
166-
)
141+
var default_value: Variant = block_settings.get("default_change", _FALLBACK_CHANGE_FOR_TYPE[property.type])
142+
block_definition = BlockDefinition.new_property_changer(_class_name, property, block_settings.category, default_value)
167143
_catalog[block_definition.name] = block_definition
168144

169145
# Getter
170-
block_definition = (
171-
BlockDefinition
172-
. new(
173-
&"%s_get_%s" % [_class_name, property.name],
174-
_class_name,
175-
"The %s property" % property.name,
176-
block_settings.category,
177-
Types.BlockType.VALUE,
178-
property.type,
179-
"%s" % property.name.capitalize().to_lower(),
180-
"%s" % property.name,
181-
)
182-
)
146+
block_definition = BlockDefinition.new_property_getter(_class_name, property, block_settings.category)
183147
_catalog[block_definition.name] = block_definition
184148

185149

@@ -238,7 +202,7 @@ static func _get_custom_parent_class_name(_custom_class_name: String) -> String:
238202
return "Node"
239203

240204

241-
static func _get_parents(_class_name: String) -> Array[String]:
205+
static func get_parents(_class_name: String) -> Array[String]:
242206
if ClassDB.class_exists(_class_name):
243207
return _get_builtin_parents(_class_name)
244208
var parents: Array[String] = []
@@ -253,7 +217,7 @@ static func get_inherited_blocks(_class_name: String) -> Array[BlockDefinition]:
253217
setup()
254218

255219
var definitions: Array[BlockDefinition] = []
256-
for _parent_class_name in _get_parents(_class_name):
220+
for _parent_class_name in get_parents(_class_name):
257221
definitions.append_array(_get_blocks_by_class(_parent_class_name))
258222
definitions.append_array(_get_blocks_by_class(""))
259223
return definitions
@@ -276,55 +240,29 @@ static func add_custom_blocks(
276240
static func get_variable_block_definitions(variables: Array[VariableDefinition]) -> Array[BlockDefinition]:
277241
var block_definitions: Array[BlockDefinition] = []
278242
for variable: VariableDefinition in variables:
279-
var block_def: BlockDefinition
280-
281-
# Getter
282-
block_def = get_variable_getter_block_definition(variable)
283-
block_definitions.append(block_def)
284-
285-
# Setter
286-
block_def = get_variable_setter_block_definition(variable)
287-
block_definitions.append(block_def)
243+
block_definitions.append(BlockDefinition.new_variable_getter(variable))
244+
block_definitions.append(BlockDefinition.new_variable_setter(variable))
288245

289246
return block_definitions
290247

291248

292-
static func get_variable_getter_block_definition(variable: VariableDefinition) -> BlockDefinition:
293-
var block_def := BlockDefinition.new()
249+
static func get_property_getter_block_definition(_class_name: String, property: Dictionary) -> BlockDefinition:
250+
var name = BlockDefinition.PROPERTY_GETTER_NAME_FORMAT % [_class_name, property.name]
251+
if name in _catalog:
252+
return _catalog[name]
253+
var block_definition := BlockDefinition.new_property_getter(_class_name, property, "Variables")
254+
_catalog[block_definition.name] = block_definition
255+
return block_definition
294256

295-
block_def.name = "get_var_%s" % variable.var_name
296-
block_def.category = "Variables"
297-
block_def.type = Types.BlockType.VALUE
298-
block_def.variant_type = variable.var_type
299-
block_def.display_template = variable.var_name
300-
block_def.code_template = variable.var_name
301-
302-
return block_def
303257

304-
305-
static func get_variable_setter_block_definition(variable: VariableDefinition) -> BlockDefinition:
306-
var _type_string: String = Types.VARIANT_TYPE_TO_STRING[variable.var_type]
307-
var block_def := BlockDefinition.new()
308-
309-
block_def.name = "set_var_%s" % variable.var_name
310-
block_def.category = "Variables"
311-
block_def.type = Types.BlockType.STATEMENT
312-
block_def.display_template = "Set %s to {value: %s}" % [variable.var_name, _type_string]
313-
block_def.code_template = "%s = {value}" % variable.var_name
314-
315-
return block_def
316-
317-
318-
static func get_property_getter_block_definition(variable: VariableDefinition) -> BlockDefinition:
319-
var block_def := get_variable_getter_block_definition(variable)
320-
block_def.description = "The %s property" % variable.var_name
321-
return block_def
322-
323-
324-
static func get_property_setter_block_definition(variable: VariableDefinition) -> BlockDefinition:
325-
var block_def := get_variable_setter_block_definition(variable)
326-
block_def.description = "Set the %s property" % variable.var_name
327-
return block_def
258+
static func get_property_setter_block_definition(_class_name: String, property: Dictionary) -> BlockDefinition:
259+
var name = BlockDefinition.PROPERTY_SETTER_NAME_FORMAT % [_class_name, property.name]
260+
if name in _catalog:
261+
return _catalog[name]
262+
var default_value: Variant = _FALLBACK_SET_FOR_TYPE[property.type]
263+
var block_definition := BlockDefinition.new_property_setter(_class_name, property, "Variables", default_value)
264+
_catalog[block_definition.name] = block_definition
265+
return block_definition
328266

329267

330268
static func get_resource_block_definition(file_path: String) -> BlockDefinition:

addons/block_code/examples/pong_game/player_score.tscn

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[gd_scene load_steps=11 format=3 uid="uid://djmtbm15n2wqq"]
22

3-
[ext_resource type="Script" path="res://addons/block_code/simple_nodes/simple_scoring/simple_scoring.gd" id="1_eafo0"]
4-
[ext_resource type="Script" path="res://addons/block_code/block_code_node/block_code.gd" id="2_4mu48"]
5-
[ext_resource type="Script" path="res://addons/block_code/serialization/block_serialization_tree.gd" id="3_kpcgt"]
6-
[ext_resource type="Script" path="res://addons/block_code/serialization/block_serialization.gd" id="4_ph8ne"]
7-
[ext_resource type="Script" path="res://addons/block_code/serialization/block_script_serialization.gd" id="6_k7up7"]
8-
[ext_resource type="Script" path="res://addons/block_code/code_generation/variable_definition.gd" id="7_x0rr3"]
3+
[ext_resource type="Script" uid="uid://chi1008f4c7el" path="res://addons/block_code/simple_nodes/simple_scoring/simple_scoring.gd" id="1_eafo0"]
4+
[ext_resource type="Script" uid="uid://cumxsbxj56dmk" path="res://addons/block_code/block_code_node/block_code.gd" id="2_4mu48"]
5+
[ext_resource type="Script" uid="uid://brx1cabdmgu38" path="res://addons/block_code/serialization/block_serialization_tree.gd" id="3_kpcgt"]
6+
[ext_resource type="Script" uid="uid://u035wsjd5tpj" path="res://addons/block_code/serialization/block_serialization.gd" id="4_ph8ne"]
7+
[ext_resource type="Script" uid="uid://tlsvrkc3fubl" path="res://addons/block_code/serialization/block_script_serialization.gd" id="6_k7up7"]
8+
[ext_resource type="Script" uid="uid://bwkinr8omutpw" path="res://addons/block_code/code_generation/variable_definition.gd" id="7_x0rr3"]
99

1010
[sub_resource type="Resource" id="Resource_paaek"]
1111
script = ExtResource("4_ph8ne")
@@ -44,7 +44,6 @@ version = 0
4444

4545
[node name="PlayerScore" type="Node2D" groups=["hud"]]
4646
script = ExtResource("1_eafo0")
47-
score = null
4847

4948
[node name="BlockCode" type="Node" parent="."]
5049
script = ExtResource("2_4mu48")

addons/block_code/examples/pong_game/pong_game.tscn

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,11 +612,9 @@ follow_viewport_enabled = true
612612

613613
[node name="PlayerScoreLeft" parent="CanvasLayer" instance=ExtResource("13_jvkp7")]
614614
position = Vector2(240, 0)
615-
score = 0
616615

617616
[node name="PlayerScoreRight" parent="CanvasLayer" instance=ExtResource("13_jvkp7")]
618617
position = Vector2(1200, 0)
619-
score = 0
620618

621619
[node name="Camera2D" type="Camera2D" parent="."]
622620
position = Vector2(960, 540)

addons/block_code/examples/spawner/spawner.tscn

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
[gd_scene load_steps=37 format=3 uid="uid://cbgxxdewi6gld"]
22

3-
[ext_resource type="Script" path="res://addons/block_code/simple_spawner/simple_spawner.gd" id="1_g2l2s"]
3+
[ext_resource type="Script" uid="uid://7kttlqmve4yi" path="res://addons/block_code/simple_spawner/simple_spawner.gd" id="1_g2l2s"]
44
[ext_resource type="PackedScene" uid="uid://dhfvkunrlqads" path="res://addons/block_code/examples/spawner/ball.tscn" id="2_d0h86"]
55
[ext_resource type="PackedScene" uid="uid://c8hrliwojohal" path="res://addons/block_code/examples/spawner/volatile_ball.tscn" id="3_tt12o"]
6-
[ext_resource type="Script" path="res://addons/block_code/block_code_node/block_code.gd" id="4_e0fbh"]
7-
[ext_resource type="Script" path="res://addons/block_code/serialization/block_serialization_tree.gd" id="5_g4h7g"]
8-
[ext_resource type="Script" path="res://addons/block_code/serialization/block_serialization.gd" id="6_dv2kl"]
9-
[ext_resource type="Script" path="res://addons/block_code/serialization/value_block_serialization.gd" id="7_cykhe"]
10-
[ext_resource type="Script" path="res://addons/block_code/serialization/block_script_serialization.gd" id="8_tovvd"]
11-
[ext_resource type="Script" path="res://addons/block_code/code_generation/variable_definition.gd" id="9_m8g1j"]
6+
[ext_resource type="Script" uid="uid://cumxsbxj56dmk" path="res://addons/block_code/block_code_node/block_code.gd" id="4_e0fbh"]
7+
[ext_resource type="Script" uid="uid://brx1cabdmgu38" path="res://addons/block_code/serialization/block_serialization_tree.gd" id="5_g4h7g"]
8+
[ext_resource type="Script" uid="uid://u035wsjd5tpj" path="res://addons/block_code/serialization/block_serialization.gd" id="6_dv2kl"]
9+
[ext_resource type="Script" uid="uid://duvgxorhfitb7" path="res://addons/block_code/serialization/value_block_serialization.gd" id="7_cykhe"]
10+
[ext_resource type="Script" uid="uid://tlsvrkc3fubl" path="res://addons/block_code/serialization/block_script_serialization.gd" id="8_tovvd"]
11+
[ext_resource type="Script" uid="uid://bwkinr8omutpw" path="res://addons/block_code/code_generation/variable_definition.gd" id="9_m8g1j"]
1212

1313
[sub_resource type="Resource" id="Resource_1x252"]
1414
script = ExtResource("6_dv2kl")
@@ -211,6 +211,7 @@ version = 0
211211
[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_c5n1h"]
212212

213213
[node name="Node2D" type="Node2D"]
214+
auto_translate_mode = 2
214215

215216
[node name="SimpleSpawner" type="Node2D" parent="."]
216217
position = Vector2(103, 128)

0 commit comments

Comments
 (0)