Skip to content

Commit 03b1384

Browse files
authored
Merge pull request #182 from endlessm/it-block-cycle
Fix InstructionTree and Block circular dependency
2 parents 7386139 + 047ec47 commit 03b1384

File tree

6 files changed

+93
-86
lines changed

6 files changed

+93
-86
lines changed

addons/block_code/drag_manager/drag.gd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ extends Control
33

44
const Background = preload("res://addons/block_code/ui/blocks/utilities/background/background.gd")
55
const BlockCanvas = preload("res://addons/block_code/ui/block_canvas/block_canvas.gd")
6+
const BlockTreeUtil = preload("res://addons/block_code/ui/block_tree_util.gd")
67
const Constants = preload("res://addons/block_code/ui/constants.gd")
78
const InstructionTree = preload("res://addons/block_code/instruction_tree/instruction_tree.gd")
89
const Types = preload("res://addons/block_code/types/types.gd")
@@ -143,7 +144,7 @@ func _snaps_to(node: Node) -> bool:
143144
if _block_scope != top_block.get_entry_statement():
144145
return false
145146
elif top_block:
146-
var tree_scope := InstructionTree.get_tree_scope(top_block)
147+
var tree_scope := BlockTreeUtil.get_tree_scope(top_block)
147148
if tree_scope != "" and _block_scope != tree_scope:
148149
return false
149150

addons/block_code/drag_manager/drag_manager.gd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ signal block_dropped
55
signal block_modified
66

77
const BlockCanvas = preload("res://addons/block_code/ui/block_canvas/block_canvas.gd")
8+
const BlockTreeUtil = preload("res://addons/block_code/ui/block_tree_util.gd")
89
const Drag = preload("res://addons/block_code/drag_manager/drag.gd")
910
const InstructionTree = preload("res://addons/block_code/instruction_tree/instruction_tree.gd")
1011
const Picker = preload("res://addons/block_code/ui/picker/picker.gd")
@@ -50,7 +51,7 @@ func drag_block(block: Block, copied_from: Block = null):
5051

5152
block.disconnect_signals()
5253

53-
var block_scope := InstructionTree.get_tree_scope(block)
54+
var block_scope := BlockTreeUtil.get_tree_scope(block)
5455
if block_scope != "":
5556
_block_canvas.set_scope(block_scope)
5657

addons/block_code/instruction_tree/instruction_tree.gd

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -56,80 +56,3 @@ static func generate_text_recursive(node: TreeNode, depth: int, out: PackedStrin
5656

5757
if node.next:
5858
generate_text_recursive(node.next, depth, out)
59-
60-
61-
static func generate_script_from_nodes(nodes: Array[Node], bsd: BlockScriptData) -> String:
62-
var entry_blocks_by_entry_statement: Dictionary = {}
63-
64-
for block in nodes:
65-
if !(block is Block):
66-
continue
67-
68-
if block is EntryBlock:
69-
var entry_statement = block.get_entry_statement()
70-
if not entry_blocks_by_entry_statement.has(entry_statement):
71-
entry_blocks_by_entry_statement[entry_statement] = []
72-
entry_blocks_by_entry_statement[entry_statement].append(block)
73-
74-
var script: String = ""
75-
76-
script += "extends %s\n\n" % bsd.script_inherits
77-
78-
for variable in bsd.variables:
79-
script += "var %s: %s\n\n" % [variable.var_name, type_string(variable.var_type)]
80-
81-
script += "\n"
82-
83-
var init_func = TreeNode.new("func _init():")
84-
85-
for entry_statement in entry_blocks_by_entry_statement:
86-
var entry_blocks: Array[EntryBlock]
87-
entry_blocks.assign(entry_blocks_by_entry_statement[entry_statement])
88-
script += _generate_script_from_entry_blocks(entry_statement, entry_blocks, init_func)
89-
90-
if init_func.children:
91-
script += generate_text(init_func)
92-
93-
return script
94-
95-
96-
static func _generate_script_from_entry_blocks(entry_statement: String, entry_blocks: Array[EntryBlock], init_func: TreeNode) -> String:
97-
var script = entry_statement + "\n"
98-
var signal_node: TreeNode
99-
var is_empty = true
100-
101-
IDHandler.reset()
102-
103-
for entry_block in entry_blocks:
104-
var next_block := entry_block.bottom_snap.get_snapped_block()
105-
106-
if next_block != null:
107-
var instruction_node: TreeNode = next_block.get_instruction_node()
108-
var to_append := generate_text(instruction_node, 1)
109-
script += to_append
110-
script += "\n"
111-
is_empty = false
112-
113-
if signal_node == null and entry_block.signal_name:
114-
signal_node = TreeNode.new("{0}.connect(_on_{0})".format([entry_block.signal_name]))
115-
116-
if signal_node:
117-
init_func.add_child(signal_node)
118-
119-
if is_empty:
120-
script += "\tpass\n\n"
121-
122-
return script
123-
124-
125-
## Returns the scope of the first non-empty scope child block
126-
static func get_tree_scope(node: Node) -> String:
127-
if node is Block:
128-
if node.scope != "":
129-
return node.scope
130-
131-
for c in node.get_children():
132-
var scope := get_tree_scope(c)
133-
if scope != "":
134-
return scope
135-
return ""

addons/block_code/ui/block_canvas/block_canvas.gd

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
extends MarginContainer
33

44
const BlockCodePlugin = preload("res://addons/block_code/block_code_plugin.gd")
5+
const BlockTreeUtil = preload("res://addons/block_code/ui/block_tree_util.gd")
56
const DragManager = preload("res://addons/block_code/drag_manager/drag_manager.gd")
67
const InstructionTree = preload("res://addons/block_code/instruction_tree/instruction_tree.gd")
78
const Util = preload("res://addons/block_code/ui/util.gd")
@@ -219,7 +220,7 @@ func set_scope(scope: String):
219220
if scope == block.get_entry_statement():
220221
valid = true
221222
else:
222-
var tree_scope := InstructionTree.get_tree_scope(block)
223+
var tree_scope := BlockTreeUtil.get_tree_scope(block)
223224
if tree_scope == "" or scope == tree_scope:
224225
valid = true
225226

@@ -321,4 +322,4 @@ func set_mouse_override(override: bool):
321322

322323
func generate_script_from_current_window(bsd: BlockScriptData) -> String:
323324
# TODO: implement multiple windows
324-
return InstructionTree.generate_script_from_nodes(_window.get_children(), bsd)
325+
return BlockTreeUtil.generate_script_from_nodes(_window.get_children(), bsd)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
extends Object
2+
3+
const InstructionTree = preload("res://addons/block_code/instruction_tree/instruction_tree.gd")
4+
5+
6+
static func generate_script_from_nodes(nodes: Array[Node], bsd: BlockScriptData) -> String:
7+
var entry_blocks_by_entry_statement: Dictionary = {}
8+
9+
for block in nodes:
10+
if !(block is Block):
11+
continue
12+
13+
if block is EntryBlock:
14+
var entry_statement = block.get_entry_statement()
15+
if not entry_blocks_by_entry_statement.has(entry_statement):
16+
entry_blocks_by_entry_statement[entry_statement] = []
17+
entry_blocks_by_entry_statement[entry_statement].append(block)
18+
19+
var script: String = ""
20+
21+
script += "extends %s\n\n" % bsd.script_inherits
22+
23+
for variable in bsd.variables:
24+
script += "var %s: %s\n\n" % [variable.var_name, type_string(variable.var_type)]
25+
26+
script += "\n"
27+
28+
var init_func = InstructionTree.TreeNode.new("func _init():")
29+
30+
for entry_statement in entry_blocks_by_entry_statement:
31+
var entry_blocks: Array[EntryBlock]
32+
entry_blocks.assign(entry_blocks_by_entry_statement[entry_statement])
33+
script += _generate_script_from_entry_blocks(entry_statement, entry_blocks, init_func)
34+
35+
if init_func.children:
36+
script += InstructionTree.generate_text(init_func)
37+
38+
return script
39+
40+
41+
static func _generate_script_from_entry_blocks(entry_statement: String, entry_blocks: Array[EntryBlock], init_func: InstructionTree.TreeNode) -> String:
42+
var script = entry_statement + "\n"
43+
var signal_node: InstructionTree.TreeNode
44+
var is_empty = true
45+
46+
InstructionTree.IDHandler.reset()
47+
48+
for entry_block in entry_blocks:
49+
var next_block := entry_block.bottom_snap.get_snapped_block()
50+
51+
if next_block != null:
52+
var instruction_node: InstructionTree.TreeNode = next_block.get_instruction_node()
53+
var to_append := InstructionTree.generate_text(instruction_node, 1)
54+
script += to_append
55+
script += "\n"
56+
is_empty = false
57+
58+
if signal_node == null and entry_block.signal_name:
59+
signal_node = InstructionTree.TreeNode.new("{0}.connect(_on_{0})".format([entry_block.signal_name]))
60+
61+
if signal_node:
62+
init_func.add_child(signal_node)
63+
64+
if is_empty:
65+
script += "\tpass\n\n"
66+
67+
return script
68+
69+
70+
## Returns the scope of the first non-empty scope child block
71+
static func get_tree_scope(node: Node) -> String:
72+
if node is Block:
73+
if node.scope != "":
74+
return node.scope
75+
76+
for c in node.get_children():
77+
var scope := get_tree_scope(c)
78+
if scope != "":
79+
return scope
80+
return ""

tests/test_instruction_tree.gd

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
extends GutTest
22
## Tests for InstructionTree
33

4+
const BlockTreeUtil = preload("res://addons/block_code/ui/block_tree_util.gd")
45
const CategoryFactory = preload("res://addons/block_code/ui/picker/categories/category_factory.gd")
56
const InstructionTree = preload("res://addons/block_code/instruction_tree/instruction_tree.gd")
67

@@ -88,7 +89,7 @@ func test_tree_node_text():
8889

8990
func test_script_no_nodes():
9091
var bsd := BlockScriptData.new("Foo")
91-
var script := InstructionTree.generate_script_from_nodes([], bsd)
92+
var script := BlockTreeUtil.generate_script_from_nodes([], bsd)
9293
assert_eq(
9394
script,
9495
(
@@ -105,7 +106,7 @@ func test_script_no_nodes():
105106
func test_script_no_entry_blocks():
106107
var bsd := BlockScriptData.new("Foo")
107108
var nodes: Array[Node] = [Node.new(), Node2D.new(), Control.new()]
108-
var script := InstructionTree.generate_script_from_nodes(nodes, bsd)
109+
var script := BlockTreeUtil.generate_script_from_nodes(nodes, bsd)
109110
assert_eq(
110111
script,
111112
(
@@ -137,7 +138,7 @@ func test_basic_script():
137138
assert_eq(ready_block.bottom_snap.get_snapped_block(), print_block)
138139

139140
var bsd := BlockScriptData.new("Node2D")
140-
var script := InstructionTree.generate_script_from_nodes([ready_block], bsd)
141+
var script := BlockTreeUtil.generate_script_from_nodes([ready_block], bsd)
141142
assert_eq(
142143
script,
143144
(
@@ -165,7 +166,7 @@ func test_multiple_entry_script():
165166
var ready_block_2: Block = dup_node(ready_block)
166167

167168
var bsd := BlockScriptData.new("Node2D")
168-
var script := InstructionTree.generate_script_from_nodes([ready_block, ready_block_2], bsd)
169+
var script := BlockTreeUtil.generate_script_from_nodes([ready_block, ready_block_2], bsd)
169170
assert_eq(
170171
script,
171172
(
@@ -196,7 +197,7 @@ func test_signal_script():
196197
entered_block.bottom_snap.snapped_block = print_block
197198

198199
var bsd := BlockScriptData.new("Area2D")
199-
var script = InstructionTree.generate_script_from_nodes([entered_block], bsd)
200+
var script = BlockTreeUtil.generate_script_from_nodes([entered_block], bsd)
200201
assert_eq(
201202
script,
202203
(

0 commit comments

Comments
 (0)