From 588a0bcbec621ff1f74211b48a0415ce3022198e Mon Sep 17 00:00:00 2001 From: Bram Dingelstad Date: Mon, 6 Dec 2021 21:14:30 +0100 Subject: [PATCH] Made connections visible --- addons/Wol/core/compiler/Parser.gd | 9 ++++---- addons/Wol/editor/WolEditor.gd | 32 +++++++++++++++++++++++++++- addons/Wol/editor/WolGraphNode.gd | 34 ++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/addons/Wol/core/compiler/Parser.gd b/addons/Wol/core/compiler/Parser.gd index b227af1..4beacbd 100644 --- a/addons/Wol/core/compiler/Parser.gd +++ b/addons/Wol/core/compiler/Parser.gd @@ -25,7 +25,8 @@ func parse_node(): return WolNode.new('Start', null, self) func next_symbol_is(valid_types): - return tokens.front().type in valid_types + compiler.assert(tokens.size() != 0, 'Ran out of tokens!') + return tokens.front() and tokens.front().type in valid_types # NOTE: 0 look ahead for `<<` and `else` func next_symbols_are(valid_types): @@ -233,7 +234,7 @@ class FormatFunctionNode extends ParseNode: parser.expect_symbol([Constants.TokenType.FormatFunctionStart]) # FIXME: Add exit condition in case of failure - while not parser.next_symbol_is([Constants.TokenType.FormatFunctionEnd]): + while parser.tokens.size() > 0 and not parser.next_symbol_is([Constants.TokenType.FormatFunctionEnd]): if parser.next_symbol_is([Constants.TokenType.Text]): format_text += parser.expect_symbol().value @@ -328,7 +329,7 @@ class CustomCommand extends ParseNode: command_tokens.append(parser.expect_symbol()) # FIXME: add exit condition - while not parser.next_symbol_is([Constants.TokenType.EndCommand]): + while parser.tokens.size() > 0 and not parser.next_symbol_is([Constants.TokenType.EndCommand]): command_tokens.append(parser.expect_symbol()) parser.expect_symbol([Constants.TokenType.EndCommand]) @@ -451,7 +452,7 @@ class Block extends ParseNode: #keep reading statements until we hit a dedent # FIXME: find exit condition - while not parser.next_symbol_is([Constants.TokenType.Dedent]): + while parser.tokens.size() > 0 and not parser.next_symbol_is([Constants.TokenType.Dedent]): #parse all statements including nested blocks statements.append(Statement.new(self, parser)) diff --git a/addons/Wol/editor/WolEditor.gd b/addons/Wol/editor/WolEditor.gd index 08a2c66..0479984 100644 --- a/addons/Wol/editor/WolEditor.gd +++ b/addons/Wol/editor/WolEditor.gd @@ -5,6 +5,7 @@ const Compiler = preload('res://addons/Wol/core/compiler/Compiler.gd') onready var GraphNodeTemplate = $GraphNodeTemplate var path +var refreshed = false func _ready(): for menu_button in [$Menu/File]: @@ -19,9 +20,12 @@ func build_nodes(): for node in Compiler.new(path).get_nodes(): var graph_node = GraphNodeTemplate.duplicate() $GraphEdit.add_child(graph_node) + + graph_node.connect('recompiled', self, '_on_graph_node_recompiled', [graph_node]) + graph_node.connect('gui_input', self, '_on_graph_node_input', [graph_node, node]) + graph_node.node = node graph_node.show() - graph_node.connect('gui_input', self, '_on_graph_node_input', [graph_node, node]) func serialize_to_file(): var buffer = [] @@ -93,6 +97,32 @@ func _on_menu_pressed(index, node): 'Open': open() +# FIXME: Come up with better way of showing connections between nodes +func _on_graph_node_recompiled(_graph_node): + if refreshed: return + $GraphEdit.clear_connections() + for graph_node in $GraphEdit.get_children(): + if not graph_node is GraphNode: + continue + + var connections = graph_node.get_connections() + graph_node.set_slot_enabled_right(0, connections.size() != 0) + graph_node.set_slot_type_right(0, 1) + + for connection in connections: + if not $GraphEdit.has_node(connection): + continue + + var other_graph_node = $GraphEdit.get_node(connection) + other_graph_node.set_slot_enabled_left(0, true) + other_graph_node.set_slot_type_left(0, 1) + + $GraphEdit.connect_node(graph_node.name, 0, connection, 0) + + refreshed = true + yield(get_tree().create_timer(.3), 'timeout') + refreshed = false + func _on_graph_node_input(event, graph_node, node): if event is InputEventMouseButton \ and event.doubleclick and event.button_index == BUTTON_LEFT: diff --git a/addons/Wol/editor/WolGraphNode.gd b/addons/Wol/editor/WolGraphNode.gd index 1ef08c3..c34992a 100644 --- a/addons/Wol/editor/WolGraphNode.gd +++ b/addons/Wol/editor/WolGraphNode.gd @@ -4,11 +4,13 @@ extends GraphNode signal recompiled const Compiler = preload('res://addons/Wol/core/compiler/Compiler.gd') +const Constants = preload('res://addons/Wol/core/Constants.gd') var node setget set_node var error_lines = [] var compiler +var program onready var text_edit = $TextEdit @@ -18,7 +20,32 @@ func _ready(): $TextDebounce.connect('timeout', self, '_on_debounce') func get_connections(): - print(compiler) + # NOTE: Program failed to compile + if not program: + return [] + + var program_node = program.nodes.values().front() + var connections = [] + + # FIXME: Don't rely on checking on 'Label\d' + var label_check = RegEx.new() + label_check.compile('^Label\\doption_\\d') + + for instruction in program_node.instructions: + # NOTE: When next node is explicit + if instruction.operation == Constants.ByteCode.RunNode: + if instruction.operands.size() > 0 \ + and instruction.operands.front().value != name: + connections.append(instruction.operands.front().value) + + # NOTE: When next node is decided through options + if instruction.operation == Constants.ByteCode.AddOption: + if instruction.operands.size() == 2 \ + and not label_check.search(instruction.operands[1].value) \ + and instruction.operands[1].value != name: + connections.append(instruction.operands[1].value) + + return connections func _on_text_changed(): $TextDebounce.start(.3) @@ -45,6 +72,7 @@ func _on_error(message, line_number, _column): func set_node(_node): node = _node title = node.title + name = node.title text_edit.text = node.body text_edit.clear_undo_history() offset = node.position @@ -55,5 +83,7 @@ func compile(): var text = '---\n%s\n===' % text_edit.text compiler = Compiler.new(null, text, true) compiler.connect('error', self, '_on_error') - compiler.compile() + program = compiler.compile() + + yield(get_tree(), 'idle_frame') emit_signal('recompiled')