/// <summary>
        /// Restores the visibility and lock of processors (on load or after an undo)
        /// </summary>
        public void RestoreProcessorView()
        {
            if (m_CurrentAsset.inheritSettingsReference != null && !m_IgnoreInheritSettings)
            {
                if (m_ProcessingNodeStack.nodes.Count > 0)
                {
                    if (m_CurrentAsset.editSettings.selectedProcessor > 0)
                    {
                        m_CurrentProcessingNode           = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.selectedProcessor];
                        m_ProcessorsReorderableList.index = m_CurrentAsset.editSettings.selectedProcessor;
                    }
                }
            }
            else
            {
                // index Checks
                m_CurrentAsset.editSettings.lockedProcessor   = Mathf.Clamp(m_CurrentAsset.editSettings.lockedProcessor, -1, m_ProcessingNodeStack.nodes.Count - 1);
                m_CurrentAsset.editSettings.selectedProcessor = Mathf.Clamp(m_CurrentAsset.editSettings.selectedProcessor, -1, m_ProcessingNodeStack.nodes.Count - 1);

                // Locked processor
                if (m_CurrentAsset.editSettings.lockedProcessor != -1)
                {
                    m_ProcessorsReorderableList.index = m_CurrentAsset.editSettings.lockedProcessor;
                    m_LockedPreviewProcessor          = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.lockedProcessor];
                    m_CurrentProcessingNode           = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.lockedProcessor];
                }
                else
                {
                    m_LockedPreviewProcessor = null;
                }

                // Selected Processor
                if (m_CurrentAsset.editSettings.selectedProcessor != -1)
                {
                    m_ProcessorsReorderableList.index = m_CurrentAsset.editSettings.selectedProcessor;

                    if (m_CurrentAsset.editSettings.lockedProcessor != -1)
                    {
                        m_CurrentProcessingNode = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.lockedProcessor];
                    }
                    else
                    {
                        m_CurrentProcessingNode = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.selectedProcessor];
                    }
                }
            }

            m_ProcessingNodeStack.InvalidateAll();
            RefreshCanvas();
        }
        public void AddProcessor(ProcessorElement element)
        {
            var settingType = element.m_ProcessorSettingType;

            // Add Element
            Undo.RecordObject(m_CurrentAsset, "Add Processor");

            ProcessingNode processor = null;

            // Reflection Stuff here
            ProcessorAttribute attribute = m_ProcessingNodeStack.settingsDefinitions[settingType];

            var info = ProcessorInfo.CreateDefault(attribute.name, true, settingType);

            processor = (ProcessingNode)Activator.CreateInstance(typeof(ProcessingNode), m_ProcessingNodeStack, info);

            if (processor != null)
            {
                m_ProcessingNodeStack.AddProcessor(processor, m_CurrentAsset);
                m_ProcessingNodeStack.InvalidateAll();
            }
        }
        public void LoadAsset(ImageSequence asset)
        {
            m_CurrentAsset = asset;

            m_InputFramesReorderableList = null;
            m_ProcessorsReorderableList  = null;
            m_LockedPreviewProcessor     = null;
            m_CurrentProcessingNode      = null;

            // Free resources if any
            if (m_ProcessingNodeStack != null)
            {
                m_ProcessingNodeStack.Dispose();
            }

            InitializeGUI();

            if (m_CurrentAsset != null)
            {
                m_ProcessingNodeStack = new ProcessingNodeStack(new ProcessingFrameSequence(null), this);

                m_CurrentAssetSerializedObject = new SerializedObject(m_CurrentAsset);

                VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Loading asset....", 0.0f);

                m_LockedPreviewProcessor = null;

                VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Loading Frames", 0.333333f);

                m_ProcessingNodeStack.LoadFramesFromAsset(m_CurrentAsset);
                UpdateInputTexturesHash();

                m_InputFramesReorderableList = new ReorderableList(m_ProcessingNodeStack.inputSequence.frames, typeof(Texture2D), true, false, true, true);
                m_InputFramesReorderableList.onAddCallback       = AddInputFrame;
                m_InputFramesReorderableList.onRemoveCallback    = RemoveInputFrame;
                m_InputFramesReorderableList.onReorderCallback   = ReorderInputFrame;
                m_InputFramesReorderableList.drawElementCallback = DrawInputFrameRListElement;
                m_InputFramesReorderableList.onSelectCallback    = SelectInputFrameRListElement;

                VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Loading Processors", 0.66666f);

                ImageSequence inheritedSettingReference = m_CurrentAsset;

                // Loading other settings if inheriting settings
                if (m_CurrentAsset.inheritSettingsReference != null)
                {
                    var dependencyList = new List <ImageSequence>();
                    var referenceAsset = FindSettingsReference(m_CurrentAsset.inheritSettingsReference, ref dependencyList);
                    if (referenceAsset == null)
                    {
                        Debug.LogWarning("Dependency Loop detected, ignoring using external settings");
                        m_IgnoreInheritSettings = true;
                    }
                    else
                    {
                        inheritedSettingReference = referenceAsset;
                        m_IgnoreInheritSettings   = false;
                    }
                }

                m_ProcessingNodeStack.LoadProcessorsFromAsset(inheritedSettingReference);
                m_ProcessorDataProvider = new ProcessorDataProvider(m_ProcessingNodeStack, m_CurrentAsset);

                // Construct the RList
                if (m_CurrentAsset.inheritSettingsReference == null)
                {
#if UNITY_2020_1_OR_NEWER
                    m_ProcessorsReorderableList = new ReorderableList(m_CurrentAsset.processorInfos, typeof(ProcessorInfo), true, false, true, true);
#else
                    m_ProcessorsReorderableList = new ReorderableList(m_CurrentAssetSerializedObject, m_CurrentAssetSerializedObject.FindProperty("processorInfos"), true, false, true, true);
#endif
                    m_ProcessorsReorderableList.onAddCallback       = ShowAddProcessorMenu;
                    m_ProcessorsReorderableList.onRemoveCallback    = MenuRemoveProcessor;
                    m_ProcessorsReorderableList.onReorderCallback   = ReorderProcessor;
                    m_ProcessorsReorderableList.onSelectCallback    = MenuSelectProcessor;
                    m_ProcessorsReorderableList.drawElementCallback = DrawRListProcessorElement;
                    m_SettingsReferenceSerializedObject             = null;
                }
                else
                {
                    m_SettingsReferenceSerializedObject             = new SerializedObject(inheritedSettingReference);
                    m_ProcessorsReorderableList                     = new ReorderableList(m_SettingsReferenceSerializedObject, m_SettingsReferenceSerializedObject.FindProperty("processorInfos"), false, false, false, false);
                    m_ProcessorsReorderableList.drawElementCallback = DrawRListPreviewProcessorElement;
                    m_ProcessorsReorderableList.onSelectCallback    = MenuSelectProcessor;
                }

                m_PreviewCanvas.sequence = m_ProcessingNodeStack.inputSequence;
                if (m_PreviewCanvas.sequence.length > 0)
                {
                    m_PreviewCanvas.currentFrameIndex = 0;
                }
                else
                {
                    m_PreviewCanvas.currentFrameIndex = -1;
                }

                VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Finalizing...", 1.0f);

                m_ProcessingNodeStack.InvalidateAll();
                RestoreProcessorView();

                EditorUtility.ClearProgressBar();
            }
        }