예제 #1
0
        public Circuit construct()
        {
            Dictionary <int, Circuit.Element> result    = new Dictionary <int, Circuit.Element>();
            Dictionary <Element, object>      elmResult = new Dictionary <Element, object>();

            foreach (KeyValuePair <int, Element> here in contents)
            {
                Element elm = here.Value;
                if (elm.availObjects.Count != 1)
                {
                    throw new ApplicationException("expecting all elements to have exactly one solution");
                }
                signals.ICircuitConnectible avail = elm.availObjects[0];
                signals.ICircuitElement     newOb = null;
                switch (elm.type)
                {
                case ElementType.Module:
                {
                    signals.IBlockDriver drv = avail as signals.IBlockDriver;
                    if (drv != null)
                    {
                        newOb = drv.Create();
                    }
                    else
                    {
                        newOb = (signals.IBlock)avail;
                    }
                    break;
                }

                case ElementType.Function:
                case ElementType.FunctionOnIn:
                case ElementType.FunctionOnOut:
                    newOb = ((signals.IFunctionSpec)avail).Create();
                    break;
                }
                result.Add(elm.circuitId, new Circuit.Element(new ElemKey(elm), elm.circuitId, newOb));
                elmResult.Add(elm, newOb);
            }

            foreach (KeyValuePair <EndpointKey, EndpointKey> conn in connections)
            {
                EndpointKey from    = conn.Key;
                EndpointKey to      = conn.Value;
                object      fromObj = elmResult[from.elem];
                object      toObj   = elmResult[to.elem];
                switch (from.elem.type)
                {
                case ElementType.Module:
                {
                    signals.IOutEndpoint outEP = from.OutputEP((signals.IBlock)fromObj);
                    switch (to.elem.type)
                    {
                    case ElementType.Module:
                    {
                        signals.IEPBuffer   buff = outEP.CreateBuffer();
                        signals.IInEndpoint inEP = to.InputEP((signals.IBlock)toObj);
                        outEP.Connect(buff);
                        inEP.Connect(buff);
                        break;
                    }

                    case ElementType.Function:
                    case ElementType.FunctionOnIn:
                    {
                        signals.IEPBuffer   buff = outEP.CreateBuffer();
                        signals.IInEndpoint inEP = ((signals.IFunction)toObj).Input;
                        outEP.Connect(buff);
                        inEP.Connect(buff);
                        break;
                    }

                    case ElementType.FunctionOnOut:
                    {
                        signals.IEPSendTo inEP = ((signals.IFunction)toObj).Output;
                        outEP.Connect(inEP);
                        break;
                    }
                    }
                    break;
                }

                case ElementType.Function:
                case ElementType.FunctionOnIn:
                {
                    signals.IInputFunction func = ((signals.IFunction)fromObj).Input;
                    switch (to.elem.type)
                    {
                    case ElementType.Module:
                    {
                        signals.IInEndpoint inEP = to.InputEP((signals.IBlock)toObj);
                        inEP.Connect(func);
                        break;
                    }

                    case ElementType.Function:
                    case ElementType.FunctionOnIn:
                    {
                        signals.IInEndpoint inEP = ((signals.IFunction)toObj).Input;
                        inEP.Connect(func);
                        break;
                    }

                    case ElementType.FunctionOnOut:
                        throw new ApplicationException("incompatible connection types");
                    }
                    break;
                }

                case ElementType.FunctionOnOut:
                {
                    signals.IOutputFunction func = ((signals.IFunction)fromObj).Output;
                    switch (to.elem.type)
                    {
                    case ElementType.Module:
                    {
                        signals.IEPBuffer   buff = func.CreateBuffer();
                        signals.IInEndpoint inEP = to.InputEP((signals.IBlock)toObj);
                        func.Connect(buff);
                        inEP.Connect(buff);
                        break;
                    }

                    case ElementType.Function:
                    case ElementType.FunctionOnIn:
                    {
                        signals.IEPBuffer   buff = func.CreateBuffer();
                        signals.IInEndpoint inEP = ((signals.IFunction)toObj).Input;
                        func.Connect(buff);
                        inEP.Connect(buff);
                        break;
                    }

                    case ElementType.FunctionOnOut:
                    {
                        signals.IOutEndpoint outEP = ((signals.IFunction)toObj).Output;
                        outEP.Connect(func);
                        break;
                    }
                    }
                    break;
                }
                }
            }
            return(new Circuit(result));
        }
예제 #2
0
 public signals.EType OutputType(signals.ICircuitConnectible conn)
 {
     return(OutputType(conn.Fingerprint));
 }
예제 #3
0
        private void resolveNeighbors(sharptest.ModLibrary library, Element elm)
        {
            if (elm.availObjects.Count != 1)
            {
                throw new ApplicationException("elm should contain a single availObject by this point");
            }
            signals.ICircuitConnectible avail       = elm.availObjects[0];
            Dictionary <Element, bool>  recurseList = new Dictionary <Element, bool>();
            List <KeyValuePair <EndpointKey, EndpointKey> > tempCollect = new List <KeyValuePair <EndpointKey, EndpointKey> >();

            tempCollect.AddRange(connections);
            foreach (KeyValuePair <EndpointKey, EndpointKey> entry in tempCollect)
            {
                EndpointKey key   = entry.Key;
                EndpointKey value = entry.Value;
                if (key.elem == elm)
                {
                    Element       otherElm = value.elem;
                    signals.EType ourType  = key.OutputType(avail);
                    bool          changed  = false;
                    if (otherElm.availObjects.Count > 1)
                    {
                        // if we have more than one option here, just look for possible compatibility
                        List <signals.ICircuitConnectible> newAvail = new List <signals.ICircuitConnectible>();
                        foreach (signals.ICircuitConnectible otherAvail in otherElm.availObjects)
                        {
                            signals.EType otherType = value.InputType(otherAvail);
                            if (ourType != otherType && findImplicitConversion(library, ourType, otherType) == null)
                            {
                                changed = true;
                            }
                            else
                            {
                                newAvail.Add(otherAvail);
                            }
                        }
                        otherElm.availObjects = newAvail;
                    }
                    if (otherElm.availObjects.Count == 1)
                    {
                        // if we're on one-to-one terms, we might add compat connections
                        signals.ICircuitConnectible otherAvail = otherElm.availObjects[0];
                        signals.EType otherType = value.InputType(otherAvail);
                        if (ourType != otherType)
                        {
                            signals.IFunctionSpec func = findImplicitConversion(library, ourType, otherType);
                            if (func == null)
                            {
                                // only option isn't type-compatible? Looks like we broke a connection
                                throw new LinkTypeFailure(entry.Key, ourType, entry.Value, otherType);
                            }
                            else
                            {
                                AddImplicitConversion(key, value, func);
                            }
                        }
                    }
                    else if (otherElm.availObjects.Count == 0)
                    {
                        // ran out of possible connections? Looks like we broke a connection
                        throw new CannotResolveElement(otherElm);
                    }
                    if (changed)
                    {
                        recurseList.Add(value.elem, true);
                    }
                }
                if (value.elem == elm)
                {
                    Element       otherElm = key.elem;
                    signals.EType ourType  = value.InputType(avail);
                    bool          changed  = false;
                    if (otherElm.availObjects.Count > 1)
                    {
                        // if we have more than one option here, just look for possible compatibility
                        List <signals.ICircuitConnectible> newAvail = new List <signals.ICircuitConnectible>();
                        foreach (signals.ICircuitConnectible otherAvail in otherElm.availObjects)
                        {
                            signals.EType otherType = key.OutputType(otherAvail);
                            if (ourType != otherType && findImplicitConversion(library, otherType, ourType) == null)
                            {
                                changed = true;
                            }
                            else
                            {
                                newAvail.Add(otherAvail);
                            }
                        }
                        otherElm.availObjects = newAvail;
                    }
                    if (otherElm.availObjects.Count == 1)
                    {
                        // if we're on one-to-one terms, we might add compat connections
                        signals.ICircuitConnectible otherAvail = otherElm.availObjects[0];
                        signals.EType otherType = key.OutputType(otherAvail);
                        if (ourType != otherType)
                        {
                            signals.IFunctionSpec func = findImplicitConversion(library, otherType, ourType);
                            if (func == null)
                            {
                                // only option isn't type-compatible? Looks like we broke a connection
                                throw new LinkTypeFailure(entry.Key, otherType, entry.Value, ourType);
                            }
                            else
                            {
                                AddImplicitConversion(key, value, func);
                            }
                        }
                    }
                    else if (otherElm.availObjects.Count == 0)
                    {
                        // ran out of possible connections? Looks like we broke a connection
                        throw new CannotResolveElement(otherElm);
                    }
                    if (changed)
                    {
                        recurseList.Add(value.elem, true);
                    }
                }
            }
            foreach (KeyValuePair <Element, bool> entry in recurseList)
            {
                if (entry.Key.availObjects.Count == 1)
                {
                    resolveNeighbors(library, entry.Key);
                }
            }
        }