public void reset() { selectedEdge = -1; selected = null; m0 = false; transitionLine = false; }
protected Rect makeNodeRect(MoronIONode node) { IEnumerable <FieldInfo> attributes; float width, height; width = 180; height = 25; attributes = node.getFieldsWithAttribute <MoronManualWriteAttribute>(); if (attributes.Count() > 0) { height += attributes.Count() * 20f; } attributes = node.getFieldsWithAttribute <MoronStateWriteAttribute>(); if (attributes.Count() > 0) { height += (attributes.Count() + 1) * 20f; } attributes = node.getFieldsWithAttribute <MoronStateReadAttribute>(); if (attributes.Count() > 0) { height += (attributes.Count() + 1) * 20f; } return(new Rect(node.position.x - width / 2, node.position.y - height / 2, width, height)); }
/// <summary> /// Creates and returns the root of a fresh set of nodes and edges for the given [thinker]. /// </summary> public MoronIONode createResolvedGraph(MoronThinker thinker) { MoronIONode[] resolvedNodes; MoronIONode node; resolvedNodes = new MoronIONode[nodes.Count]; for (int i = 0; i < nodes.Count; i++) { node = (MoronIONode)Activator.CreateInstance(nodes[i].GetType()); node.thinker = thinker; node.guid = nodes[i].guid; node.interruptsIntent = nodes[i].interruptsIntent; node.setJoistsTo(nodes[i]); resolvedNodes[i] = node; } foreach (Pair <int, int> edge in edges) { resolvedNodes[edge.key].addEdge(resolvedNodes[edge.value]); } for (int i = 0; i < resolvedNodes.Length; i++) { resolvedNodes[i].init(); } return(resolvedNodes[0]); }
protected void drawNode(MoronIONode node) { Rect nodeRect; nodeRect = makeNodeRect(node); drawBody(node, nodeRect); drawTitleLabel(node, nodeRect); drawFields(node, nodeRect); }
protected void setCurrentNode(MoronIONode node) { if (currentNode != null) { currentNode.deactivate(); notifyNearby(currentNode, false); } currentNode = node; notifyNearby(currentNode, true); currentNode.activate(); }
protected void drawJoistList <T>(MoronIONode node, Rect nodeRect, ref Rect current, ref Rect label, Func <String, String> getCall, Action <String, String> setCall, String labelText) where T : Attribute { IEnumerable <FieldInfo> fields; String[] matchingArray; float labelWidth; int index, original, adj; fields = node.getFieldsWithAttribute <T>(); if (fields.Count() <= 0) { return; } label.y = current.y; label.width = GUI.skin.label.CalcSize(new GUIContent(labelText)).x; current.y += 20; EditorGUI.LabelField(label, labelText); // reads foreach (FieldInfo field in fields) { label.y = current.y; label.width = GUI.skin.label.CalcSize(new GUIContent(field.Name)).x; labelWidth = label.width + 5; current.x = nodeRect.x + labelWidth; current.width = nodeRect.width - labelWidth - 2; EditorGUI.LabelField(label, field.Name); matchingArray = graph.statemapDefinition.getFieldsForType(field.FieldType).Select(k => k.name).ToArray(); original = Array.IndexOf(matchingArray, getCall(field.Name)); adj = original; if (original < 0) { adj = 0; } index = EditorGUI.Popup(current, adj, matchingArray); if (index >= 0 && index < matchingArray.Length && index != original) { setCall(field.Name, matchingArray[index]); EditorUtility.SetDirty(graph); } current.y += 20; } }
protected void recurseReadUpdates(MoronIONode node) { MoronChoice choice; node.updateReadFields(); foreach (GraphEdge edge in node.edges) { choice = edge.to as MoronChoice; if (choice != null) { recurseReadUpdates(choice); continue; } ((MoronIONode)edge.to).updateReadFields(); } }
protected void drawTitleLabel(MoronIONode node, Rect nodeRect) { String name; Rect labelRect; name = findNodeTypeName(node.GetType()); labelRect = nodeRect; labelRect.x += labelRect.width / 2; labelRect.x -= GUI.skin.label.CalcSize(new GUIContent(name)).x / 2; labelRect.xMax = nodeRect.xMax; labelRect.height = 15; GUI.color = Color.white; GUI.Label(labelRect, name, GUIStyle.none); labelRect.xMin = nodeRect.xMin; labelRect.y += labelRect.height; labelRect.height = 1; GUI.color = Color.black; GUI.DrawTexture(labelRect, EditorGUIUtility.whiteTexture); }
protected void notifyNearby(MoronIONode node, bool active) { MoronChoice choice; foreach (GraphEdge edge in node.edges) { choice = edge.to as MoronChoice; if (choice == null || !choice.interruptsIntent) { continue; } if (active) { choice.notifyNearby(); } else { choice.notifyNotNearby(); } } }
protected void drawFields(MoronIONode node, Rect nodeRect) { System.Object value, original; Rect current, label; float labelWidth; current = new Rect(nodeRect.x, nodeRect.y + 20, nodeRect.width, 20); label = current; GUI.color = NODE_BACKGROUND_COLOR; GUI.contentColor = NODE_BACKGROUND_COLOR; GUI.backgroundColor = NODE_BACKGROUND_COLOR; // manual foreach (FieldInfo field in node.getFieldsWithAttribute <MoronManualWriteAttribute>()) { label.y = current.y; label.width = GUI.skin.label.CalcSize(new GUIContent(field.Name)).x; labelWidth = label.width + 5; current.x = nodeRect.x + labelWidth; current.width = nodeRect.width - labelWidth - 2; original = node.getManualJoist(field.Name); value = EditorPropertyHelper.propertyField(current, label, field.Name, field.FieldType, original); node.setManualJoist(field.Name, value); if (value != original) { EditorUtility.SetDirty(graph); } current.y += 20; } drawJoistList <MoronStateReadAttribute>(node, nodeRect, ref current, ref label, node.getReadJoist, node.setReadJoist, " Reads:"); drawJoistList <MoronStateWriteAttribute>(node, nodeRect, ref current, ref label, node.getWriteJoist, node.setWriteJoist, " Writes:"); }
protected void makeTransition(MoronIONode from, MoronIONode to) { Pair <int, int> edge; int metaIndex, previousEdgeMetaIndex, count; if (from == to) { return; } metaIndex = graph.nodes.IndexOf(from); previousEdgeMetaIndex = -1; switch (transitionReplacement) { case MoronTransitionCondition.INTENT: // if both are intents, we make sure that [from] has no other intent edges - an intent can only have one other intent as an edge. if (from is MoronIntent && to is MoronIntent) { graph.edges.RemoveAll(e => e.key == metaIndex && graph.nodes[e.value] is MoronIntent); } break; case MoronTransitionCondition.YES: // remove the lowest-index transition, and insert into its old spot. for (int i = 0; i < graph.edges.Count; i++) { if (graph.edges[i].key == metaIndex) { previousEdgeMetaIndex = i; break; } } if (previousEdgeMetaIndex >= 0) { graph.edges.RemoveAt(previousEdgeMetaIndex); } break; case MoronTransitionCondition.NO: // remove the highest-index transition, and insert into its old spot. count = 0; for (int i = 0; i < graph.edges.Count; i++) { if (graph.edges[i].key == metaIndex && ++count == 2) { previousEdgeMetaIndex = i; break; } } if (previousEdgeMetaIndex >= 0) { graph.edges.RemoveAt(previousEdgeMetaIndex); } break; } edge = new Pair <int, int>(graph.nodes.IndexOf(from), graph.nodes.IndexOf(to)); if (previousEdgeMetaIndex < 0) { graph.edges.Add(edge); } else { graph.edges.Insert(previousEdgeMetaIndex, edge); } EditorUtility.SetDirty(graph); }
protected void drawBody(MoronIONode node, Rect nodeRect) { MoronThinker thinker; MoronIONode thinkerNode; TimeSpan age; Rect borderRect; Color desiredColor; // border borderRect = nodeRect; borderRect.x -= 1; borderRect.y -= 1; borderRect.width += 2; borderRect.height += 2; if (node == selected) { GUI.color = Color.yellow; } else { GUI.color = Color.black; } GUI.DrawTexture(borderRect, EditorGUIUtility.whiteTexture); // body if (node is MoronIntent) { if (node == graph.nodes[0]) { desiredColor = INTENT_ROOT_COLOR; } else { desiredColor = INTENT_COLOR; } } else { desiredColor = CHOICE_COLOR; } if (Application.isPlaying && Selection.gameObjects.Length > 0) { thinker = Selection.gameObjects[0].GetComponent <MoronThinker>(); if (thinker != null) { if (thinker.getCurrentNode().guid == node.guid) { desiredColor = Color.white; } else { if (guidMap.ContainsKey(node.guid)) { thinkerNode = guidMap[node.guid]; age = DateTime.Now.AddMilliseconds(-NODE_FLASHTIME).Subtract(thinkerNode.lastActiveTime); if (age.TotalMilliseconds < NODE_FLASHTIME) { desiredColor = Color.LerpUnclamped(Color.white, desiredColor, (float)age.TotalMilliseconds / (float)NODE_FLASHTIME); } } } } } GUI.color = desiredColor; GUI.DrawTexture(nodeRect, EditorGUIUtility.whiteTexture); }
public void setJoistsTo(MoronIONode other) { readJoists = other.readJoists; writeJoists = other.writeJoists; manualJoists = other.manualJoists; }
public void updateInput(Event current) { MoronIONode currentNode; Vector2 position; position = current.mousePosition + scrollPosition; switch (current.type) { case EventType.MouseDown: if (!checkStatemapWidth(position.x)) { break; } lastClicked = position; switch (current.button) { case 0: selectedEdge = -1; currentNode = findNodeForPosition(position); if (transitionLine) { m0 = false; if (currentNode != null) { makeTransition(selected, currentNode); } break; } selected = currentNode; if (selected != null) { selectionOffset = VectorHandling.convXY(selected.position) - position; m0 = true; } else { deselectNode(); selectionOffset = Vector3.zero; selectedEdge = findEdgeForPosition(position); } break; case 1: selected = findNodeForPosition(position); if (selected == null) { selectedEdge = findEdgeForPosition(position); } rightClick(); break; } transitionLine = false; GUI.FocusControl(""); break; case EventType.MouseUp: transitionLine = false; if (current.button != 0) { break; } m0 = false; if (!checkStatemapWidth(position.x)) { break; } if (findNodeForPosition(position) != selected) { deselectNode(); } break; case EventType.MouseDrag: lastDragged = position; if (!m0 || selected == null) { break; } selected.position = VectorHandling.gridsnap(lastDragged + selectionOffset, GRIDSNAP_SIZE); markDirty(); break; case EventType.KeyDown: if (!checkStatemapWidth(current.mousePosition.x)) { break; } switch (current.keyCode) { case KeyCode.X: case KeyCode.Delete: deleteSelected(); break; case KeyCode.T: MoronTransitionCondition condition; if (selected == null || transitionLine) { break; } condition = MoronTransitionCondition.INTENT; if (selected is MoronChoice) { condition = MoronTransitionCondition.YES; } startTransition(condition); break; case KeyCode.A: showAddMenu(); break; } break; } }
protected void deselectNode() { selected = null; GUI.FocusControl(""); }