コード例 #1
0
        /// <summary>
        /// Given the specified target <see cref="GameObject"/> and <see cref="Component"/> type,
        /// this method enumerates all <see cref="Component"/> types that will have to be created
        /// on the target object in order to satisfy its requirements. The result will be sorted
        /// in order of creation.
        /// </summary>
        /// <param name="targetObj"></param>
        /// <param name="targetComponentType"></param>
        /// <returns></returns>
        public IEnumerable <Type> GetRequirementsToCreate(GameObject targetObj, Type targetComponentType)
        {
            // Retrieve the component's requirements
            TypeData data;

            if (!this.typeDataCache.TryGetValue(targetComponentType, out data))
            {
                data = new TypeData(targetComponentType);
                this.typeDataCache[targetComponentType] = data;
            }
            data.EnsureCreationChain(this);

            // Create a sorted list of all components that need to be instantiated
            // in order to satisfy the requirements for adding the given component to
            // the specified object.
            List <Type> createList = new List <Type>(data.CreationChain.Count);

            for (int i = 0; i < data.CreationChain.Count; i++)
            {
                CreationChainItem item = data.CreationChain[i];
                if (targetObj.GetComponent(item.RequiredType) != null)
                {
                    i += item.SkipIfExists;
                    continue;
                }
                if (item.CreateType != null && !createList.Contains(item.CreateType))
                {
                    createList.Add(item.CreateType);
                }
            }
            return(createList);
        }
コード例 #2
0
            private void RemoveCreationChainDuplicates()
            {
                // We'll iterate over the creation chain assuming that each item
                // is found to be already existing (so we can't assume to have created
                // any specific type for abstract and interface requirements).
                List <TypeInfo> guaranteedTypes  = new List <TypeInfo>();
                int             uncertainCounter = 0;
                int             parentIndex      = -1;

                for (int i = 0; i < this.CreationChain.Count; i++)
                {
                    // Can we guarantee that all requirements of this item will have been met?
                    TypeInfo requriedTypeInfo = this.CreationChain[i].RequiredType.GetTypeInfo();
                    bool     requirementMet   = guaranteedTypes.Any(t => requriedTypeInfo.IsAssignableFrom(t));

                    // If yes, remove the item and its sub-chains
                    if (requirementMet)
                    {
                        int removeCount = 1 + this.CreationChain[i].SkipIfExists;
                        this.CreationChain.RemoveRange(i, removeCount);
                        if (uncertainCounter > 0)
                        {
                            CreationChainItem parentItem = this.CreationChain[parentIndex];
                            parentItem.SkipIfExists        -= removeCount;
                            this.CreationChain[parentIndex] = parentItem;
                            uncertainCounter -= removeCount;
                        }
                        i--;
                    }
                    // Otherwise, proceed to the next item
                    else
                    {
                        if (uncertainCounter == 0)
                        {
                            // If this item will create a Component, we can guarantee that its requirement is met
                            if (this.CreationChain[i].CreateType != null)
                            {
                                guaranteedTypes.Add(requriedTypeInfo);
                            }
                            // If this item might skip followup items, only allow to assume that the very last
                            // item's requirement will have been met, since after that one we can be sure that
                            // it was either there all along or was now created.
                            uncertainCounter += Math.Max(0, this.CreationChain[i].SkipIfExists - 1);
                            parentIndex       = i;
                        }
                        else
                        {
                            uncertainCounter--;
                        }
                    }
                }
            }