예제 #1
0
        public static SerializedGate SerializeTopLayer(ContextGate contextGate, List <Cable> cables)
        {
            var store = new SerializedGate();

            store.Name = contextGate.Name;
            store.Type = typeof(ContextGate).Name;
            store.Size = contextGate.Size;

            ExtractContext(store, contextGate, cables);

            return(store);
        }
예제 #2
0
        public static ContextGate DeserializeTopLayer(SerializedGate storageObject, List <Cable> cables)
        {
            if (storageObject.Type != "ContextGate")
            {
                throw new Exception("Object does not store an ContextGate");
            }
            ContextGate contextGate = new ContextGate();

            contextGate.Name = storageObject.Name;
            contextGate.Tag  = storageObject.Tag;
            contextGate.Size = storageObject.Size;
            var idToNode      = new Dictionary <int, ConnectionNode>();
            var cableEpToNode = new Dictionary <int, ConnectionNode>();
            var uncabledNodes = new LinkedList <ConnectionNode>();

            foreach (SerializedGate innerStore in storageObject.Context)
            {
                Gate innerGate = Deserialize(innerStore);
                if (!(innerGate is ContextGate))
                {
                    if (innerStore.InputLabels != null)
                    {
                        for (int i = 0; i < innerGate.Input.Count; i++)
                        {
                            innerGate.Input[i].Name = innerStore.InputLabels[i];
                        }
                    }
                    if (innerStore.OutputLabels != null)
                    {
                        for (int i = 0; i < innerGate.Output.Count; i++)
                        {
                            innerGate.Output[i].Name = innerStore.OutputLabels[i];
                        }
                    }
                }
                contextGate.Context.Add(innerGate);
                for (int i = 0; i < innerStore.OutputConnections.Count(); i++)
                {
                    int id = innerStore.OutputConnections[i];
                    if (id != 0)
                    {
                        idToNode[id] = innerGate.Output[i];
                    }
                }
            }

            for (int i = 0; i < storageObject.Context.Count; i++)
            {
                SerializedGate innerStore = storageObject.Context[i];
                Gate           innerGate  = contextGate.Context[i];
                for (int j = 0; j < innerStore.InputConnections.Count(); j++)
                {
                    int id = innerStore.InputConnections[j];
                    if (id != 0)
                    {
                        if (!idToNode.ContainsKey(id))
                        {
                            throw new InvalidOperationException("Invalid connection");
                        }
                        ConnectionNode thisNode  = innerGate.Input[j];
                        ConnectionNode otherNode = idToNode[id];
                        otherNode.NextConnectedTo.Add(thisNode);
                        thisNode.BackConnectedTo = otherNode;
                        otherNode.IsEmpty        = false;
                        thisNode.IsEmpty         = false;
                        thisNode.State           = thisNode.IsInverted ? !otherNode.State : otherNode.State;
                        if (innerStore.CableEndPoints != null)
                        {
                            int endpoint = innerStore.CableEndPoints[j];
                            cableEpToNode[endpoint] = thisNode;
                        }
                        uncabledNodes.AddLast(thisNode);
                    }
                }
            }

            if (storageObject.Cables == null)
            {
                return(contextGate);
            }

            foreach (SerializedGate.Cable cablestore in storageObject.Cables)
            {
                if (!idToNode.ContainsKey(cablestore.OutputConnection))
                {
                    continue;
                }
                ConnectionNode outputNode = idToNode[cablestore.OutputConnection];
                ConnectionNode inputNode  = cableEpToNode[cablestore.EndPoint];
                Cable          cable      = new Cable(outputNode);
                foreach (Point point in cablestore.Points)
                {
                    cable.AddSegment(point);
                }
                cable.ConnectTo(inputNode, false);
                cables.Add(cable);
                uncabledNodes.Remove(inputNode);
            }

            foreach (ConnectionNode node in uncabledNodes)
            {
                Cable cable = new Cable(node.BackConnectedTo);
                cable.ConnectTo(node, false);
                cables.Add(cable);
            }

            return(contextGate);
        }
예제 #3
0
        public static Gate Deserialize(SerializedGate storageObject)
        {
            Gate gate;

            switch (storageObject.Type)
            {
            case "ContextGate":
                gate = new ContextGate();
                break;

            case "AndGate":
                gate = new AndGate();
                break;

            case "OrGate":
                gate = new OrGate();
                break;

            case "NopGate":
                gate = new NopGate();
                break;

            case "InputSwitch":
                gate = new InputSwitch();
                break;

            case "OutputLight":
                gate = new OutputLight();
                break;

            case "SegmentDisplay":
                gate = new SegmentDisplay();
                break;

            default:
                throw new InvalidOperationException("Unknown type");
            }

            gate.Name     = storageObject.Name;
            gate.Tag      = storageObject.Tag;
            gate.Position = storageObject.Position;
            gate.Size     = storageObject.Size;

            if (storageObject.InputConnections == null)
            {
                storageObject.InputConnections = new int[0];
            }
            if (storageObject.OutputConnections == null)
            {
                storageObject.OutputConnections = new int[0];
            }

            if (storageObject.Type == "ContextGate")
            {
                ContextGate contextGate  = gate as ContextGate;
                var         idToNode     = new Dictionary <int, ConnectionNode>();
                var         inputStores  = new List <SerializedGate>();
                var         outputStores = new List <SerializedGate>();
                var         gateStores   = new List <SerializedGate>();

                foreach (SerializedGate innerStore in storageObject.Context)
                {
                    switch (innerStore.Type)
                    {
                    case "InputSwitch":
                        inputStores.Add(innerStore);
                        break;

                    case "OutputLight":
                        outputStores.Add(innerStore);
                        break;

                    default:
                        gateStores.Add(innerStore);
                        break;
                    }
                }

                inputStores.Sort(ComparePosition);
                outputStores.Sort(ComparePosition);

                foreach (SerializedGate gateStore in gateStores)
                {
                    Gate innerGate = Deserialize(gateStore);
                    contextGate.Context.Add(innerGate);
                    for (int i = 0; i < gateStore.OutputConnections.Count(); i++)
                    {
                        int id = gateStore.OutputConnections[i];
                        if (id != 0)
                        {
                            idToNode[id] = innerGate.Output[i];
                        }
                    }
                }
                foreach (SerializedGate inputStore in inputStores)
                {
                    int id        = inputStore.OutputConnections.First();
                    var inputNode = new InputNode(contextGate);
                    inputNode.Name = inputStore.Name;
                    contextGate.Input.Add(inputNode);
                    if (id != 0)
                    {
                        idToNode[id] = inputNode;
                    }
                }

                for (int i = 0; i < gateStores.Count; i++)
                {
                    SerializedGate innerStore = gateStores[i];
                    Gate           innerGate  = contextGate.Context[i];
                    for (int j = 0; j < innerStore.InputConnections.Count(); j++)
                    {
                        int id = innerStore.InputConnections[j];
                        if (id != 0)
                        {
                            if (!idToNode.ContainsKey(id))
                            {
                                throw new InvalidOperationException("Invalid connection");
                            }
                            ConnectionNode thisNode  = innerGate.Input[j];
                            ConnectionNode otherNode = idToNode[id];
                            otherNode.NextConnectedTo.Add(thisNode);
                            thisNode.BackConnectedTo = otherNode;
                            //otherNode.IsEmpty = false;
                            //thisNode.IsEmpty = false;
                            thisNode.State = thisNode.IsInverted ? !otherNode.State : otherNode.State;
                        }
                    }
                }
                foreach (SerializedGate outputStore in outputStores)
                {
                    int        id          = outputStore.InputConnections.First();
                    OutputNode contextNode = new OutputNode(contextGate);
                    contextNode.Name = outputStore.Name;
                    contextGate.Output.Add(contextNode);
                    if (id != 0)
                    {
                        if (!idToNode.ContainsKey(id))
                        {
                            throw new InvalidOperationException("Invalid connection");
                        }
                        ConnectionNode otherNode = idToNode[id];
                        otherNode.NextConnectedTo.Add(contextNode);
                        contextNode.BackConnectedTo = otherNode;
                        //otherNode.IsEmpty = false;
                        //contextNode.IsEmpty = false;
                        contextNode.State = otherNode.State;
                    }
                }
            }
            else
            {
                foreach (int id in storageObject.InputConnections)
                {
                    gate.Input.Add(new InputNode(gate));
                }
                foreach (int id in storageObject.OutputConnections)
                {
                    gate.Output.Add(new OutputNode(gate));
                }
            }

            if (storageObject.InvertedInputs != null)
            {
                foreach (int index in storageObject.InvertedInputs)
                {
                    gate.Input[index].Invert();
                    gate.Input[index].State = !gate.Input[index].State;
                }
            }
            if (storageObject.InvertedOutputs != null)
            {
                foreach (int index in storageObject.InvertedOutputs)
                {
                    gate.Output[index].Invert();
                }
            }

            if (storageObject.InitialActiveOutputs != null)
            {
                foreach (int index in storageObject.InitialActiveOutputs)
                {
                    gate.Output[index].State = true;
                }
            }

            if (storageObject.RisingEdgeInputs != null)
            {
                foreach (int index in storageObject.RisingEdgeInputs)
                {
                    gate.Input[index].IsRisingEdge = true;
                }
            }

            if (storageObject.MasterSlaveOutputs != null)
            {
                foreach (int index in storageObject.MasterSlaveOutputs)
                {
                    gate.Output[index].IsMasterSlave = true;
                }
            }

            if (storageObject.CenteredInputs != null)
            {
                foreach (int index in storageObject.CenteredInputs)
                {
                    gate.Input[index].IsCentered = true;
                }
            }

            if (storageObject.CenteredOutputs != null)
            {
                foreach (int index in storageObject.CenteredOutputs)
                {
                    gate.Output[index].IsCentered = true;
                }
            }

            if (storageObject.Type == "InputSwitch")
            {
                ((InputSwitch)gate).State = gate.Output.First().IsInverted ? !gate.Output.First().State : gate.Output.First().State;
            }

            return(gate);
        }
예제 #4
0
        private static void ExtractContext(SerializedGate store, ContextGate contextGate, List <Cable> cables = null)
        {
            var contextCopy   = new List <Gate>(contextGate.Context);
            int nextId        = 1;
            int nextEp        = 1;
            var nodeToId      = new Dictionary <ConnectionNode, int>();
            var nodeToCableEp = new Dictionary <ConnectionNode, int>();
            var switches      = new List <SerializedGate>();
            var lights        = new List <SerializedGate>();

            store.Context = new List <SerializedGate>();

            for (int i = 0; i < contextGate.Input.Count; i++)
            {
                var inputSwitch = new InputSwitch();
                inputSwitch.Output.Add(new OutputNode(inputSwitch));
                //inputSwitch.UpdateConnectionNodePos();
                ConnectionNode contextNode = contextGate.Input[i];
                ConnectionNode switchNode  = inputSwitch.Output.First();
                switchNode.NextConnectedTo = contextNode.NextConnectedTo;
                inputSwitch.Position       = new Point(0, i);
                contextCopy.Add(inputSwitch);
            }
            foreach (Gate innerGate in contextCopy)
            {
                foreach (OutputNode output in innerGate.Output)
                {
                    if (output.NextConnectedTo.Count > 0)
                    {
                        nodeToId[output] = nextId;
                        foreach (ConnectionNode next in output.NextConnectedTo)
                        {
                            nodeToId[next] = nextId;
                        }
                        nextId++;
                    }
                    else
                    {
                        nodeToId[output] = 0;
                    }
                }
            }

            for (int i = 0; i < contextGate.Output.Count; i++)
            {
                int id;
                var outputLight = new OutputLight();
                outputLight.Input.Add(new InputNode(outputLight));
                //outputLight.UpdateConnectionNodePos();
                ConnectionNode contextNode = contextGate.Output[i];
                if (nodeToId.ContainsKey(contextNode))
                {
                    id = nodeToId[contextNode];
                    nodeToId.Remove(contextNode);
                }
                else
                {
                    id = 0;
                }
                ConnectionNode switchNode = outputLight.Input.First();
                nodeToId[switchNode] = id;
                outputLight.Position = new Point(1, i);
                contextCopy.Add(outputLight);
            }

            foreach (Gate innerGate in contextCopy)
            {
                SerializedGate innerStore = Serialize(innerGate);
                if (innerGate is InputSwitch)
                {
                    switches.Add(innerStore);
                }
                else if (innerGate is OutputLight)
                {
                    lights.Add(innerStore);
                }
                innerStore.InputConnections = new int[innerGate.Input.Count];
                if (cables != null)
                {
                    innerStore.CableEndPoints = new int[innerGate.Input.Count];
                }
                for (int i = 0; i < innerGate.Input.Count; i++)
                {
                    ConnectionNode node = innerGate.Input[i];
                    if (nodeToId.ContainsKey(node))
                    {
                        innerStore.InputConnections[i] = nodeToId[node];
                        if (cables != null)
                        {
                            innerStore.CableEndPoints[i] = nextEp;
                            nodeToCableEp[node]          = nextEp++;
                        }
                    }
                    else
                    {
                        innerStore.InputConnections[i] = 0;
                    }
                    if (node.Name != null)
                    {
                        if (innerStore.InputLabels == null)
                        {
                            innerStore.InputLabels = new string[innerGate.Input.Count];
                        }
                        innerStore.InputLabels[i] = node.Name;
                    }
                }
                innerStore.OutputConnections = new int[innerGate.Output.Count];
                for (int i = 0; i < innerGate.Output.Count; i++)
                {
                    ConnectionNode node = innerGate.Output[i];
                    if (nodeToId.ContainsKey(node))
                    {
                        innerStore.OutputConnections[i] = nodeToId[node];
                    }
                    else
                    {
                        throw new InvalidOperationException("Invalid connection");
                    }
                    if (node.Name != null)
                    {
                        if (innerStore.OutputLabels == null)
                        {
                            innerStore.OutputLabels = new string[innerGate.Output.Count];
                        }
                        innerStore.OutputLabels[i] = node.Name;
                    }
                }
                store.Context.Add(innerStore);
            }

            switches.Sort(ComparePosition);
            lights.Sort(ComparePosition);

            for (int i = 0; i < Math.Min(switches.Count, contextGate.Input.Count); i++)
            {
                switches[i].Name = contextGate.Input[i].Name;
            }
            for (int i = 0; i < Math.Min(lights.Count, contextGate.Output.Count); i++)
            {
                lights[i].Name = contextGate.Output[i].Name;
            }

            if (cables == null)
            {
                return;
            }
            store.Cables = new List <SerializedGate.Cable>();
            foreach (Cable cable in cables)
            {
                var cablestore = new SerializedGate.Cable();
                cablestore.Points = new List <Point>(cable.Points);
                ConnectionNode startNode, endNode;
                if (cable.StartNode is OutputNode)
                {
                    startNode = cable.StartNode;
                    endNode   = cable.EndNode;
                }
                else
                {
                    endNode   = cable.StartNode;
                    startNode = cable.EndNode;
                    cablestore.Points.Reverse();
                }
                if (nodeToId.ContainsKey(startNode))
                {
                    cablestore.OutputConnection = nodeToId[startNode];
                }
                if (nodeToCableEp.ContainsKey(endNode))
                {
                    cablestore.EndPoint = nodeToCableEp[endNode];
                }
                store.Cables.Add(cablestore);
            }
        }