protected void InitSlotsFromProperties(IEnumerable <VFXPropertyWithValue> properties, VFXSlot.Direction direction)
 {
     foreach (var p in properties)
     {
         var slot = VFXSlot.Create(p, direction);
         InnerAddSlot(slot, -1, false);
     }
 }
Ejemplo n.º 2
0
        public void Init(Type _type)
        {
            if (_type != null && outputSlots.Count == 0)
            {
                VFXSlot slot = VFXSlot.Create(new VFXProperty(_type, "o"), VFXSlot.Direction.kOutput);
                AddSlot(slot);

                if (!typeof(UnityEngine.Object).IsAssignableFrom(_type))
                {
                    slot.value = System.Activator.CreateInstance(_type);
                }
            }
            else
            {
                throw new InvalidOperationException("Cannot init VFXParameter");
            }
            m_ExprSlots = outputSlots[0].GetVFXValueTypeSlots().ToArray();
            m_ValueExpr = m_ExprSlots.Select(t => t.DefaultExpression(valueMode)).ToArray();
        }
        protected bool SyncSlots(VFXSlot.Direction direction, bool notify)
        {
            bool isInput = direction == VFXSlot.Direction.kInput;

            var expectedProperties = (isInput ? inputProperties : outputProperties).ToArray();
            int nbSlots            = isInput ? GetNbInputSlots() : GetNbOutputSlots();
            var currentSlots       = isInput ? inputSlots : outputSlots;

            // check all slots owner (TODO Still useful?)
            for (int i = 0; i < nbSlots; ++i)
            {
                VFXSlot slot      = currentSlots[i];
                var     slotOwner = slot.owner as VFXSlotContainerModel <ParentType, ChildrenType>;
                if (slotOwner != this)
                {
                    Debug.LogError("Slot :" + slot.name + " of Container" + name + "Has a wrong owner.");
                    slot.SetOwner(this); // make sure everything works even if the owner was lost for some reason.
                }
            }

            bool recreate = false;

            if (nbSlots != expectedProperties.Length)
            {
                recreate = true;
            }
            else
            {
                for (int i = 0; i < nbSlots; ++i)
                {
                    if (!currentSlots[i].property.Equals(expectedProperties[i].property))
                    {
                        recreate = true;
                        break;
                    }
                }
            }

            if (recreate)
            {
                var existingSlots = new List <VFXSlot>(currentSlots);

                // Remove all slots
                for (int i = nbSlots - 1; i >= 0; --i)
                {
                    InnerRemoveSlot(currentSlots[i], false);
                }

                var newSlotCount = expectedProperties.Length;
                var newSlots     = new VFXSlot[newSlotCount];
                var createdSlots = new List <VFXSlot>(newSlotCount);

                // Reuse slots that already exists or create a new one if not
                for (int i = 0; i < newSlotCount; ++i)
                {
                    var p    = expectedProperties[i];
                    var slot = existingSlots.Find(s => p.property.Equals(s.property));
                    if (slot != null)
                    {
                        slot.UpdateAttributes(p.property.attributes);
                        existingSlots.Remove(slot);
                    }
                    else
                    {
                        slot = VFXSlot.Create(p, direction);
                        createdSlots.Add(slot);
                    }

                    newSlots[i] = slot;
                }

                for (int i = 0; i < createdSlots.Count; ++i)
                {
                    var dstSlot = createdSlots[i];

                    // Try to keep links and value for slots of same name and compatible types
                    var srcSlot = existingSlots.FirstOrDefault(s => s.property.name == dstSlot.property.name);

                    // Find the first slot with same type (should perform a more clever selection based on name distance)
                    if (srcSlot == null)
                    {
                        srcSlot = existingSlots.FirstOrDefault(s => s.property.type == dstSlot.property.type);
                    }

                    // Try to find a slot that can be implicitely converted
                    if (srcSlot == null)
                    {
                        srcSlot = existingSlots.FirstOrDefault(s => VFXConverter.CanConvertTo(s.property.type, dstSlot.property.type));
                    }

                    if (srcSlot != null)
                    {
                        VFXSlot.CopyLinksAndValue(dstSlot, srcSlot, notify);
                        srcSlot.UnlinkAll(true, notify);
                        existingSlots.Remove(srcSlot);
                    }
                }

                // Remove all remaining links
                foreach (var slot in existingSlots)
                {
                    slot.UnlinkAll(true, notify);
                }

                // Add all slots
                foreach (var s in newSlots)
                {
                    InnerAddSlot(s, -1, false);
                }

                if (notify)
                {
                    Invalidate(InvalidationCause.kStructureChanged);
                }
            }
            else
            {
                // Update properties
                for (int i = 0; i < nbSlots; ++i)
                {
                    VFXProperty prop = currentSlots[i].property;
                    currentSlots[i].UpdateAttributes(expectedProperties[i].property.attributes);
                }
            }

            return(recreate);
        }