using Godot; using System.Collections.Generic; public partial class CodingWindow : PanelContainer { private Robot robot; [Export] VBoxContainer codeBlocks; [Export] VBoxContainer editorWindow; [Export] OptionButton availableScripts; [Export] LineEdit scriptName; [Export] LineEdit nameInput; public Dictionary DSLNodes; public override void _Ready() { DSLNodes = ResourceLoader.LoadDSLNodes(); GenerateCodingBlocks(); } public override void _Notification(int id) { if (id == NotificationVisibilityChanged) { if (Visible) LoadWindow(); } } private void LoadWindow() { if (robot == null) return; nameInput.Text = robot.Name; SetupScriptOptions(); ClearWindow(); } private void SetupScriptOptions() { availableScripts.Clear(); availableScripts.AddItem("Select script to load..."); List scripts = FileHandler.LoadProgramNames(); scripts.Sort((a, b) => a.CompareTo(b)); foreach (string script in scripts) { availableScripts.AddItem(script); } } public void SaveRobotName() { if (robot == null) return; robot.Name = nameInput.Text; } public void CloseWindow() { Hide(); } public void GenerateCodingBlocks() { NodeDisplay nodeDisplay; foreach (ProgramNode nodeTemplate in DSLNodes.Keys) { nodeDisplay = DSLNodes[nodeTemplate].Instantiate(); nodeDisplay.node = nodeTemplate; codeBlocks.AddChild(nodeDisplay); nodeDisplay.ShowListDisplay(); nodeDisplay.listDisplay.Pressed += () => { AddEditorNode(DSLNodes[nodeTemplate], nodeTemplate.Duplicate()); }; } } private void AddEditorNode(PackedScene prefab, ProgramNode node) { NodeDisplay editorDisplay = prefab.Instantiate(); editorDisplay.node = node; editorWindow.AddChild(editorDisplay); editorDisplay.ShowEditorDisplay(); editorDisplay.OnDeleteNode += () => { editorWindow.RemoveChild(editorDisplay); editorDisplay.QueueFree(); }; } public void ClearWindow() { foreach (Node node in editorWindow.GetChildren()) { editorWindow.RemoveChild(node); node.QueueFree(); } scriptName.Text = ""; } public void CompileProgram() { List nodes = new List(); for (int i = 0; i < editorWindow.GetChildCount(); i++) { NodeDisplay nodeDisplay = editorWindow.GetChild(i); nodeDisplay.node.ReadParameters(nodeDisplay); nodes.Add(nodeDisplay.node.Duplicate()); if (i != 0) { nodes[i - 1].nextNode = nodes[i]; } if (i > 0) { nodes[i].previousNode = nodes[i-1]; } } if (robot == null) return; if (nodes.Count > 0) robot.SetupExecution(nodes); robot.currentProgram = scriptName.Text.Length <= 0 ? $"Script{availableScripts.ItemCount}" : scriptName.Text; } public void SetRobot(Robot robot) { this.robot = robot; } public void LoadProgram(int index) { ClearWindow(); string scriptContent = FileHandler.LoadProgram(availableScripts.GetItemText(index)); string[] nodes = scriptContent.Split(";"); foreach (string node in nodes) { NodeDisplay nodeDisplay = NodeDisplay.Load(node, DSLNodes); if (nodeDisplay != null) { editorWindow.AddChild(nodeDisplay); nodeDisplay.ShowEditorDisplay(); nodeDisplay.OnDeleteNode += () => { editorWindow.RemoveChild(nodeDisplay); nodeDisplay.QueueFree(); }; } } scriptName.Text = availableScripts.GetItemText(index); availableScripts.Select(0); } public void SaveProgram() { string result = ""; for (int i = 0; i < editorWindow.GetChildCount(); i++) { NodeDisplay nodeDisplay = editorWindow.GetChild(i); nodeDisplay.node.ReadParameters(nodeDisplay); result += nodeDisplay.node.Save(); result += ";\r\n"; } if (result.Length <= 0) return; string filename = scriptName.Text.Length <= 0 ? $"Script{availableScripts.ItemCount}" : scriptName.Text; FileHandler.SaveProgram(filename, result); SetupScriptOptions(); } }