Esempio n. 1
0
    internal NNTPCommands FindWork(VirtualConnection vConnection)
    {
        //List<int> vCons;

        if (vConnection == null)
        {
            return(null);
        }
        if (vConnection.Server == null)
        {
            return(null);
        }

        NNTPCommands vCom = SearchRandomStack(vConnection);

        if (vCom != null)
        {
            return(vCom);
        }
        if (vConnection.Server.Priority == ServerPriority.Low)
        {
            return(null);
        }

        return(SearchRandomSlot(vConnection));
    }
Esempio n. 2
0
    internal IndexedCollection SwitchStack(int SlotID, VirtualConnection vConnection)
    {
        IndexedCollection iStack          = null;
        List <int>        AvailableStacks = null;

        while (true)
        {
            if (!SlotExist(SlotID))
            {
                return(null);
            }
            if (vConnection.Cancelled)
            {
                return(null);
            }

            AvailableStacks = SmartStack(vConnection);
            if (AvailableStacks.Count == 0)
            {
                return(null);
            }

            foreach (int ServerID in AvailableStacks)
            {
                iStack = Stack(ServerID, SlotID);
                if (iStack != null)
                {
                    return(iStack);
                }
            }
        }
    }
Esempio n. 3
0
    private List <int> SmartStack(VirtualConnection vConnection)
    {
        int        SmallestStack   = 0;
        List <int> ActiveSlots     = WaitingSlots;
        List <int> AvailableStacks = new List <int>();

        foreach (VirtualServer vServer in List())
        {
            if (!ServerActive(vServer.ID))
            {
                continue;
            }
            int iLoad = WorkLoad(vServer.ID, ActiveSlots);

            if (AvailableStacks.Count == 0 || iLoad <= SmallestStack)
            {
                if (SmallestStack > 0)
                {
                    AvailableStacks.Clear();
                }
                AvailableStacks.Add(vServer.ID);
                SmallestStack = iLoad;
            }
        }

        if ((AvailableStacks.Count == 0) && (ServerActive(vConnection.Server.ID)))
        {
            AvailableStacks.Add(vConnection.Server.ID);
        }

        return(AvailableStacks);
    }
Esempio n. 4
0
    public static (List <List <IShape> >, List <(IShape, List <IShape>)>) Run(int min, int max, uint times)
    {
        Rules rules = new Rules();

        rules.AddRule(
            new Attributes(

                ),
            (Quad quad) => {
            Vertex b1 = quad.l1.Bisect();
            Vertex b2 = quad.l2.Bisect();
            Vertex b3 = quad.l3.Bisect();
            Vertex b4 = quad.l4.Bisect();

            Vertex c = (b1 + b2 + b3 + b4) / 4f;

            Quad q4 = new Quad(rules, quad.Attributes.Copy(), (0, 0), (b4, c, b3, quad.v4));
            Quad q1 = new Quad(rules, quad.Attributes.Copy(), (1, 0), (quad.v1, b1, c, b4));
            Quad q3 = new Quad(rules, quad.Attributes.Copy(), (0, 1), (c, b2, quad.v3, b3));
            Quad q2 = new Quad(rules, quad.Attributes.Copy(), (1, 1), (b1, quad.v2, b2, c));

            if (quad.VC == null || !quad.VC.Persistant)
            {
                VirtualConnection.Connect(q4, q1, false, false, true);
                VirtualConnection.Connect(q3, q2, true, false, true);
            }

            return(new List <IShape> {
                q1, q2, q3, q4
            });
        }
Esempio n. 5
0
        public void DisconnectSocket(Socket socket, bool recordUndo, bool saveAssets = false)
        {
            if (!socket.IsConnected)
            {
                return;
            }

            if (recordUndo)
            {
                RecordUndo(GraphAction.Disconnect.ToString());
            }
            List <string> socketConnectionIds = socket.GetConnectionIds();

            foreach (string connectionId in socketConnectionIds)
            {
                if (!ConnectionsDatabase.ContainsKey(connectionId))
                {
                    continue;
                }
                VirtualConnection vc = ConnectionsDatabase[connectionId];
                vc.OutputSocket.RemoveConnection(connectionId);
                vc.InputSocket.RemoveConnection(connectionId);
                EditorUtility.SetDirty(vc.OutputNode);
                EditorUtility.SetDirty(vc.InputNode);
                ConnectionsDatabase.Remove(connectionId);
            }

            CurrentGraph.SetDirty(saveAssets);
            GraphEvent.Send(GraphEvent.EventType.EVENT_NODE_DISCONNECTED, socket.NodeId);
        }
Esempio n. 6
0
        protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
        {
            base.OnPreviewMouseDown(e);

            m_currentPosition = e.GetPosition(this);
            m_originPoint     = m_currentPosition;
            m_hittestElement  = this.HitTest <BaseNodeControl>(m_currentPosition);
            if (m_hittestElement != null) // if node based element is clicked
            {
                var connector = m_hittestElement as ConnectorControl;
                if (connector != null)
                {
                    var sourceConnector = connector;

                    // if connector is already connected and Ctrl key pressed - start nodes reconnection
                    if (connector.ConnectionPoint.IsConnected && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
                    {
                        var connections = m_connections.Where(c => c.Value.Source.Equals(connector) || c.Value.Destination.Equals(connector)).ToList();
                        if (connections.Any())
                        {
                            var record = connections.First();
                            // this is not a misstake.
                            // If this is Source connector for connection then virtual connection should start from
                            // oposit connector which is Destination and vice versa.
                            if (record.Value.Source.Equals(connector))
                            {
                                sourceConnector = (ConnectorControl)record.Value.Destination;
                            }
                            else
                            {
                                sourceConnector = (ConnectorControl)record.Value.Source;
                            }

                            Diagram.Connections.Remove(record.Key);
                        }
                    }

                    // if it is connector - create virtual connection
                    // virtual elements excluded from hit test
                    var virtualConnector = new VirtualConnectionPoint(sourceConnector)
                    {
                        X = m_currentPosition.X,
                        Y = m_currentPosition.Y
                    };
                    Children.Add(virtualConnector);

                    var virtualConnection          = new VirtualConnection(sourceConnector.ConnectionPoint);
                    var virtualConnectionContainer = new ConnectionContainerControl(sourceConnector, virtualConnector,
                                                                                    virtualConnection, false);
                    m_connections.Add(virtualConnection, virtualConnectionContainer);
                    Children.Add(virtualConnectionContainer);

                    m_hittestElement = virtualConnector;
                }

                m_hittestElement.CaptureMouse();
            }
        }
Esempio n. 7
0
    internal void LogError(NNTPError zErr, VirtualConnection vConnection)
    {
        if (zSeg != null)
        {
            zSeg.LogError(ID, zErr);
        }

        if (vConnection != null)
        {
            vConnection.LogError(ID, zErr);
        }
    }
Esempio n. 8
0
    private NNTPCommands SearchRandomStack(VirtualConnection vConnection)
    {
        foreach (IndexedCollection vStack in WaitingStacks(vConnection.Server.ID))
        {
            NNTPCommands zCommand = (NNTPCommands)vStack.Take();
            if (zCommand != null)
            {
                return(zCommand);
            }
        }

        return(null);
    }
Esempio n. 9
0
    private NNTPCommands SearchRandomSlot(VirtualConnection vConnection)
    {
        foreach (VirtualSlot vSlot in RandomSlots()) // Global queue
        {
            NNTPCommands zCommand = (NNTPCommands)vSlot.Take(vConnection);
            if (zCommand != null)
            {
                return(zCommand);
            }
        }

        return(null);
    }
        public Stream OpenVirtualConnection()
        {
            // Improve discoverability of read-loop errors (in case the developer doesn't add an OnError listener)
            ThrowIfReadLoopFailed();

            var id = Interlocked.Increment(ref _nextInnerStreamId);
            var newInnerStream = new VirtualConnection(id, this);
            lock (_activeInnerStreams)
            {
                _activeInnerStreams.Add(id, newInnerStream);
            }

            return newInnerStream;
        }
Esempio n. 11
0
    internal void Progress(long AddedBytes, VirtualConnection vConnection)
    {
        if (zSeg != null)
        {
            long rBytes = Interlocked.Read(ref AddedBytes);

            zSeg.Progress(rBytes);

            VirtualSlot vSlot = vConnection.Scheduler.Slots.Item(zSeg.SlotID);

            if (vSlot != null)
            {
                vSlot.Progress(rBytes);
            }
        }
    }
Esempio n. 12
0
    internal void Statistics(long AddedBytes, long RealTime, VirtualConnection vConnection)
    {
        if (zSeg != null)
        {
            long lTime  = Interlocked.Read(ref RealTime);
            long rBytes = Interlocked.Read(ref AddedBytes);

            zSeg.Statistics(rBytes, lTime);

            VirtualSlot vSlot = vConnection.Scheduler.Slots.Item(zSeg.SlotID);

            if (vSlot != null)
            {
                vSlot.Statistics(rBytes, lTime);
            }
        }
    }
Esempio n. 13
0
        private void ValidateConnectionsDatabase()
        {
            if (m_connectionsDatabase == null)
            {
                return;
            }
            var invalidKeys = new List <string>(); //temp keys list

            foreach (string key in ConnectionsDatabase.Keys)
            {
                if (ConnectionsDatabase[key] == null)
                {
                    invalidKeys.Add(key); //null virtual connection -> remove key
                    continue;
                }

                VirtualConnection v = ConnectionsDatabase[key];
                if (v.OutputNode == null)
                {
                    invalidKeys.Add(key); //null output node -> remove key
                    continue;
                }

                if (v.InputNode == null)
                {
                    invalidKeys.Add(key); //null input node -> remove key
                    continue;
                }

                if (v.OutputSocket == null)
                {
                    invalidKeys.Add(key); //null output socket -> remove key
                    continue;
                }

                if (v.InputSocket == null)
                {
                    invalidKeys.Add(key);                        //null input socket -> remove key
                }
            }

            foreach (string invalidKey in invalidKeys)
            {
                ConnectionsDatabase.Remove(invalidKey);                                        //remove invalid keys
            }
        }
            public override async ValueTask <Connection> AcceptAsync(IConnectionProperties options = null, CancellationToken cancellationToken = default)
            {
                using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, cancellationToken);

                var network          = new VirtualNetwork();
                var serverConnection = new VirtualConnection(network, isServer: true);
                var clientConnection = new VirtualConnection(network, isServer: false);

                while (true)
                {
                    TaskCompletionSource <Connection> tcs = await _pendingConnects.Reader.ReadAsync(cancellationToken);

                    if (tcs.TrySetResult(clientConnection))
                    {
                        return(serverConnection);
                    }
                }
            }
Esempio n. 15
0
        /// <summary> Draws the connection curves of a virtual connection </summary>
        /// <param name="vc">Target virtual connection being drawn</param>
        private void DrawConnectionCurve(VirtualConnection vc)
        {
            //connect
            m_connectionAlpha = 1f;
            if (m_mode == GraphMode.Connect)
            {
                m_connectionAlpha = 0.5f;
            }

            m_normalColor = DGUI.Utility.IsProSkin
                                ? DGUI.Colors.GetDColor(ColorName.UnityDark).Light
                                : DGUI.Colors.GetDColor(ColorName.UnityLight).Dark;
            m_outputColor = DGUI.Colors.GetDColor(DGUI.Colors.NodyOutputColorName).Normal;
            m_inputColor  = DGUI.Colors.GetDColor(DGUI.Colors.NodyInputColorName).Normal;

            m_normalColor.a = m_connectionAlpha;
            m_outputColor.a = m_connectionAlpha;
            m_inputColor.a  = m_connectionAlpha;

            m_connectionColor = m_normalColor;

            m_animateInput  = false;
            m_animateOutput = false;

            //A node is selected and the Alt Key is not pressed -> show the connection color depending on socket type of this node (if it is an output or an input one)
            if (WindowSettings.SelectedNodes.Count == 1 && !m_altKeyPressed)
            {
                //                Node selectedNode = NodesDatabase[m_selectedNodes.Ids[0]];
                Node selectedNode = WindowSettings.SelectedNodes[0];
                if (selectedNode == null)
                {
                    return;
                }
                if (selectedNode.ContainsConnection(vc.ConnectionId))
                {
                    if (selectedNode == vc.OutputNode)
                    {
                        //color for output connection
                        m_connectionColor = m_outputColor;
                        m_animateOutput   = true;
                    }

                    if (selectedNode == vc.InputNode)
                    {
                        //color for input connection
                        m_connectionColor = m_inputColor;
                        m_animateInput    = true;
                    }
                }
            }

            float currentCurveWidth = NodySettings.Instance.CurveWidth;

            if (EditorApplication.isPlaying)
            {
                if (vc.InputNode.GetConnection(vc.ConnectionId).Ping)
                {
                    vc.Ping.value  = true;
                    vc.Ping.target = false;
                    vc.InputNode.GetConnection(vc.ConnectionId).Ping = false;
                }
                else if (vc.OutputNode.GetConnection(vc.ConnectionId).Ping)
                {
                    vc.Ping.value  = true;
                    vc.Ping.target = false;
                    vc.OutputNode.GetConnection(vc.ConnectionId).Ping = false;
                }

                if (vc.Ping.faded > 0)
                {
                    m_connectionColor = Color.LerpUnclamped(m_connectionColor, DGUI.Colors.GetDColor(DGUI.Colors.ActionColorName).Normal, vc.Ping.faded);
                    currentCurveWidth = NodySettings.Instance.CurveWidth * (1 + 2 * vc.Ping.faded);
                }
            }
            else if (vc.Ping.faded > 0)
            {
                vc.Ping.value  = false;
                vc.Ping.target = false;
            }


            m_dotColor = m_connectionColor;


            if (m_altKeyPressed) //delete mode is enabled -> check if we should color the connection to RED
            {
                //check this connection's points by testing if the mouse if hovering over one of this connection's virtual points
                bool colorTheConnectionRed = vc.InputVirtualPoint == m_currentHoveredVirtualPoint || vc.OutputVirtualPoint == m_currentHoveredVirtualPoint;
                if (colorTheConnectionRed)
                {
                    m_connectionColor  = Color.red; //set the connection color to RED -> as the developer might want to remove this connection
                    currentCurveWidth += 1;         //make the red curve just a tiny bit more thick to make it stand out even better
                }
            }

            m_connectionBackgroundColor = new Color(m_connectionColor.r * 0.2f,
                                                    m_connectionColor.g * 0.2f,
                                                    m_connectionColor.b * 0.2f,
                                                    m_connectionAlpha - 0.2f);
            HandleMaterial.SetPass(0);
            HandleUtility.handleMaterial.SetPass(0);

            Handles.DrawBezier(vc.OutputVirtualPoint.Rect.position,
                               vc.InputVirtualPoint.Rect.position,
                               vc.OutputTangent,
                               vc.InputTangent,
                               m_connectionBackgroundColor,
                               null,
                               currentCurveWidth + 2);
            Handles.DrawBezier(vc.OutputVirtualPoint.Rect.position,
                               vc.InputVirtualPoint.Rect.position,
                               vc.OutputTangent,
                               vc.InputTangent,
                               m_connectionColor,
                               null,
                               currentCurveWidth);

            if (!HasFocus)
            {
                return;                                      //if the window does not have focus -> return (DO NOT PLAY ANIMATION)
            }
            if (!MouseInsideWindow)
            {
                return;                                      //if the mouse is not inside the window -> return (DO NOT PLAY ANIMATION)
            }
            if (!m_animateInput && !m_animateOutput)
            {
                return;                                      //if the animation is not enabled for both points -> return (DO NOT PLAY ANIMATION)
            }
            m_numberOfPoints = (int)(Vector2.Distance(vc.OutputVirtualPoint.Rect.position,
                                                      vc.InputVirtualPoint.Rect.position) *
                                     NodySettings.Instance.CurvePointsMultiplier);  //points multiplier - useful for a smooth dot travel - smaller means fewer travel point (makes the point 'jumpy') and higher means more travel points (make the point move smoothly)
            if (m_numberOfPoints <= 0)
            {
                return;
            }
            m_bezierPoints = Handles.MakeBezierPoints(vc.OutputVirtualPoint.Rect.position,
                                                      vc.InputVirtualPoint.Rect.position,
                                                      vc.OutputTangent,
                                                      vc.InputTangent,
                                                      m_numberOfPoints);

            m_dotPointIndex = 0;
            m_numberOfPoints--; //we set the number of points as the bezierPoints length - 1

            if (m_animateInput)
            {
                m_dotPointIndex = (int)(AnimationTime * m_numberOfPoints);
            }
            else if (m_animateOutput)
            {
                m_dotPointIndex = m_numberOfPoints - (int)((1 - AnimationTime) * m_numberOfPoints);
            }

            m_dotPointIndex = Mathf.Clamp(m_dotPointIndex, 0, m_numberOfPoints);

            m_dotPoint = m_bezierPoints[m_dotPointIndex];

            m_dotSize = currentCurveWidth * 2;

            //make the dot a bit brighter
            m_dotColor = new Color(m_dotColor.r * 1.2f,
                                   m_dotColor.g * 1.2f,
                                   m_dotColor.b * 1.2f,
                                   m_dotColor.a);

            GUI.color = m_dotColor;
            GUI.Box(new Rect(m_dotPoint.x - m_dotSize / 2, m_dotPoint.y - m_dotSize / 2, m_dotSize, m_dotSize), "", DotStyle);
            GUI.color = Color.white;
        }
Esempio n. 16
0
        private void CalculateConnectionCurve(VirtualConnection vc)
        {
            //get the lists of all the calculated virtual points for both sockets
            List <VirtualPoint> outputVirtualPoints = PointsDatabase[vc.OutputSocket.Id];
            List <VirtualPoint> inputVirtualPoints  = PointsDatabase[vc.InputSocket.Id];

            //get both OutputSocket and InputSocket rects converted to WorldSpace
            Rect outputSocketWorldRect = GetSocketWorldRect(vc.OutputSocket);
            Rect inputSocketWorldRect  = GetSocketWorldRect(vc.InputSocket);

            //get position values needed to determine the connection points and curve settings
            //            float outputSocketCenter = (outputSocketWorldRect.center.x + PanOffset.x) / Zoom;
            float outputSocketCenter = outputSocketWorldRect.center.x;
            //            float inputSocketCenter = (inputSocketWorldRect.center.x + PanOffset.x) / Zoom;
            float inputSocketCenter = inputSocketWorldRect.center.x;

            //get the closest virtual points for both sockets
            float minDistance = 100000;

            foreach (VirtualPoint outputVirtualPoint in outputVirtualPoints)
            {
                foreach (VirtualPoint inputVirtualPoint in inputVirtualPoints)
                {
                    float currentDistance = Vector2.Distance(outputVirtualPoint.Rect.position, inputVirtualPoint.Rect.position);
                    if (currentDistance > minDistance)
                    {
                        continue;
                    }
                    vc.OutputVirtualPoint = outputVirtualPoint;
                    vc.InputVirtualPoint  = inputVirtualPoint;
                    minDistance           = currentDistance;
                }
            }

            //set both the output and the input points as their respective tangents
            Vector2 zoomedPanOffset = CurrentPanOffset / CurrentZoom;

            Vector2 outputPoint     = vc.OutputVirtualPoint.Rect.position - zoomedPanOffset;
            Vector2 inputPoint      = vc.InputVirtualPoint.Rect.position - zoomedPanOffset;
            float   outputNodeWidth = vc.OutputNode.GetWidth();
            float   inputNodeWidth  = vc.InputNode.GetWidth();
            float   widthDifference = outputNodeWidth > inputNodeWidth ? outputNodeWidth - inputNodeWidth : inputNodeWidth - outputNodeWidth;

            vc.OutputTangent = outputPoint + zoomedPanOffset;
            vc.InputTangent  = inputPoint + zoomedPanOffset;

            //UP TO THIS POINT WE HAVE A STRAIGHT LINE
            //from here we start calculating the custom tangent values -> thus turning our connection line into a dynamic curve

            Vector2 outputTangentArcDirection; //output point tangent
            Vector2 inputTangentArcDirection;  //input point tangent

            //OUTPUT RIGHT CONNECTION
            if (outputSocketCenter < inputSocketCenter && outputSocketCenter <= inputPoint.x ||
                outputSocketCenter >= inputSocketCenter && outputPoint.x >= inputSocketCenter && outputSocketCenter <= inputPoint.x)
            {
                //                DDebug.Log("OUTPUT RIGHT");
                if (outputPoint.x <= inputSocketCenter + widthDifference / 2 && inputSocketCenter > outputPoint.x)
                {
                    outputTangentArcDirection = Vector2.right;
                    inputTangentArcDirection  = Vector2.left;
                }
                else
                {
                    outputTangentArcDirection = Vector2.right;
                    inputTangentArcDirection  = Vector2.right;
                }
            }
            //OUTPUT LEFT CONNECTION
            else
            {
                //                DDebug.Log("OUTPUT LEFT");
                if (outputPoint.x >= inputSocketCenter)
                {
                    outputTangentArcDirection = Vector2.left;
                    inputTangentArcDirection  = Vector2.right;
                }
                else
                {
                    outputTangentArcDirection = Vector2.left;
                    inputTangentArcDirection  = Vector2.left;
                }
            }

            //set the curve strength (curvature) to be dynamic, by taking into account the distance between the connection points
            float outputCurveStrength = minDistance * (NodySettings.Instance.CurveStrengthModifier + vc.OutputSocket.CurveModifier);
            float inputCurveStrength  = minDistance * (NodySettings.Instance.CurveStrengthModifier + vc.InputSocket.CurveModifier);

            //update the tangents with the dynamic values
            vc.OutputTangent += outputTangentArcDirection * outputCurveStrength;
            vc.InputTangent  += inputTangentArcDirection * inputCurveStrength;
        }
Esempio n. 17
0
    public static (List <List <IShape> >, List <(IShape, List <IShape>)>) Run(int min, int max, uint times)
    {
        Rules rules = new Rules();

        rules.AddRule(
            new Attributes(
                ("Floors", new ScalarAttribute(3f))
                ),
            (Start start) => {
            Vertex[] v1 = start.l2.Sections(0.3f, 0.65f);
            Vertex[] v2 = start.l4.Sections(0.35f, 0.7f);

            Floor f1 = new Floor(rules, start.Attributes.Copy(), (0, 2), (start.v1, start.v2, v1[1], v2[0]));
            Floor f2 = new Floor(rules, start.Attributes.Copy(), (0, 1), (v2[0], v1[1], v1[0], v2[1]));
            Floor f3 = new Floor(rules, start.Attributes.Copy(), (0, 0), (v2[1], v1[0], start.v3, start.v4));

            return(new List <IShape> {
                f1, f2, f3
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Floors", new ScalarAttribute(2f)),
                ("Wide", new ScalarAttribute(0f))
                ),
            (Start start) => {
            Vertex[] v1 = start.l1.Sections(4);
            Vertex[] v2 = start.l3.Sections(4);

            Attributes a = start.Attributes.Copy();
            a.Set("RoofSlanted", new ScalarAttribute(1f));

            Vertical s1 = new Vertical(rules, a.Copy(), (0, 0), (start.v1, v1[3], v2[0], start.v4));
            Vertical s2 = new Vertical(rules, start.Attributes.Copy(), (1, 0), (v1[3], v1[2], v2[1], v2[0]));
            Vertical s3 = new Vertical(rules, start.Attributes.Copy(), (2, 0), (v1[2], v1[1], v2[2], v2[1]));
            Vertical s4 = new Vertical(rules, start.Attributes.Copy(), (3, 0), (v1[1], v1[0], v2[3], v2[2]));
            Vertical s5 = new Vertical(rules, a.Copy(), (4, 0), (v1[0], start.v2, start.v3, v2[3]));

            VirtualConnection.Connect(s1, s5, true, false, true);

            return(new List <IShape> {
                s1, s2, s3, s4, s5
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Floors", new ScalarAttribute(2f)),
                ("Wide", new ScalarAttribute(1f))
                ),
            (Start start) => {
            Vertex[] v1 = start.l1.Sections(10);
            Vertex[] v2 = start.l3.Sections(10);

            Vertical s1  = new Vertical(rules, start.Attributes.Copy(), (0, 0), (start.v1, v1[9], v2[0], start.v4));
            Vertical s2  = new Vertical(rules, start.Attributes.Copy(), (1, 0), (v1[9], v1[8], v2[1], v2[0]));
            Vertical s3  = new Vertical(rules, start.Attributes.Copy(), (2, 0), (v1[8], v1[7], v2[2], v2[1]));
            Vertical s4  = new Vertical(rules, start.Attributes.Copy(), (3, 0), (v1[7], v1[6], v2[3], v2[2]));
            Vertical s5  = new Vertical(rules, start.Attributes.Copy(), (4, 0), (v1[6], v1[5], v2[4], v2[3]));
            Vertical s6  = new Vertical(rules, start.Attributes.Copy(), (5, 0), (v1[5], v1[4], v2[5], v2[4]));
            Vertical s7  = new Vertical(rules, start.Attributes.Copy(), (6, 0), (v1[4], v1[3], v2[6], v2[5]));
            Vertical s8  = new Vertical(rules, start.Attributes.Copy(), (7, 0), (v1[3], v1[2], v2[7], v2[6]));
            Vertical s9  = new Vertical(rules, start.Attributes.Copy(), (8, 0), (v1[2], v1[1], v2[8], v2[7]));
            Vertical s10 = new Vertical(rules, start.Attributes.Copy(), (9, 0), (v1[1], v1[0], v2[9], v2[8]));
            Vertical s11 = new Vertical(rules, start.Attributes.Copy(), (10, 0), (v1[0], start.v2, start.v3, v2[9]));

            return(new List <IShape> {
                s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("RoofSlanted", new ScalarAttribute(0f))
                ),
            (Vertical vertical) => {
            Vertex[] v1 = vertical.l2.Sections(0.3f, 0.65f);
            Vertex[] v2 = vertical.l4.Sections(0.35f, 0.7f);

            Section s1 = new Section(rules, vertical.Attributes.Copy(), (0, 2), (vertical.v1, vertical.v2, v1[1], v2[0]));
            Section s2 = new Section(rules, vertical.Attributes.Copy(), (0, 1), (v2[0], v1[1], v1[0], v2[1]));
            Roof r     = new Roof(rules, vertical.Attributes.Copy(), (0, 0), (v2[1], v1[0], vertical.v3, vertical.v4));

            return(new List <IShape> {
                s1, s2, r
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("RoofSlanted", new ScalarAttribute(1f))
                ),
            (Vertical vertical) => {
            Vertex[] v1 = vertical.l2.Sections(0.3f, 0.65f);
            Vertex[] v2 = vertical.l4.Sections(0.35f, 0.7f);

            Section s = new Section(rules, vertical.Attributes.Copy(), (0, 2), (vertical.v1, vertical.v2, v1[1], v2[0]));
            Roof r    = new Roof(rules, vertical.Attributes.Copy(), (0, 1), (v2[0], v1[1], v1[0], v2[1]));

            return(new List <IShape> {
                s, r
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("RoofSlanted", new ScalarAttribute(1f))
                ),
            (Roof roof) => {
            Vertex v = roof.l2.Bisect();
            Triad t  = new Triad(rules, roof.Attributes.Copy(), (0, 0), (v, roof.v1, roof.v2));

            return(new List <IShape> {
                t
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("RoofSize", new ScalarAttribute(1f)),
                ("RoofSlanted", new ScalarAttribute(0f))
                ),
            (Roof roof) => {
            Vertex v1 = roof.l2.Bisect(0.6f);
            Vertex v2 = roof.l4.Bisect(0.4f);

            Quad q = new Quad(rules, roof.Attributes.Copy(), (0, 0), (roof.v2, v1, v2, roof.v1));

            return(new List <IShape> {
                q
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("RoofSize", new ScalarAttribute(2f)),
                ("RoofSlanted", new ScalarAttribute(0f))
                ),
            (Roof roof) => {
            Vertex v1 = roof.l2.Bisect(0.7f);
            Vertex v2 = roof.l4.Bisect(0.3f);

            Quad q = new Quad(rules, roof.Attributes.Copy(), (0, 0), (roof.v2, v1, v2, roof.v1));

            return(new List <IShape> {
                q
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("RoofSize", new ScalarAttribute(3f)),
                ("RoofSlanted", new ScalarAttribute(0f))
                ),
            (Roof roof) => {
            Vertex v1 = roof.l2.Bisect(0.8f);
            Vertex v2 = roof.l4.Bisect(0.2f);

            Quad q = new Quad(rules, roof.Attributes.Copy(), (0, 0), (roof.v2, v1, v2, roof.v1));

            return(new List <IShape> {
                q
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Sections", new ScalarAttribute(5f))
                ),
            (Floor floor) => {
            Vertex[] v1 = floor.l1.Sections(4);
            Vertex[] v2 = floor.l3.Sections(4);

            Section s1 = new Section(rules, floor.Attributes.Copy(), (0, 0), (floor.v1, v1[3], v2[0], floor.v4));
            Section s2 = new Section(rules, floor.Attributes.Copy(), (1, 0), (v1[3], v1[2], v2[1], v2[0]));
            Section s3 = new Section(rules, floor.Attributes.Copy(), (2, 0), (v1[2], v1[1], v2[2], v2[1]));
            Section s4 = new Section(rules, floor.Attributes.Copy(), (3, 0), (v1[1], v1[0], v2[3], v2[2]));
            Section s5 = new Section(rules, floor.Attributes.Copy(), (4, 0), (v1[0], floor.v2, floor.v3, v2[3]));

            return(new List <IShape> {
                s1, s2, s3, s4, s5
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Sections", new ScalarAttribute(4f))
                ),
            (Floor floor) => {
            Vertex[] v1 = floor.l1.Sections(3);
            Vertex[] v2 = floor.l3.Sections(3);

            Section s1 = new Section(rules, floor.Attributes.Copy(), (0, 0), (floor.v1, v1[2], v2[0], floor.v4));
            Section s2 = new Section(rules, floor.Attributes.Copy(), (1, 0), (v1[2], v1[1], v2[1], v2[0]));
            Section s3 = new Section(rules, floor.Attributes.Copy(), (2, 0), (v1[1], v1[0], v2[2], v2[1]));
            Section s4 = new Section(rules, floor.Attributes.Copy(), (4, 0), (v1[0], floor.v2, floor.v3, v2[2]));

            return(new List <IShape> {
                s1, s2, s3, s4
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Door", new ScalarAttribute(0f)),
                ("Corn", new ScalarAttribute(1f)),
                ("Bar", new ScalarAttribute(1f)),
                ("Stairs", new ScalarAttribute(0f))
                ),
            (Section section) => {
            Vertex[] v1 = section.l2.Sections(0.1f, 0.85f);
            Vertex[] v2 = section.l4.Sections(0.15f, 0.9f);

            Attributes a = section.Attributes.Copy();
            a.Set("Corn", new ScalarAttribute(0f));
            a.Set("Bar", new ScalarAttribute(0f));

            Attributes b = a.Copy();
            b.Set("R", new ScalarAttribute(255f));
            b.Set("G", new ScalarAttribute(255f));
            b.Set("B", new ScalarAttribute(255f));

            Cornice c = new Cornice(rules, b.Copy(), (0, 0), (section.v1, section.v2, v1[1], v2[0]));
            Section s = new Section(rules, a, (0, 1), (v2[0], v1[1], v1[0], v2[1]));
            Bar bar   = new Bar(rules, b.Copy(), (0, 2), (v2[1], v1[0], section.v3, section.v4));

            return(new List <IShape> {
                c, s, bar
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Door", new ScalarAttribute(0f)),
                ("Corn", new ScalarAttribute(1f)),
                ("Bar", new ScalarAttribute(0f)),
                ("Stairs", new ScalarAttribute(0f))
                ),
            (Section section) => {
            Vertex[] v1 = section.l2.Sections(0.1f);
            Vertex[] v2 = section.l4.Sections(0.9f);

            Attributes a = section.Attributes.Copy();
            a.Set("Corn", new ScalarAttribute(0f));
            a.Set("Bar", new ScalarAttribute(0f));

            Attributes b = a.Copy();
            b.Set("R", new ScalarAttribute(255f));
            b.Set("G", new ScalarAttribute(255f));
            b.Set("B", new ScalarAttribute(255f));

            Section s = new Section(rules, a, (0, 0), (section.v1, section.v2, v1[0], v2[0]));
            Cornice c = new Cornice(rules, b, (0, 1), (v2[0], v1[0], section.v3, section.v4));

            return(new List <IShape> {
                s, c
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Corn", new ScalarAttribute(0f)),
                ("Bar", new ScalarAttribute(0f)),
                ("Door", new ScalarAttribute(0f)),
                ("Sections", new ScalarAttribute(4f)),
                ("Stairs", new ScalarAttribute(0f))
                ),
            (Section section) => {
            Vertex[] v1 = section.l1.Sections(0.25f, 0.75f);
            Vertex[] v2 = section.l3.Sections(0.25f, 0.75f);

            Line l1 = new Line(v1[0], v2[1]);
            Line l2 = new Line(v1[1], v2[0]);

            Vertex[] v3 = l1.Sections(0.1f, 0.82f);
            Vertex[] v4 = l2.Sections(0.1f, 0.82f);

            Quad q1 = new Quad(rules, section.Attributes.Copy(), (0, 0), (section.v1, section.v4, v2[0], v1[1]));
            Quad q2 = new Quad(rules, section.Attributes.Copy(), (0, 2), (v1[0], v2[1], section.v3, section.v2));

            Quad q3 = new Quad(rules, section.Attributes.Copy(), (0, 3), (v2[0], v4[0], v3[0], v2[1]));
            Quad q4 = new Quad(rules, section.Attributes.Copy(), (0, 4), (v1[1], v4[1], v3[1], v1[0]));

            Attributes a = section.Attributes.Copy();
            a.Set("R", new ScalarAttribute(255f));
            a.Set("G", new ScalarAttribute(255f));
            a.Set("B", new ScalarAttribute(255f));

            Window w = new Window(rules, a, (1, 0), (v4[0], v4[1], v3[1], v3[0]));

            return(new List <IShape> {
                q1, q2, q3, q4, w
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Corn", new ScalarAttribute(0f)),
                ("Bar", new ScalarAttribute(0f)),
                ("Door", new ScalarAttribute(0f)),
                ("Sections", new ScalarAttribute(5f)),
                ("Stairs", new ScalarAttribute(0f))
                ),
            (Section section) => {
            Vertex[] v1 = section.l1.Sections(0.2f, 0.8f);
            Vertex[] v2 = section.l3.Sections(0.2f, 0.8f);

            Line l1 = new Line(v1[0], v2[1]);
            Line l2 = new Line(v1[1], v2[0]);

            Vertex[] v3 = l1.Sections(0.1f, 0.82f);
            Vertex[] v4 = l2.Sections(0.1f, 0.82f);

            Quad q1 = new Quad(rules, section.Attributes.Copy(), (0, 0), (section.v1, section.v4, v2[0], v1[1]));
            Quad q2 = new Quad(rules, section.Attributes.Copy(), (0, 2), (v1[0], v2[1], section.v3, section.v2));

            Quad q3 = new Quad(rules, section.Attributes.Copy(), (0, 3), (v2[0], v4[0], v3[0], v2[1]));
            Quad q4 = new Quad(rules, section.Attributes.Copy(), (0, 4), (v1[1], v4[1], v3[1], v1[0]));

            Window w = new Window(rules, section.Attributes.Copy(), (1, 0), (v4[0], v4[1], v3[1], v3[0]));

            return(new List <IShape> {
                q1, q2, q3, q4, w
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Stairs", new ScalarAttribute(1f))
                ),
            (Section section) => {
            Vertex[] v1 = section.l1.Sections(0.15f, 0.85f);
            Vertex[] v2 = section.l3.Sections(0.15f, 0.85f);

            Quad q1 = new Quad(rules, section.Attributes.Copy(), (0, 0), (section.v1, section.v4, v2[0], v1[1]));
            Quad q2 = new Quad(rules, section.Attributes.Copy(), (0, 2), (v1[0], v2[1], section.v3, section.v2));

            Window w = new Window(rules, section.Attributes.Copy(), (1, 0), (v2[0], v1[1], v1[0], v2[1]));

            return(new List <IShape> {
                q1, q2, w
            });
        }
            );

        rules.AddRule(
            new Attributes(
                ("Door", new RangeAttribute(1f, 2f))
                ),
            (Section section) => {
            Vertex[] v1 = section.l2.Sections(0.20f, 0.25f);
            Vertex[] v2 = section.l4.Sections(0.75f, 0.8f);

            Line l = new Line(v1[1], v2[0]);

            Vertex[] v3 = l.Sections(0.07f, 0.93f);
            Vertex[] v4 = section.l1.Sections(0.07f, 0.93f);


            // Upper area
            Door door  = new Door(rules, section.Attributes.Copy(), (1, 0), (v4[1], v4[0], v3[1], v3[0]));
            Quad mid   = new Quad(rules, section.Attributes.Copy(), (2, 0), (v2[0], v1[1], v1[0], v2[1]));
            Quad upper = new Quad(rules, section.Attributes.Copy(), (3, 0), (v2[1], v1[0], section.v3, section.v4));

            // Sides
            Quad side1 = new Quad(rules, section.Attributes.Copy(), (0, 1), (section.v1, v2[0], v3[0], v4[1]));
            Quad side2 = new Quad(rules, section.Attributes.Copy(), (1, 1), (section.v2, v4[0], v3[1], v1[1]));

            return(new List <IShape> {
                door, mid, upper, side1, side2
            });
        }
            );

        rules.AddRule(
            new Attributes(

                ),
            (Window window) => {
            Vertex[] v1 = window.l1.Sections(0.05f, 0.95f);
            Vertex[] v2 = window.l3.Sections(0.05f, 0.95f);

            Line l1 = new Line(v1[0], v2[1]);
            Line l2 = new Line(v1[1], v2[0]);

            Vertex[] v3 = l1.Sections(0.1f, 0.9f);
            Vertex[] v4 = l2.Sections(0.1f, 0.9f);

            Quad q1 = new Quad(rules, window.Attributes.Copy(), (0, 0), (window.v1, window.v4, v2[0], v1[1]));
            Quad q2 = new Quad(rules, window.Attributes.Copy(), (0, 2), (v1[0], v2[1], window.v3, window.v2));

            Quad q3 = new Quad(rules, window.Attributes.Copy(), (0, 3), (v2[0], v4[0], v3[0], v2[1]));
            Quad q4 = new Quad(rules, window.Attributes.Copy(), (0, 4), (v1[1], v4[1], v3[1], v1[0]));

            Glass g = new Glass(rules, window.Attributes.Copy(), (1, 0), (v4[0], v4[1], v3[1], v3[0]));

            return(new List <IShape> {
                q1, q2, q3, q4, g
            });
        }