using UnityEngine; using System.Collections; using System.Collections.Generic; public class WMG_Graph_Manager : WMG_Events, IWMG_Data_Generators, IWMG_Caching_Functions, IWMG_Path_Finding { private List nodesParent = new List(); // Each gameobject in this list is a WMG Node private List linksParent = new List(); // Each gameobject in this list is a WMG Link // Data generation functions private WMG_Data_Generators data_gen = new WMG_Data_Generators(); public List GenLinear(int numPoints, float minX, float maxX, float a, float b) { return data_gen.GenLinear(numPoints, minX, maxX, a, b); } public List GenQuadratic(int numPoints, float minX, float maxX, float a, float b, float c) { return data_gen.GenQuadratic(numPoints, minX, maxX, a, b, c); } public List GenExponential(int numPoints, float minX, float maxX, float a, float b, float c) { return data_gen.GenExponential(numPoints, minX, maxX, a, b, c); } public List GenLogarithmic(int numPoints, float minX, float maxX, float a, float b, float c) { return data_gen.GenLogarithmic(numPoints, minX, maxX, a, b, c); } /// /// Generate data of the form c^2 = (X - a)^2 * (Y - b)^2 /// /// List of Vector2 forming a circle. public List GenCircular(int numPoints, float a, float b, float c) { return data_gen.GenCircular(numPoints, a, b, c); } public List GenCircular2(int numPoints, float a, float b, float c, float degreeOffset) { return data_gen.GenCircular2(numPoints, a, b, c, degreeOffset); } public List GenRadar(List data, float a, float b, float degreeOffset) { return data_gen.GenRadar(data, a, b, degreeOffset); } public List GenRandomXY(int numPoints, float minX, float maxX, float minY, float maxY) { return data_gen.GenRandomXY(numPoints, minX, maxX, minY, maxY); } public List GenRandomY(int numPoints, float minX, float maxX, float minY, float maxY) { return data_gen.GenRandomY(numPoints, minX, maxX, minY, maxY); } public List GenRandomList(int numPoints, float min, float max) { return data_gen.GenRandomList(numPoints, min, max); } // Caching functions private WMG_Caching_Functions caching = new WMG_Caching_Functions(); public void updateCacheAndFlagList(ref List cache, List val, ref bool flag) { caching.updateCacheAndFlagList(ref cache, val, ref flag); } public void updateCacheAndFlag(ref T cache, T val, ref bool flag) { caching.updateCacheAndFlag(ref cache, val, ref flag); } public void SwapVals(ref T val1, ref T val2) { caching.SwapVals(ref val1, ref val2); } public void SwapValsList(ref List val1, ref List val2) { caching.SwapValsList(ref val1, ref val2); } // Path Finding Functions private WMG_Path_Finding path_find = new WMG_Path_Finding(); public List FindShortestPathBetweenNodes(WMG_Node fromNode, WMG_Node toNode) { path_find.nodesParent = nodesParent; return path_find.FindShortestPathBetweenNodes(fromNode, toNode); } public List FindShortestPathBetweenNodesWeighted(WMG_Node fromNode, WMG_Node toNode, bool includeRadii) { path_find.nodesParent = nodesParent; return path_find.FindShortestPathBetweenNodesWeighted(fromNode, toNode, includeRadii); } // Graph Manager functions public string getLabelText(string text, WMG_Enums.labelTypes labelType, float value, float percent, int numDecimals) { string theText = text; float multiplier = Mathf.Pow(10f, numDecimals+2); if (labelType == WMG_Enums.labelTypes.None) { theText = ""; } else if (labelType == WMG_Enums.labelTypes.Labels_Percents) { theText += " (" + (Mathf.Round(percent*multiplier)/multiplier*100).ToString() + "%)"; } else if (labelType == WMG_Enums.labelTypes.Labels_Values) { theText += " (" + Mathf.Round(value).ToString() + ")"; } else if (labelType == WMG_Enums.labelTypes.Labels_Values_Percents) { theText += " - " + Mathf.Round(value).ToString() + " (" + (Mathf.Round(percent*multiplier)/multiplier*100).ToString() + "%)"; } else if (labelType == WMG_Enums.labelTypes.Values_Only) { theText = Mathf.Round(value).ToString(); } else if (labelType == WMG_Enums.labelTypes.Percents_Only) { theText = (Mathf.Round(percent*multiplier)/multiplier*100).ToString() + "%"; } else if (labelType == WMG_Enums.labelTypes.Values_Percents) { theText = Mathf.Round(value).ToString() + " (" + (Mathf.Round(percent*multiplier)/multiplier*100).ToString() + "%)"; } return theText; } public List NodesParent { get { return nodesParent; } } public List LinksParent { get { return linksParent; } } public GameObject CreateNode(Object prefabNode, GameObject parent) { // Creates a node from a prefab, gives a default parent to this object, and adds the node to the manager's list GameObject curObj = Instantiate(prefabNode) as GameObject; Vector3 origScale = curObj.transform.localScale; Vector3 origRot = curObj.transform.localEulerAngles; GameObject theParent = parent; if (parent == null) theParent = this.gameObject; changeSpriteParent(curObj, theParent); curObj.transform.localScale = origScale; curObj.transform.localEulerAngles = origRot; WMG_Node curNode = curObj.GetComponent(); curNode.SetID(nodesParent.Count); nodesParent.Add(curObj); return curObj; } public GameObject CreateLink(WMG_Node fromNode, GameObject toNode, Object prefabLink, GameObject parent) { GameObject createdLink = fromNode.CreateLink(toNode, prefabLink, linksParent.Count, parent, true); linksParent.Add(createdLink); return createdLink; } public GameObject CreateLinkNoRepos(WMG_Node fromNode, GameObject toNode, Object prefabLink, GameObject parent) { GameObject createdLink = fromNode.CreateLink(toNode, prefabLink, linksParent.Count, parent, false); linksParent.Add(createdLink); return createdLink; } public WMG_Link GetLink(WMG_Node fromNode, WMG_Node toNode) { foreach (GameObject link in fromNode.links) { WMG_Link aLink = link.GetComponent(); WMG_Node toN = aLink.toNode.GetComponent(); if (toN.id != toNode.id) toN = aLink.fromNode.GetComponent(); if (toN.id == toNode.id) return aLink; } return null; } public GameObject ReplaceNodeWithNewPrefab(WMG_Node theNode, Object prefabNode) { // Used to swap prefabs of a node GameObject newNode = CreateNode(prefabNode, theNode.transform.parent.gameObject); WMG_Node newNode2 = newNode.GetComponent(); newNode2.numLinks = theNode.numLinks; newNode2.links = theNode.links; newNode2.linkAngles = theNode.linkAngles; newNode2.SetID(theNode.id); newNode2.name = theNode.name; newNode.transform.position = theNode.transform.position; // Update link from / to node references for (int i = 0; i < theNode.numLinks; i++) { WMG_Link aLink = theNode.links[i].GetComponent(); WMG_Node fromN = aLink.fromNode.GetComponent(); if (fromN.id == theNode.id) { aLink.fromNode = newNode; } else { aLink.toNode = newNode; } } nodesParent.Remove(theNode.gameObject); Destroy(theNode.gameObject); return newNode; } public void DeleteNode(WMG_Node theNode) { // Deleting a node also deletes all of its link and swaps IDs with the largest node ID in the list int idToDelete = theNode.id; foreach (GameObject node in nodesParent) { WMG_Node aNode = node.GetComponent(); if (aNode != null && aNode.id == nodesParent.Count - 1) { aNode.SetID(idToDelete); while (theNode.numLinks > 0) { WMG_Link aLink = theNode.links[0].GetComponent(); DeleteLink(aLink); } nodesParent.Remove(theNode.gameObject); DestroyImmediate(theNode.gameObject); return; } } } public void DeleteLink(WMG_Link theLink) { // Deleting a link updates references in the to and from nodes and swaps IDs with the largest link ID in the list WMG_Node fromN = theLink.fromNode.GetComponent(); WMG_Node toN = theLink.toNode.GetComponent(); for (int i = 0; i < fromN.numLinks; i++) { WMG_Link aLink = fromN.links[i].GetComponent(); if (aLink.id == theLink.id) { fromN.numLinks--; fromN.links[i] = fromN.links[fromN.numLinks]; break; } } for (int i = 0; i < toN.numLinks; i++) { WMG_Link aLink = toN.links[i].GetComponent(); if (aLink.id == theLink.id) { toN.numLinks--; toN.links[i] = toN.links[toN.numLinks]; break; } } int idToDelete = theLink.id; foreach (GameObject child in linksParent) { WMG_Link aLink = child.GetComponent(); if (aLink != null && aLink.id == linksParent.Count - 1) { aLink.SetId(idToDelete); linksParent.Remove(theLink.gameObject); DestroyImmediate(theLink.gameObject); fromN.links.RemoveAt(fromN.numLinks); fromN.linkAngles.RemoveAt(fromN.numLinks); toN.links.RemoveAt(toN.numLinks); toN.linkAngles.RemoveAt(toN.numLinks); return; } } } }