private static Expression FindMostReductiveNodeOrNull(NodeSizes results, int maximumNumberOfNodesPerDelegate) { // By setting a maximum size, we prevent that the one of the root nodes will be selected as most // reductive node. Although this would reduce the expression to a few nodes, this will leave us // with a new expression that is as big or almost as big, and might even cause a stack overflow. int maximumSizeOfReducibleNode = maximumNumberOfNodesPerDelegate * 9 / 10; // 90% int maximumSizeOfNode = results.TotalSize - maximumSizeOfReducibleNode; // We must set a minimum size for the nodes to prevent selecting nodes with just a few sub nodes // (such as CallExpression and InvocationExpression nodes that capture a ConstantExpression), // because that would reduce them with new expressions of the same size, and would cause us to // keep looping infinitely without reducing the size of the expression. // Although we could lower the size to 4 or 5, this could cause those small trees (that are // always leaf structures) to be selected, while we prefer reducing big object graphs first, // because replacing a leaf node will cause all its parents to be replaced, making it impossible // to detect duplicate reduced expressions (see the ReduceObjectGraphSize method). This makes it // much less likely to be able to reuse a compiled delegate. int minimumSizeOfNode = 10; // Here we sort not only by total cost, but in case there are multiple nodes with the same total // cost, we prefer the node with the biggest size. This has the same reason as explained above. var nodesByTotalCost = from info in results.Nodes where info.TreeSize <= maximumSizeOfNode && info.TreeSize >= minimumSizeOfNode orderby info.TotalCost descending, info.TreeSize descending select info; var nodeWithLargestCost = nodesByTotalCost.FirstOrDefault(); return(nodeWithLargestCost != null ? nodeWithLargestCost.Node : null); }
private bool ShouldBeCulled(INode node) { var nodePos = GridToWindowPositionNoClipped(node.Position); if (nodePos.x / _zoom > position.width) { return(true); // Right } if (nodePos.y / _zoom > position.height) { return(true); // Bottom } if (NodeSizes.ContainsKey(node)) { var size = NodeSizes[node]; if (nodePos.x + size.x < 0) { return(true); // Left } if (nodePos.y + size.y < 0) { return(true); // Top } } return(false); }
bool IsHoveringTitle(INode node) { var mousePos = Event.current.mousePosition; //Get node position var nodePos = GridToWindowPosition(node.Position); float width; if (NodeSizes.TryGetValue(node, out var size)) { width = size.x; } else { width = 200; } var windowRect = new Rect(nodePos, new Vector2(width / Zoom, 30 / Zoom)); return(windowRect.Contains(mousePos)); }
private void DrawNodeEditorArea( NodeEditor nodeEditor, EditorNode editorNode, NodeEditorGuiState state) { var eventType = state.EventType; var stateEvent = state.Event; var node = editorNode.Node; if (eventType == EventType.Ignore || stateEvent.type == EventType.Ignore || stateEvent.rawType == EventType.Ignore) { return; } var guiColor = GUI.color; var selected = IsSelected(node); if (selected) { var style = new GUIStyle(nodeEditor.GetBodyStyle()); var highlightStyle = new GUIStyle(NodeEditorResources.styles.nodeHighlight); highlightStyle.padding = style.padding; style.padding = new RectOffset(); GUI.color = nodeEditor.GetTint(); GUILayout.BeginVertical(style); GUI.color = this.GetSettings().highlightColor; //TODO fix style GUILayout.BeginVertical(new GUIStyle(highlightStyle)); } else { var style = new GUIStyle(nodeEditor.GetBodyStyle()); GUI.color = nodeEditor.GetTint(); GUILayout.BeginVertical(style); } GUI.color = guiColor; EditorGUI.BeginChangeCheck(); //Draw node contents nodeEditor.OnHeaderGUI(); nodeEditor.OnBodyGUI(); //If user changed a value, notify other scripts through onUpdateNode if (EditorGUI.EndChangeCheck()) { if (NodeEditor.OnUpdateNode != null) { NodeEditor.OnUpdateNode(node); } node.SetDirty(); } GUILayout.EndVertical(); //Cache data about the node for next frame if (state.EventType == EventType.Repaint) { var size = GUILayoutUtility.GetLastRect().size; if (NodeSizes.ContainsKey(node)) { NodeSizes[node] = size; } else { NodeSizes.Add(node, size); } foreach (var portPairs in NodeEditor.PortPositions) { var id = portPairs.Key; var portHandlePos = portPairs.Value; portHandlePos += node.Position; var rect = new Rect(portHandlePos.x - 8, portHandlePos.y - 8, 16, 16); PortConnectionPoints[id] = rect; } } if (selected) { GUILayout.EndVertical(); } }