예제 #1
0
        /// <summary>
        /// Use this block reference to derive a custom block based on the variable argument counts.
        /// </summary>
        /// <param name="?">original reference</param>
        /// <returns>derived description</returns>
        public AdvanceBlockDescription Derive(AdvanceBlockReference reference)
        {
            if (reference.Varargs.Count == 0)
            {
                return(this);
            }

            AdvanceBlockDescription result = new AdvanceBlockDescription();

            result.Assign(this);
            result.Inputs = new Dictionary <string, AdvanceBlockParameterDescription>();
            foreach (KeyValuePair <string, AdvanceBlockParameterDescription> e in this.Inputs)
            {
                int count;
                if (reference.Varargs.TryGetValue(e.Key, out count))
                {
                    for (int i = 1; i <= count; i++)
                    {
                        AdvanceBlockParameterDescription value = e.Value.Copy();
                        value.Type    = e.Value.Type; // keep shared type
                        value.Id      = e.Key + i;
                        value.Varargs = false;
                        result.Inputs.Add(value.Id, value);
                    }
                }
                else
                {
                    result.Inputs.Add(e.Key, e.Value);
                }
            }

            return(result);
        }
        /// <summary>
        /// Fill object data from xml node
        /// </summary>
        /// <param name="source">Source Xml</param>
        protected override void LoadFromXmlNode(XmlNode source)
        {
            this.Id            = GetAttribute(source, "id");
            this.Documentation = GetAttribute(source, "documentation", null);
            this.Keywords      = GetListAttribute(source, "keywords");
            this.Visuals       = CreateFromXml <AdvanceBlockVisuals>(source);
            HashSet <string> usedIds = new HashSet <string>();

            foreach (XmlNode n in GetChildren(source, "*"))
            {
                switch (n.Name)
                {
                case "block":
                    AdvanceBlockReference b = CreateFromXml <AdvanceBlockReference>(n);
                    b.parent = this;
                    if (usedIds.Contains(b.Id))
                    {
                        this.ThrowDuplicatedIdentifierException(n, b.Id);
                    }
                    else
                    {
                        this.Blocks.Add(b.Id, b);
                        usedIds.Add(b.Id);
                    }
                    break;

                case "composite-block":
                    AdvanceCompositeBlock cb = CreateFromXml <AdvanceCompositeBlock>(n);
                    cb.Parent = this;
                    if (usedIds.Contains(cb.Id))
                    {
                        this.ThrowDuplicatedIdentifierException(n, cb.Id);
                    }
                    else
                    {
                        this.Composites.Add(cb.Id, cb);
                        usedIds.Add(cb.Id);
                    }
                    break;

                case "constant":
                    AdvanceConstantBlock c = CreateFromXml <AdvanceConstantBlock>(n);
                    if (usedIds.Contains(c.Id))
                    {
                        this.ThrowDuplicatedIdentifierException(n, c.Id);
                    }
                    else
                    {
                        this.Constants.Add(c.Id, c);
                        usedIds.Add(c.Id);
                    }
                    break;

                case "bind":
                    AdvanceBlockBind bb = CreateFromXml <AdvanceBlockBind>(n);
                    bb.Parent = this;
                    this.Bindings.Add(bb);
                    break;

                case "type-variable":
                    AdvanceTypeVariable tv = CreateFromXml <AdvanceTypeVariable>(n);
                    if (!this.AddTypeVariable(tv))
                    {
                        this.ThrowDuplicatedIdentifierException(n, tv.Name);
                    }
                    break;

                case "input":
                    AdvanceCompositeBlockParameterDescription inp = CreateFromXml <AdvanceCompositeBlockParameterDescription>(n);
                    if (!this.AddInput(inp))
                    {
                        this.ThrowDuplicatedIdentifierException(n, inp.Id);
                    }
                    break;

                case "output":
                    AdvanceCompositeBlockParameterDescription outp = CreateFromXml <AdvanceCompositeBlockParameterDescription>(n);
                    if (!this.AddOutput(outp))
                    {
                        this.ThrowDuplicatedIdentifierException(n, outp.Id);
                    }
                    break;
                }
            }
            this.LinkTypeVariables();
        }