// lineNumber == -1 signifies no line number public void Init(int lineNumber, Instruction instruction, Divider myDivider) { base.Init(myDivider); this.lineNumber = lineNumber; this.instruction = instruction; draggable.onDragSuccess = (Draggable.Slot slot) => { Insert(slot); // Reset frontend Destroy(gameObject); Globals.program.BroadcastInstructionChange(); }; draggable.onDragTrash = (Draggable.Slot slot) => { if (lineNumber != -1) { Remove(); Globals.program.BroadcastInstructionChange(); } Destroy(gameObject); }; // Configure text opCodeTM.text = instruction.opCode.ToString(); // Configure color OpCategory category = InstructionMaps.opCodeOpCategoryMap[instruction.opCode]; bg.color = opCategoryColorMap.map[category]; // Create argument fields ArgumentSpec[] argSpecs = InstructionMaps.opArgSpecMap[instruction.opCode]; for (int argNum = 0; argNum < instruction.args.Length; ++argNum) { GameObject field; Argument arg = instruction.args[argNum]; if (argSpecs[argNum].regOnly || argSpecs[argNum].presets != null) { field = Instantiate(dropdownFieldPrefab, transform); field.GetComponent <DropdownField>().Init(argSpecs[argNum], arg); } else { field = Instantiate(slotFieldPrefab, transform); field.GetComponent <SlotField>().Init(arg); } // Add header // GameObject header = Instantiate(headerPrefab, field.transform); // header.GetComponent<TextMeshProUGUI>().text = argSpecs[argNum].name; } }
void Start() { cg.blocksRaycasts = initialCGBlocksRaycasts; Globals.Reset(); Program program = Globals.program; // Create code block for each instruction in program instructionBlockTransforms = new Transform[program.instructions.Count]; int lineNumber = 0; int nextLabelIndex = 0; foreach (Instruction instruction in program.instructions) { // Create any labels for the current line while (nextLabelIndex < program.branchLabelList.Count && program.branchLabelList[nextLabelIndex].val == lineNumber) { CreateLabel(ref nextLabelIndex); } // Create divider Divider divider = Instantiate(dividerPrefab, transform, false).GetComponent <Divider>(); divider.Init(lineNumber); Globals.dividers.Add(divider); // Create code block GameObject instructionBlock = Instantiate(instructionBlockPrefab, transform, false); instructionBlock.GetComponent <InstructionBlock>().Init(lineNumber, instruction, divider); instructionBlockTransforms[lineNumber] = instructionBlock.transform; ++lineNumber; } // Create any remaining labels while (nextLabelIndex < program.branchLabelList.Count) { CreateLabel(ref nextLabelIndex); } // Create end divider Divider endDivider = Instantiate(dividerPrefab, transform, false).GetComponent <Divider>(); endDivider.Init(lineNumber); Globals.dividers.Add(endDivider); OnRectTransformDimensionsChange(); HandleTick(); }
private void CreateLabel(ref int nextLabelIndex) { Label label = Program.branchLabelList[nextLabelIndex]; Divider labelDivider = Instantiate(dividerPrefab, transform, false).GetComponent <Divider>(); labelDivider.Init(label.val, label); Dividers.Add(labelDivider); // TODO: Need to test on bad devices to see if there's a performance hit when the code list is reset // NOTE: Maybe if there is, we can use pooling and continue to do a full reset GameObject labelBlock = Instantiate(labelBlockPrefab, transform, false); labelBlock.GetComponent <LabelBlock>().Init(label, labelDivider, this); ++nextLabelIndex; }
private void Generate() { cg.blocksRaycasts = initialCGBlocksRaycasts; Dividers.Clear(); SlotFields.Clear(); // Create code block for each instruction in program instructionBlockTransforms = new Transform[Program.instructions.Count]; int lineNumber = 0; int nextLabelIndex = 0; foreach (Instruction instruction in Program.instructions) { // Create any labels for the current line while (nextLabelIndex < Program.branchLabelList.Count && Program.branchLabelList[nextLabelIndex].val == lineNumber) { CreateLabel(ref nextLabelIndex); } // Create divider Divider divider = Instantiate(dividerPrefab, transform, false).GetComponent <Divider>(); divider.Init(lineNumber); Dividers.Add(divider); // Create code block GameObject instructionBlock = Instantiate(instructionBlockPrefab, transform, false); instructionBlock.GetComponent <InstructionBlock>().Init(lineNumber, instruction, divider, this); instructionBlockTransforms[lineNumber] = instructionBlock.transform; ++lineNumber; } // Create any remaining labels while (nextLabelIndex < Program.branchLabelList.Count) { CreateLabel(ref nextLabelIndex); } // Create end divider Divider endDivider = Instantiate(dividerPrefab, transform, false).GetComponent <Divider>(); endDivider.Init(lineNumber); Dividers.Add(endDivider); OnRectTransformDimensionsChange(); }
private void Move(Draggable.Slot slot) { Divider targetDivider = (Divider)slot; int oldLineNumber = label.val; int newLineNumber = targetDivider.lineNumber; label.val = newLineNumber; // Remove old entry codeList.Program.branchLabelList.Remove(label); // Find new entry int insertionIndex = 0; for (int i = 0; i < codeList.Program.branchLabelList.Count; ++i) { Label l = codeList.Program.branchLabelList[i]; if (l.val > label.val) { break; } else if (l.val < label.val) { insertionIndex = i + 1; } else if (l.val == label.val) { if (l == targetDivider.label) { insertionIndex = i; break; } else { insertionIndex = i + 1; } } } codeList.Program.branchLabelList.Insert(insertionIndex, label); codeList.Program.BroadcastBranchLabelChange(); // Reset frontend Destroy(gameObject); }
public void Init(Label label, Divider myDivider, CodeList codeList) { base.Init(myDivider, codeList); this.label = label; string labelText = label.name + " (" + label.val + ")"; GetComponentInChildren <TextMeshProUGUI>().text = labelText; Draggable draggable = GetComponent <Draggable>(); draggable.onDragSuccess = Move; draggable.onDragTrash = (Draggable.Slot slot) => { codeList.Program.RemoveLabel(label); Destroy(gameObject); }; }
public void Init(Divider myDivider) { this.myDivider = myDivider; draggable.Init(Globals.dividers, Globals.trashSlots); draggable.filterFunc = (Draggable.Slot slot) => slot == myDivider; draggable.onDragStart = () => { myDivider?.gameObject.SetActive(false); bg.raycastTarget = false; cg.blocksRaycasts = false; rt.sizeDelta = new Vector2(collapsedWidth, rt.sizeDelta.y); }; draggable.onDragEnd = () => { myDivider?.gameObject.SetActive(true); bg.raycastTarget = true; cg.blocksRaycasts = true; }; }
protected void Init(Divider myDivider, CodeList codeList) { this.myDivider = myDivider; this.codeList = codeList; draggable.Init(codeList.Dividers, codeList.TrashSlots); draggable.filterFunc = (Draggable.Slot slot) => slot == myDivider; draggable.onDragStart = () => { myDivider?.gameObject.SetActive(false); bg.raycastTarget = false; cg.blocksRaycasts = false; rt.sizeDelta = new Vector2(collapsedWidth, rt.sizeDelta.y); }; draggable.onDragEnd = () => { myDivider?.gameObject.SetActive(true); bg.raycastTarget = true; cg.blocksRaycasts = true; }; }
private void Insert(Draggable.Slot slot) { Divider targetDivider = (Divider)slot; int newLineNumber = targetDivider.lineNumber; int adjustedNewLineNumber; if (lineNumber != -1) { // Remove old instruction Remove(); adjustedNewLineNumber = newLineNumber > lineNumber ? newLineNumber - 1 : newLineNumber; } else { adjustedNewLineNumber = newLineNumber; } // Insert new instruction Globals.program.instructions.Insert(adjustedNewLineNumber, instruction); // Adjust labels bool crossed = false; foreach (Label label in Globals.program.branchLabelList) { if (targetDivider.label == label) { crossed = true; } if (crossed || adjustedNewLineNumber < label.val) { ++label.val; // TODO: This will need to be variable when we add dragging selected blocks } } }