/// <summary> /// Adding an edge to a Btc graph can do the following if the edge already exists: /// 1) not add the new edge, instead upgrade existing edge to type mixed ( == input and output) /// 2) not add the new edge, instead update the existing edge's edge counts if any are zero (means unknown) /// </summary> public override void AddEdge(CdmEdge e) { #region Data Quality Checks CdmEdgeBtc ebNew = e as CdmEdgeBtc; if (ebNew == null) { Msg.LogError("CdmGraphBtc.AddEdge cannot cast edge to CdmEdgeBtc"); return; } // Check edge has been handed to us in correct format, that is Transaction in the source slot CdmNode n = FindNodeAtEndOfEdge(ebNew.NodeTargetId, ebNew.EdgeId); if (n != null) { // Above may seem a bit lax, but we dont know order things will be added to the graph, maybe node is not known yet if (n.NodeType != NodeType.Tx) { Msg.LogError("CdmGraphBtc.AddEdge all edges must have a transaction as their source"); return; } } #endregion CdmEdgeBtc ebExisting = FindEdgeByNodeSourceAndTarget(ebNew.NodeSourceId, ebNew.NodeTargetId) as CdmEdgeBtc; if (ebExisting == null) { // New edge, just add to list _edges.Add(ebNew); } else { // Edge exists in graph already, upgrade it to type mixed if needed MergeExistingEdge(ebNew, ebExisting); } }
private void UpdateExistingEdgeGoData(GameObject edgeExistingGo, CdmEdgeBtc edgeNewBtc) { Msg.Log("GraphFactory.UpdateExistingEdgeGoData is refreshing edge data"); // TODO What might need updated? Since Cdm handles merges, it seems safe enough to overwrite whole object. GraphEdgeBrain blb = edgeExistingGo.GetComponent <GraphEdgeBrain>(); if (blb != null) { blb.CdmEdgeBtc = edgeNewBtc; // TODO plus propogate any values across the edge GO ? } }
/// <summary> /// Create a new edge game object, or update an existing one. New edges get added to _graphIndex list. /// </summary> void IGraphFactory.CreateOrUpdateEdge(CdmEdge edgeNew) { CdmEdgeBtc edgeNewBtc = edgeNew as CdmEdgeBtc; // Do we exist already? GameObject edgeExistingGo; if (_graphIndex.TryGetValue(edgeNewBtc.EdgeId, out edgeExistingGo)) { UpdateExistingEdgeGoData(edgeExistingGo, edgeNewBtc); return; } // We are new. Do necessary nodes exist? GameObject sourceGo; bool sourceExists = _graphIndex.TryGetValue(edgeNewBtc.NodeSourceId, out sourceGo); GameObject targetGo; bool targetExists = _graphIndex.TryGetValue(edgeNewBtc.NodeTargetId, out targetGo); if (!sourceExists || !targetExists) { Msg.LogWarning("GraphFactory.CreateEdge cannot create edge because source or target GameObject dont exist yet"); return; } // Do it GameObject createdEdge = null; //Msg.Log("GraphFactory.CreateEdge: Edge about to be created: " + edgeNewBtc.EdgeId); createdEdge = InstantiateEdge(edgeNewBtc.EdgeId, edgeNewBtc.EdgeIdFriendly, edgeNewBtc.EdgeNumberInSource, edgeNewBtc.EdgeNumberInTarget, sourceGo, targetGo, edgeNewBtc.EdgeType, true, edgeNewBtc.ValueInSource, edgeNewBtc.ValueInTarget); if (createdEdge == null) { Msg.LogWarning("GraphFactory.CreateEdge: Edge not created."); } else { Msg.Log("GraphFactory.GenerateEdge: Edge created: " + createdEdge.gameObject.name); GraphEdgeBrain geb = createdEdge.GetComponent <GraphEdgeBrain>(); if (geb != null) { geb.CdmEdgeBtc = edgeNewBtc; } // index it _graphIndex.Add(edgeNewBtc.EdgeId, createdEdge); } }
private void OnCdmPoolGraphAdded(object sender, CdmPoolEventArgs args) { // Note: it is possible to filter to just showing graphs that WE requested from the cdmpool. To do this, examine args.CdmRequest to see // what the request was. For now this is not needed and not done. CdmGraphBtc gb = args.CdmGraph as CdmGraphBtc; if (gb == null) { Msg.LogError("FrontEndController.OnCdmPoolGraphAdded heard event but graph fragment is null or not correct type"); return; } else { Msg.Log("FrontEndController.OnCdmPoolGraphAdded heard event that graph fragment" + gb.GraphId + " is to be added to pool"); } // Create nodes and edges Vector3 location = args.CdmRequest.WorldLocation; foreach (CdmNode n in gb.GetAllNodes()) { CdmNodeBtc nb = n as CdmNodeBtc; GraphFactory.CreateOrUpdateNode(nb, location); } foreach (CdmEdge e in gb.GetAllEdges()) { CdmEdgeBtc eb = e as CdmEdgeBtc; GraphFactory.CreateOrUpdateEdge(eb); } // An audio-visual feast if (AudioManager.Instance != null) { AudioManager.Instance.PlayPop(); } }
/// <summary> /// Merge data from incoming edge ebNew into existing edge ebExisting, updating the existing edge and changing its type to mixed if needed. /// </summary> private void MergeExistingEdge(CdmEdgeBtc ebNew, CdmEdgeBtc ebExisting) { // Edge types. Anything can override Unknown, otherwise merging two different types promotes to Mixed if (ebNew.EdgeType != ebExisting.EdgeType) { if (ebNew.EdgeType == EdgeType.Unknown) { // no change to existing edge type } else { // New edge type is known if (ebExisting.EdgeType == EdgeType.Unknown) { ebExisting.EdgeType = ebNew.EdgeType; } else { // Both existing and new edge types are known if (ebExisting.EdgeType == ebNew.EdgeType) { // they are the same anyway, no change } else { ebExisting.EdgeType = EdgeType.Mixed; } } } } // Edge values for mixed edges float fsmall = 0.000001f; if (ebExisting.EdgeType == EdgeType.Mixed) { if (ebExisting.ValueInSource <= fsmall && ebNew.ValueInSource > fsmall) { ebExisting.ValueInSource = ebNew.ValueInSource; } if (ebExisting.ValueInTarget <= fsmall && ebNew.ValueInTarget > fsmall) { ebExisting.ValueInTarget = ebNew.ValueInTarget; } } // Edge exists in graph already, check to see if we have more info about edge numbering // Source Edge Number if (ebExisting.EdgeNumberInSource == 0) { if (ebNew.NodeSourceId == ebExisting.NodeSourceId) { // edge in graph already is stored same way around as new edge, so source node in graph == source node in new if (ebNew.EdgeNumberInSource > 0) { ebExisting.EdgeNumberInSource = ebNew.EdgeNumberInSource; } } else { // edge in graph already is stored other way around as new edge, so source node in graph == target node in new if (ebNew.EdgeNumberInTarget > 0) { ebExisting.EdgeNumberInSource = ebNew.EdgeNumberInTarget; } } } // Target Edge Number if (ebExisting.EdgeNumberInTarget == 0) { if (ebNew.NodeSourceId == ebExisting.NodeSourceId) { // edge in graph already is stored same way around as new edge, so source node in graph == source node in new if (ebNew.EdgeNumberInTarget > 0) { ebExisting.EdgeNumberInTarget = ebNew.EdgeNumberInTarget; } } else { // edge in graph already is stored other way around as new edge, so source node in graph == target node in new if (ebNew.EdgeNumberInSource > 0) { ebExisting.EdgeNumberInTarget = ebNew.EdgeNumberInSource; } } } }