public void RecreateCopy()
        {
            if (m_SubChildren != null)
            {
                foreach (var child in m_SubChildren)
                {
                    if (child != null)
                    {
                        child.onInvalidateDelegate -= SubChildrenOnInvalidate;
                        ScriptableObject.DestroyImmediate(child, true);
                    }
                }
            }

            if (subgraph == null)
            {
                m_SubChildren = null;
                m_SubBlocks   = null;
                return;
            }

            var graph = m_Subgraph.GetResource().GetOrCreateGraph();
            HashSet <ScriptableObject> dependencies = new HashSet <ScriptableObject>();

            var context = graph.children.OfType <VFXBlockSubgraphContext>().FirstOrDefault();

            if (context == null)
            {
                m_SubChildren = null;
                m_SubBlocks   = null;
                return;
            }

            foreach (var child in graph.children.Where(t => t is VFXOperator || t is VFXParameter))
            {
                dependencies.Add(child);
                child.CollectDependencies(dependencies);
            }

            foreach (var block in context.children)
            {
                dependencies.Add(block);
                block.CollectDependencies(dependencies);
            }

            var copy = VFXMemorySerializer.DuplicateObjects(dependencies.ToArray());

            m_SubChildren = copy.OfType <VFXModel>().Where(t => t is VFXBlock || t is VFXOperator || t is VFXParameter).ToArray();
            m_SubBlocks   = m_SubChildren.OfType <VFXBlock>().ToArray();
            foreach (var child in m_SubChildren)
            {
                child.onInvalidateDelegate += SubChildrenOnInvalidate;
            }
            foreach (var child in copy)
            {
                child.hideFlags = HideFlags.HideAndDontSave;
            }
            SyncSlots(VFXSlot.Direction.kInput, true);
            PatchInputExpressions();
        }
        public void RecreateCopy()
        {
            ClearCopy();

            if (subgraph == null)
            {
                m_SubChildren  = null;
                m_UsedSubgraph = null;
                return;
            }

            var graph = m_Subgraph.GetResource().GetOrCreateGraph();
            HashSet <ScriptableObject> dependencies = new HashSet <ScriptableObject>();

            foreach (var child in graph.children.Where(t => t is VFXOperator || t is VFXParameter))
            {
                dependencies.Add(child);
                child.CollectDependencies(dependencies);
            }

            var copy = VFXMemorySerializer.DuplicateObjects(dependencies.ToArray());

            m_UsedSubgraph = graph;
            m_SubChildren  = copy.OfType <VFXModel>().Where(t => t is VFXOperator || t is VFXParameter).ToArray();

            foreach (var child in copy)
            {
                child.hideFlags = HideFlags.HideAndDontSave;
            }
        }
Exemple #3
0
        public object Backup()
        {
            Profiler.BeginSample("VFXGraph.Backup");
            var dependencies = new HashSet <ScriptableObject>();

            dependencies.Add(this);
            CollectDependencies(dependencies);

            var result = VFXMemorySerializer.StoreObjectsToByteArray(dependencies.ToArray(), CompressionLevel.Fastest);

            Profiler.EndSample();

            return(result);
        }
Exemple #4
0
        public void Restore(object str)
        {
            Profiler.BeginSample("VFXGraph.Restore");
            var scriptableObject = VFXMemorySerializer.ExtractObjects(str as byte[], false);

            Profiler.BeginSample("VFXGraph.Restore SendUnknownChange");
            foreach (var model in scriptableObject.OfType <VFXModel>())
            {
                model.OnUnknownChange();
            }
            Profiler.EndSample();
            Profiler.EndSample();
            m_ExpressionGraphDirty  = true;
            m_ExpressionValuesDirty = true;
            m_DependentDirty        = true;
        }
        private static Func <object, bool, ScriptableObject[]> GetExtractObjectsFunction()
        {
            var advancedMethod = typeof(VFXMemorySerializer).GetMethod("ExtractObjects", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(byte[]), typeof(bool) }, null);

            if (advancedMethod != null)
            {
                return(delegate(object objects, bool asCopy)
                {
                    return advancedMethod.Invoke(null, new object[] { objects as byte[], asCopy }) as ScriptableObject[];
                });
            }

            return(delegate(object objects, bool asCopy)
            {
                return VFXMemorySerializer.ExtractObjects(objects as string, asCopy);
            });
        }
        //Temporary : Use reflection to access to StoreObjectsToByteArray (doesn't break previous behavior if editor isn't up to date)
        //TODO : Clean this when major version is released
        private static Func <ScriptableObject[], CompressionLevel, object> GetStoreObjectsFunction()
        {
            var advancedMethod = typeof(VFXMemorySerializer).GetMethod("StoreObjectsToByteArray", BindingFlags.Public | BindingFlags.Static);

            if (advancedMethod != null)
            {
                return(delegate(ScriptableObject[] objects, CompressionLevel level)
                {
                    return advancedMethod.Invoke(null, new object[] { objects, level }) as byte[];
                });
            }

            return(delegate(ScriptableObject[] objects, CompressionLevel level)
            {
                return VFXMemorySerializer.StoreObjects(objects) as object;
            });
        }
Exemple #7
0
        public object Backup()
        {
            Profiler.BeginSample("VFXGraph.Backup");
            var dependencies = new HashSet <ScriptableObject>();

            dependencies.Add(this);
            CollectDependencies(dependencies);

            // This is a guard where dependencies that couldnt be deserialized (because script is missing for instance) are removed from the list
            // because else StoreObjectsToByteArray is crashing
            // TODO Fix that
            var safeDependencies = dependencies.Where(o => o != null);
            var result           = VFXMemorySerializer.StoreObjectsToByteArray(safeDependencies.ToArray(), CompressionLevel.Fastest);

            Profiler.EndSample();

            return(result);
        }
Exemple #8
0
        static void OnCompileResource(VisualEffectResource resource)
        {
            if (resource != null)
            {
                VFXGraph graph = resource.graph as VFXGraph;
                if (graph != null)
                {
                    if (!graph.sanitized)
                    {
                        //Early return, the reimport will be forced with the next OnPostprocessAllAssets after Sanitize
                        resource.ClearRuntimeData();
                    }
                    else
                    {
                        //Workaround, use backup system to prevent any modification of the graph during compilation
                        //The responsible of this unexpected change is PrepareSubgraphs => RecurseSubgraphRecreateCopy => ResyncSlots
                        //It will let the VFXGraph in a really bad state after compilation.
                        graph = resource.GetOrCreateGraph();
                        var dependencies = new HashSet <ScriptableObject>();
                        dependencies.Add(graph);
                        graph.CollectDependencies(dependencies);
                        var backup = VFXMemorySerializer.StoreObjectsToByteArray(dependencies.ToArray(), CompressionLevel.None);

                        graph.CompileForImport();

                        VFXMemorySerializer.ExtractObjects(backup, false);
                        //The backup during undo/redo is actually calling UnknownChange after ExtractObjects
                        //You have to avoid because it will call ResyncSlot
                    }
                }
                else
                {
                    Debug.LogError("OnCompileResource error - VisualEffectResource without graph");
                }
            }
        }
Exemple #9
0
        public void RecreateCopy()
        {
            DetachFromOriginal();

            if (m_Subgraph == null)
            {
                m_SubChildren  = null;
                m_UsedSubgraph = null;
                return;
            }

            var resource = m_Subgraph.GetResource();

            if (resource == null)
            {
                m_SubChildren  = null;
                m_UsedSubgraph = null;
                return;
            }

            var graph = resource.GetOrCreateGraph();
            HashSet <ScriptableObject> dependencies = new HashSet <ScriptableObject>();

            graph.CollectDependencies(dependencies);

            var duplicated = VFXMemorySerializer.DuplicateObjects(dependencies.ToArray());

            m_SubChildren  = duplicated.OfType <VFXModel>().Where(t => t is VFXContext || t is VFXOperator || t is VFXParameter).ToArray();
            m_UsedSubgraph = graph;
            foreach (var child in duplicated.Zip(dependencies, (a, b) => new { copy = a, original = b }))
            {
                child.copy.hideFlags = HideFlags.HideAndDontSave;
                if (child.copy is VFXSlot)
                {
                    var original = child.original as VFXSlot;
                    var copy     = child.copy as VFXSlot;
                    if (original.direction == VFXSlot.Direction.kInput || original.owner is VFXParameter)
                    {
                        m_OriginalToCopy[original]     = copy;
                        original.onInvalidateDelegate += OnOriginalSlotModified;
                    }
                }
                else if (child.copy is VFXSubgraphBlock subgraphBlock)
                {
                    subgraphBlock.RecreateCopy();
                }
            }

            List <string> newInputFlowNames = new List <string>();

            foreach (var basicEvent in m_SubChildren.OfType <VFXBasicEvent>())
            {
                if (!newInputFlowNames.Contains(basicEvent.eventName))
                {
                    newInputFlowNames.Add(basicEvent.eventName);
                }
            }

            bool hasStart = false;
            bool hasStop  = false;

            foreach (var initialize in m_SubChildren.OfType <VFXBasicSpawner>())
            {
                if (!hasStart && initialize.inputFlowSlot[0].link.Count() == 0)
                {
                    hasStart = true;
                }
                if (!hasStop && initialize.inputFlowSlot[1].link.Count() == 0)
                {
                    hasStop = true;
                }
            }

            int directEventCount = newInputFlowNames.Count;

            foreach (var subContext in m_SubChildren.OfType <VFXSubgraphContext>())
            {
                for (int i = 0; i < subContext.inputFlowCount; ++i)
                {
                    string name = subContext.GetInputFlowName(i);
                    switch (name)
                    {
                    case VisualEffectAsset.PlayEventName:
                        hasStart = true;
                        break;

                    case VisualEffectAsset.StopEventName:
                        hasStop = true;
                        break;

                    default:
                        m_InputFlowNames.Add(name);
                        break;
                    }
                }
            }
            newInputFlowNames.Sort(0, directEventCount, Comparer <string> .Default);
            newInputFlowNames.Sort(directEventCount, newInputFlowNames.Count - directEventCount, Comparer <string> .Default);
            if (hasStop)
            {
                newInputFlowNames.Insert(0, VisualEffectAsset.StopEventName);
            }
            if (hasStart)
            {
                newInputFlowNames.Insert(0, VisualEffectAsset.PlayEventName);
            }

            if (m_InputFlowNames == null || !newInputFlowNames.SequenceEqual(m_InputFlowNames) || inputFlowSlot.Length != inputFlowCount)
            {
                var oldLinks = new Dictionary <string, List <VFXContextLink> >();

                for (int i = 0; i < inputFlowSlot.Count() && i < m_InputFlowNames.Count; ++i)
                {
                    oldLinks[GetInputFlowName(i)] = inputFlowSlot[i].link.ToList();
                }
                m_InputFlowNames = newInputFlowNames;
                RefreshInputFlowSlots();

                for (int i = 0; i < inputFlowSlot.Count(); ++i)
                {
                    List <VFXContextLink> ctxSlot;
                    if (oldLinks.TryGetValue(GetInputFlowName(i), out ctxSlot))
                    {
                        foreach (var link in ctxSlot)
                        {
                            LinkFrom(link.context, link.slotIndex, i);
                        }
                    }
                }
            }
            SyncSlots(VFXSlot.Direction.kInput, true);
        }