static BTLGUILine GenerateCommentLineGui(string lineContent, int indent, int lineNumber) { var commentGUILine = new BTLGUILine(); commentGUILine.indent = indent; commentGUILine.lineNumber = lineNumber; string tabs = ""; for (int i = 0; i < indent; ++i) { tabs += "\t"; } string cleaned = lineContent; if (tabs != "") { cleaned = cleaned.Replace(tabs, ""); } cleaned = cleaned.Replace("\t", " "); var token = GenerateCommentToken(cleaned, lineNumber); commentGUILine.tokens.Add(token); return(commentGUILine); }
private void GUI_tokens(BTLGUILine line) { GUIStyle style = BTLSyntaxHighlight.style_label; for (int i = 0; i < line.tokens.Count; ++i) { BTNode node = null; if (i < line.btnodes.Count) { node = line.btnodes[i]; } var token = line.tokens[i]; style = BTLSyntaxHighlight.GetTokenStyle(token); if (bt.program == null || bt.program.codemaps == null) { style = BTLSyntaxHighlight.style_comment; } if (bt.exceptions.Length > 0) { style = BTLSyntaxHighlight.style_comment; } if (line.hasErrors) { style = BTLSyntaxHighlight.style_failed; } GUI_token(style, node, token); }// for tokens }
// Map each token to its corresponding node. public static void MapNodes(BTLGUILine line, CodeMap codemap) { line.btnodes.Clear(); for (int t = 0; t < line.tokens.Count; ++t) { line.btnodes.Add(null); } for (int t = 0; t < line.tokens.Count; ++t) { var token = line.tokens[t]; if (token.type == BTLTokenizer.TokenType.Comment) { continue; } for (int n = 0; n < codemap.nodes.Length; ++n) { var node = codemap.nodes[n]; var nodeLoc = codemap.substringLocations[n]; if ( nodeLoc.start <= token.substring_start && (token.substring_start + token.substring_length) <= (nodeLoc.start + nodeLoc.length) ) { line.btnodes[t] = node; break; } } } }
void RenderLine(BTLGUILine line) { GUILayout.BeginHorizontal(); GUI_lineNumber(line); GUI_indentation(line); if (bt.program != null && bt.program.codemaps != null && SourceDisplay.isPlaying && bt.program.exceptions.Length == 0) { GUI_tokens_live(line); } else { GUI_tokens(line); } GUILayout.EndHorizontal(); }
private void GUI_tokens_live(BTLGUILine line) { GUIStyle style = BTLSyntaxHighlight.style_label; for (int i = 0; i < line.tokens.Count; ++i) { BTNode node = null; if (i < line.btnodes.Count) { node = line.btnodes[i]; } var token = line.tokens[i]; style = BTLSyntaxHighlight.GetTokenStyle(token); if (node != null) { var nodeStyle = GetNodeStyle(node); if (nodeStyle != null) { style = nodeStyle; } } if (bt.exceptions.Length > 0) { style = BTLSyntaxHighlight.style_comment; } if (line.hasErrors) { style = BTLSyntaxHighlight.style_failed; } GUI_token(style, node, token); // debug info bool isLastNodeToken = node != null && (i + 1 >= line.btnodes.Count || node != line.btnodes[i + 1]); if (isLastNodeToken && node.debugInfo != null && node.debugInfo != "") { GUILayout.Label(string.Format("[{0}]", node.debugInfo.Replace("\t", " ")), BTLSyntaxHighlight.style_comment); } }// for tokens }
private bool HasBeenTickedOnThisFrame(BTLGUILine line) { bool hasBeenTickedOnThisFrame = false; if (line.btnodes != null) { foreach (var n in line.btnodes) { hasBeenTickedOnThisFrame = n != null && bt.program != null && bt.status != Status.Ready && n.lastTick == bt.program.tickCount; if (hasBeenTickedOnThisFrame) { break; } } } return(hasBeenTickedOnThisFrame); }
private static bool ContainsLeafNodes(BTLGUILine line) { bool containsLeafNode = false; if (line.btnodes != null) { foreach (var n in line.btnodes) { if (n == null) { continue; } if (n.GetType() == typeof(BTTask) || n.GetType() == typeof(BTTreeProxy)) { containsLeafNode = true; break; } } } return(containsLeafNode); }
private static void GUI_indentation(BTLGUILine line) { string strIndent = ""; for (int i = 0; i < line.indent + (line.isFoldable ? 0 : 1); i++) { strIndent += " "; } { //style.normal.textColor = hiddenColor; GUILayout.Label(strIndent, BTLSyntaxHighlight.style_label); } //style.normal.textColor = BTLSyntaxHighlight.guiColor; if (line.isFoldable) { // line.isFoldout = GUILayout.Toggle(line.isFoldout, line.isFoldout ? "[+]" : "[-]", style); if (GUILayout.Button(" ", line.isFoldout ? BTLSyntaxHighlight.style_INFoldout : BTLSyntaxHighlight.style_INFoldin)) { line.isFoldout = !line.isFoldout; } } }
private static void ParentOrAddToLines(List <BTLGUILine> lines, Stack <BTLGUILine> parentStack, BTLGUILine current) { if (current.tokens.Count > 0) { while (parentStack.Count > 0 && parentStack.Peek().indent >= current.indent) { parentStack.Pop(); } } if (parentStack.Count > 0 && !parentStack.Peek().children.Contains(current)) { parentStack.Peek().children.Add(current); } else { if (!lines.Contains(current)) { lines.Add(current); } } }
public static SourceDisplay Analyse(BTLTokenizer.Token[] tokens, int sourceIndex) { if (tokens == null) { return(null); } SourceDisplay sourceDisplay = new SourceDisplay(sourceIndex); int lineNumber = 1; var lines = new List <BTLGUILine>(); var orphans = new List <BTLGUILine>(); var parentStack = new Stack <BTLGUILine>(); BTLGUILine current = new BTLGUILine(); current.lineNumber = lineNumber; foreach (var t in tokens) { bool isComment = current.tokens.Count > 0 && current.tokens[0].type == BTLTokenizer.TokenType.Comment; if (t.type == BTLTokenizer.TokenType.EOL && current.tokens.Count == 0) {// Empty line orphans.Add(current); ++lineNumber; current = new BTLGUILine(); current.indent = 0; current.lineNumber = lineNumber; } else if (t.type == BTLTokenizer.TokenType.EOL && isComment) {// End of comments ++lineNumber; orphans.Add(current); current = new BTLGUILine(); current.indent = 0; current.lineNumber = lineNumber; } else if (t.type == BTLTokenizer.TokenType.EOL && !isComment) {// End of line containing nodes ++lineNumber; ParentOrAddToLines(lines, parentStack, current); if (current.tokens.Count > 0) { parentStack.Push(current); } current = new BTLGUILine(); current.indent = 0; current.lineNumber = lineNumber; } else if (t.type == BTLTokenizer.TokenType.Indent && current.tokens.Count == 0) { current.indent++; } else if (t.type == BTLTokenizer.TokenType.Comment) { var commentLines = t.content.Split('\n'); if (commentLines.Length > 0) { current.tokens.Add(GenerateCommentToken(commentLines[0], current.lineNumber)); for (int i = 1; i < commentLines.Length; ++i) { ++lineNumber; var commentline = commentLines[i]; var commentGUILine = GenerateCommentLineGui(commentline, current.indent, lineNumber); current.children.Add(commentGUILine); } } } else { current.tokens.Add(t); } } ParentOrAddToLines(lines, parentStack, current); sourceDisplay.lines = lines.ToArray(); sourceDisplay.orphans = orphans.ToArray(); ProcessFoldable(sourceDisplay.lines); ProcessFoldable(sourceDisplay.orphans); return(sourceDisplay); }
public static SourceDisplay[] MapGUILines(BTSource[] btlSources, BTProgram program, PandaScriptException[] pandaExceptions) { if (btlSources == null || program == null) { return(null); } var sourceDisplays = new SourceDisplay[btlSources.Length]; for (int i = 0; i < btlSources.Length; i++) { if (btlSources[i] == null) { continue; } SourceDisplay sourceDisplay = null; var tokens = BTLAssetManager.GetBTLTokens(btlSources, btlSources[i]); sourceDisplay = BTLGUILine.Analyse(tokens, i); sourceDisplays[i] = sourceDisplay; CodeMap codemap = null; if (program.codemaps != null && i < program.codemaps.Length) { codemap = program.codemaps[i]; } if (codemap != null) { BTLGUILine.MapNodes(sourceDisplay.lines, codemap); var lines = sourceDisplay.flattenLines; foreach (var line in lines) { foreach (var n in line.btnodes) { var task = n as BTTask; if (task != null && task.boundState != BoundState.Bound) { line.hasErrors = true; } } } } if (sourceDisplay != null) { var lines = sourceDisplay.flattenLines; foreach (var line in lines) { foreach (var pandaException in pandaExceptions) { if (pandaException != null) { if (pandaException.filePath == btlSources[i].url && line.lineNumber == pandaException.lineNumber) { line.hasErrors = true; } } } } } } return(sourceDisplays); }
private void GUI_lineNumber(BTLGUILine line) { // Determine whether the lines contains a node that has been ticked on this frame. bool hasBeenTickedOnThisFrame = HasBeenTickedOnThisFrame(line); bool containsLeafNode = hasBeenTickedOnThisFrame ? ContainsLeafNodes(line) : false; var lineNumberStyle = BTLSyntaxHighlight.style_lineNumber; #if !PANDA_BT_FREE bool isActive = hasBeenTickedOnThisFrame && (containsLeafNode || line.isFoldout) && !line.isBreakPointEnable; #else bool isActive = hasBeenTickedOnThisFrame && (containsLeafNode || line.isFoldout); #endif if (isActive) { lineNumberStyle = BTLSyntaxHighlight.style_lineNumber_active; } #if !PANDA_BT_FREE if (line.isBreakPointEnable) { if (hasBeenTickedOnThisFrame && isPaused && line.isBreakPointActive) { lineNumberStyle = BTLSyntaxHighlight.style_breakpoint_active; } else { switch (line.breakPointStatus) { case Status.Running: lineNumberStyle = BTLSyntaxHighlight.style_breakpoint_set_running; break; case Status.Succeeded: lineNumberStyle = BTLSyntaxHighlight.style_breakpoint_set_succeeded; break; case Status.Failed: lineNumberStyle = BTLSyntaxHighlight.style_breakpoint_set_failed; break; default: lineNumberStyle = BTLSyntaxHighlight.style_breakpoint_set_running; break; } } } #endif if (line.hasErrors) { lineNumberStyle = BTLSyntaxHighlight.style_lineNumber_error; } #if UNITY_EDITOR && !PANDA_BT_FREE if (line.btnodes != null && line.btnodes.Count > 0) { if (GUILayout.Button(line.lineNumberText, lineNumberStyle)) { if (Event.current.button == 0) { line.ToggleBreakPoint(); } else if (Event.current.button == 1) { line.ClearBreakPoint(); } var breakPoints = bt.sourceInfos[scriptIndex].breakPoints; var breakPointStatuses = bt.sourceInfos[scriptIndex].breakPointStatuses; bool isDirty = true; while (isDirty) { isDirty = false; for (int i = 0; i < breakPoints.Count; ++i) { if (breakPoints[i] == line.lineNumber) { breakPoints.RemoveAt(i); breakPointStatuses.RemoveAt(i); isDirty = true; break; } } } if (line.isBreakPointEnable) { breakPoints.Add(line.lineNumber); breakPointStatuses.Add(line.breakPointStatus); } } } else { GUILayout.Label(line.lineNumberText, lineNumberStyle); } #else GUILayout.Label(line.lineNumberText, lineNumberStyle); #endif }