void OnClickOutput(GameObject sender) { Debug.Log("click output child" + sender); LinkNodeData cur_data = new LinkNodeData(this, sender, false, -1, m_outputOperators.Count); LinkLineMgr.Instance.SettleOrCreateMatch(cur_data); }
// 断开当前的线,并握住这根线的这一头 public void ChangeLink(LinkNodeData node) { OperatorLink input_node, output_node; int input_idx; GameObject input_anchor, output_anchor; GetLinkData(node, out input_node, out input_idx, out output_node); output_node.RemoveOutputLink(input_node, input_idx); input_node.RemoveInputLink(input_idx); LinkLine line = RemoveLinkLine(input_node, input_idx, output_node); m_curLine = line; if (node.isInput) { output_anchor = output_node.FindOutputAnchor(); line.SetNode(output_anchor, null); m_matchingObj = new LinkNodeData(output_node, output_anchor, false, -1, -1); } else { input_anchor = input_node.FindInputAnchor(input_idx); line.SetNode(null, input_anchor); m_matchingObj = new LinkNodeData(input_node, input_anchor, true, input_idx, -1); } OnLinkChange(); }
// 判断当前节点是否已经有线了 public bool HasOccupy(LinkNodeData node) { for (int i = 0; i != m_links.Count; ++i) { if ((node.isInput && m_links[i].inputObj == node.obj && m_links[i].inputObjIdx == node.inputIdx) || (!node.isInput && m_links[i].outputObj == node.obj)) { return(true); } } return(false); }
// 创建一条线 public void StartMatch(LinkNodeData src) { m_matchingObj = src; m_curLine = CreateLine(); if (src.isInput) { m_curLine.SetNode(null, src.anchorObj); } else { m_curLine.SetNode(src.anchorObj, null); } }
// 删除一个link public void RemoveLink(LinkNodeData node) { OperatorLink input_node, output_node; int input_idx; GetLinkData(node, out input_node, out input_idx, out output_node); output_node.RemoveOutputLink(input_node, input_idx); input_node.RemoveInputLink(input_idx); LinkLine line = RemoveLinkLine(input_node, input_idx, output_node); GameObject.Destroy(line.gameObject); OnLinkChange(); }
// 放弃当前的线 public void CancelMatch() { if (m_matchingObj == null) { return; } m_matchingObj = null; if (m_curLine != null) { GameObject.Destroy(m_curLine.gameObject); m_curLine = null; } }
// 获取某个连接点当前的状态信息 public void GetLinkData(LinkNodeData node, out OperatorLink input_node, out int input_idx, out OperatorLink output_node) { if (node.isInput) { input_node = node.obj; input_idx = node.inputIdx; output_node = input_node.GetInputNode(input_idx); } else { input_node = node.obj.GetOutputNode(node.outputIdx); input_idx = node.obj.GetOutputNodeInIdx(node.outputIdx); output_node = node.obj; } }
// 检查这个节点是否可以用来连接 public bool CanMatch(LinkNodeData dst) { if (!m_matchingObj.isInput ^ dst.isInput) { Debug.Log("input is same!"); return(false); } if (IsCauseCicle(dst)) { Debug.Log("cause circle!"); return(false); } return(true); }
// 根据当前状态,决定是创建新的还是放下旧的 public void SettleOrCreateMatch(LinkNodeData src) { if (LinkLineMgr.Instance.IsMatching()) { if (LinkLineMgr.Instance.CanMatch(src)) { LinkLineMgr.Instance.SettleMatch(src); } else { Debug.Log("Cannot match!"); } } else { LinkLineMgr.Instance.StartMatch(src); } }
void OnClickInputChild(GameObject sender) { int child_idx = int.Parse(sender.name); Debug.Log("click input child: " + sender); LinkNodeData cur_data = new LinkNodeData(this, sender, true, child_idx, 0); if (!LinkLineMgr.Instance.HasOccupy(cur_data)) { LinkLineMgr.Instance.SettleOrCreateMatch(cur_data); } else if (LinkLineMgr.Instance.IsMatching()) { return; } else { LinkLineMgr.Instance.ChangeLink(cur_data); } }
// 检查是否会造成循环 public bool IsCauseCicle(LinkNodeData node) { if (node.obj == m_matchingObj.obj) { return(true); } Dictionary <OperatorLink, bool> checked_pool = new Dictionary <OperatorLink, bool>(); checked_pool[node.obj] = true; checked_pool[m_matchingObj.obj] = true; OperatorLink input_node = node.isInput ? node.obj : m_matchingObj.obj; OperatorLink output_node = node.isInput ? m_matchingObj.obj : node.obj; Stack <OperatorLink> to_check_stack = new Stack <OperatorLink>(); to_check_stack.Push(output_node); while (to_check_stack.Count != 0) { OperatorLink cur_link = to_check_stack.Pop(); foreach (OperatorLink child_link in cur_link.m_inputOperators) { if (child_link != null) { if (child_link == input_node) { return(true); } if (!checked_pool.ContainsKey(child_link)) { checked_pool[child_link] = true; to_check_stack.Push(child_link); } } } } return(false); }
// 决定当前的线 public void SettleMatch(LinkNodeData dst) { if (!CanMatch(dst)) { return; } OperatorLink input_node = (dst.isInput ? dst : m_matchingObj).obj; OperatorLink output_node = (!dst.isInput ? dst : m_matchingObj).obj; GameObject input_anchor = (dst.isInput ? dst : m_matchingObj).anchorObj; GameObject output_anchor = (!dst.isInput ? dst : m_matchingObj).anchorObj; int input_idx = dst.isInput ? dst.inputIdx : m_matchingObj.inputIdx; input_node.AddInputLink(output_node, input_idx); output_node.AddOutputLink(input_node, input_idx); m_links.Add(new LinkData(m_curLine, input_node, input_idx, output_node)); m_curLine.SetNode(output_anchor, input_anchor); m_matchingObj = null; m_curLine = null; OnLinkChange(); }