Esempio n. 1
0
        public List <Schematic> resolve(sharptest.ModLibrary library)
        {
            if (library == null)
            {
                throw new ArgumentNullException("library");
            }
            if (this.contents.Count == 0 || this.connections.Count == 0)
            {
                return(null);
            }
            if (!isFullyConnected())
            {
                throw new ApplicationException("schematic is not fully connected");
            }

            foreach (Element elm in this.contents.Values)
            {
                elm.populateAvail(library);
            }

            Schematic all = this.Clone();

            Dictionary <int, Element> .Enumerator firstEnum = all.contents.GetEnumerator();
            firstEnum.MoveNext();
            Element first = firstEnum.Current.Value;
            Dictionary <int, bool> seen = new Dictionary <int, bool>();

            return(resolveImpl(library, all, seen, first.circuitId));
        }
Esempio n. 2
0
            public void populateAvail(sharptest.ModLibrary library)
            {
                if (library == null)
                {
                    throw new ArgumentNullException("library");
                }
                if (this.explicitAvail)
                {
                    return;
                }
                availObjects = new List <signals.ICircuitConnectible>();

                switch (this.type)
                {
                case ElementType.Module:
                    List <List <signals.IBlockDriver> > blocks = library.block(this.name);
                    if (blocks != null)
                    {
                        foreach (List <signals.IBlockDriver> variant in blocks)
                        {
                            foreach (signals.IBlockDriver driver in variant)
                            {
                                if (driver.canCreate)
                                {
                                    this.availObjects.Add(driver);
                                }
                                if (driver.canDiscover)
                                {
                                    signals.IBlock[] found = driver.Discover();
                                    foreach (signals.IBlock discBlk in found)
                                    {
                                        if (this.nodeId == null || String.Compare(discBlk.NodeId, this.nodeId, true) == 0)
                                        {
                                            this.availObjects.Add(discBlk);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;

                case ElementType.Function:
                case ElementType.FunctionOnIn:
                case ElementType.FunctionOnOut:
                    List <signals.IFunctionSpec> funcs = library.func(this.name);
                    if (funcs != null)
                    {
                        foreach (signals.IFunctionSpec spec in funcs)
                        {
                            this.availObjects.Add(spec);
                        }
                    }
                    break;
                }
            }
Esempio n. 3
0
        private static signals.IFunctionSpec findImplicitConversion(sharptest.ModLibrary library, signals.EType inpType, signals.EType outType)
        {
            List <signals.IFunctionSpec> idents = library.func("=");

            if (idents == null)
            {
                return(null);
            }
            foreach (signals.IFunctionSpec avail in idents)
            {
                signals.EType identInput  = avail.Fingerprint.inputs[0];
                signals.EType identOutput = avail.Fingerprint.outputs[0];
                if (inpType == identInput && outType == identOutput)
                {
                    return(avail);
                }
            }
            return(null);
        }
Esempio n. 4
0
        private static List <Schematic> resolveImpl(sharptest.ModLibrary library, Schematic here, Dictionary <int, bool> seen, int elmKey)
        {
            if (seen.ContainsKey(elmKey))
            {
                return new List <Schematic> {
                           here
                }
            }
            ;
            if (!here.contents.ContainsKey(elmKey))
            {
                throw new ApplicationException("couldn't kind elmKey in contents");
            }
            Element elm = here.contents[elmKey];

            seen.Add(elmKey, true);
            try
            {
                List <Schematic> answers = new List <Schematic>();
                ResolveFailure   failure = new ResolveFailure();
                if (elm.availObjects.Count == 0)
                {
                    failure.Add(new CannotResolveElement(elm));
                }
                foreach (signals.ICircuitConnectible avail in elm.availObjects)
                {
                    Schematic newSchem = here.Clone();
                    Element   newElem  = newSchem.contents[elmKey];
                    newElem.availObjects.Clear();
                    newElem.availObjects.Add(avail);

                    try
                    {
                        newSchem.resolveNeighbors(library, newElem);
                    }
                    catch (ResolveFailureReason fault)
                    {
                        failure.Add(fault);
                        continue;
                    }

                    Dictionary <int, bool> recurseList = new Dictionary <int, bool>();
                    foreach (KeyValuePair <EndpointKey, EndpointKey> entry in newSchem.connections)
                    {
                        EndpointKey key   = entry.Key;
                        EndpointKey value = entry.Value;
                        if (key.elem == newElem)
                        {
                            if (!seen.ContainsKey(value.elem.circuitId))
                            {
                                recurseList.Add(value.elem.circuitId, true);
                            }
                        }
                        else if (value.elem == newElem)
                        {
                            if (!seen.ContainsKey(key.elem.circuitId))
                            {
                                recurseList.Add(key.elem.circuitId, true);
                            }
                        }
                    }
                    List <Schematic> possibles = new List <Schematic>();
                    possibles.Add(newSchem);
                    foreach (KeyValuePair <int, bool> entry in recurseList)
                    {
                        List <Schematic> prevPass = possibles;
                        possibles = new List <Schematic>();
                        foreach (Schematic possible in prevPass)
                        {
                            try
                            {
                                possibles.AddRange(resolveImpl(library, possible, seen, entry.Key));
                            }
                            catch (ResolveFailure fail)
                            {
                                failure.Add(fail);
                            }
                        }
                    }
                    answers.AddRange(possibles);
                }
                if (answers.Count == 0 && failure.reasons.Count > 0)
                {
                    throw failure;
                }
                return(answers);
            }
            finally
            {
                seen.Remove(elmKey);
            }
        }
Esempio n. 5
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);
                }
            }
        }