private static YarnSpinnerLoader.NodeInfo TreeNodeToYarnNode(MerinoTreeElement treeNode) { var info = new YarnSpinnerLoader.NodeInfo(); info.title = treeNode.name; info.body = treeNode.nodeBody; info.tags = treeNode.nodeTags; var newPosition = new YarnSpinnerLoader.NodeInfo.Position { x = treeNode.nodePosition.x, y = treeNode.nodePosition.y }; info.position = newPosition; if (((MerinoTreeElement)treeNode.parent).leafType != MerinoTreeElement.LeafType.File) { info.parent = treeNode.parent.name; } return(info); }
public static IList <MerinoTreeElement> GetDataFromFile(TextAsset source, int startID = 1, bool useFastMode = false) { var treeElements = new List <MerinoTreeElement>(); if (!useFastMode) { AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(source)); // TODO: only reload assets that need it? how to do that //var format = YarnSpinnerLoader.GetFormatFromFileName(AssetDatabase.GetAssetPath(currentFile)); // TODO: add JSON and ByteCode support? } // ROOT: create a root node for the file itself var fileRoot = new MerinoTreeElement(source.name, 0, startID); fileRoot.leafType = MerinoTreeElement.LeafType.File; fileRoot.children = new List <TreeElement>(); treeElements.Add(fileRoot); if (MerinoData.FileToNodeID.ContainsKey(source)) { MerinoData.FileToNodeID[source] = startID; } else { MerinoData.FileToNodeID.Add(source, startID); } // load nodes // if there's no header sentinel in the text file, then just return an empty list if (!source.text.Contains("---")) { return(treeElements); } // otherwise, load nodes from file var nodes = YarnSpinnerLoader.GetNodesFromText(source.text, NodeFormat.Text); var parents = new Dictionary <MerinoTreeElement, string>(); foreach (var node in nodes) { // clean some of the stuff to help prevent file corruption string cleanName = MerinoUtils.CleanYarnField(node.title, true); string cleanBody = MerinoUtils.CleanYarnField(node.body); string cleanTags = MerinoUtils.CleanYarnField(node.tags, true); string cleanParent = string.IsNullOrEmpty(node.parent) ? "" : MerinoUtils.CleanYarnField(node.parent, true); // write data to the objects var newItem = new MerinoTreeElement(cleanName, 0, startID + treeElements.Count); newItem.nodeBody = cleanBody; newItem.nodePosition = new Vector2Int(node.position.x, node.position.y); newItem.nodeTags = cleanTags; if (string.IsNullOrEmpty(cleanParent) || cleanParent == "Root") { newItem.parent = fileRoot; newItem.cachedParentID = fileRoot.id; fileRoot.children.Add(newItem); } else { parents.Add(newItem, cleanParent); // we have to assign parents in a second pass later on, not right now } treeElements.Add(newItem); } // second pass: now that all nodes have been created, we can finally assign parents foreach (var kvp in parents) { var parent = treeElements.Find(x => x.name == kvp.Value); if (parent == null) { MerinoDebug.LogFormat(LoggingLevel.Error, "Merino couldn't assign parent for node {0}: can't find a parent called {1}", kvp.Key.name, kvp.Value); } else { // tell child about it's parent kvp.Key.parent = parent; kvp.Key.cachedParentID = parent.id; // tell parent about it's child if (kvp.Key.parent.children == null) // init parent's list of children if not already initialized { kvp.Key.parent.children = new List <TreeElement>(); } kvp.Key.parent.children.Add(kvp.Key); } } return(treeElements); }