static string[] OnWillSaveAssets(string[] assetPaths)
        {
            //find all TextureRecipe assets, then check if any are being saved
            List <string> recipeAssetPaths = new List <string>();

            var recipeGUIDs = AssetDatabase.FindAssets("t:TextureRecipe");

            foreach (var recipeID in recipeGUIDs)
            {
                recipeAssetPaths.Add(AssetDatabase.GUIDToAssetPath(recipeID));
            }

            foreach (string assetPath in assetPaths)
            {
                if (recipeAssetPaths.Contains(assetPath))
                {
                    //We are saving this recipe so generate any other assets that it requires
                    TextureRecipe recipe = AssetDatabase.LoadAssetAtPath <TextureRecipe>(assetPath);
                    GeneratorFactory.createMappings();

                    var builtSubAssetPaths = bakeSubAssets(recipe);

                    var oldAssetPaths = new List <string>(assetPaths);
                    oldAssetPaths.AddRange(builtSubAssetPaths);
                    assetPaths = oldAssetPaths.ToArray();
                }
            }

            return(assetPaths);
        }
 static void buildModifiedShaders()
 {
     if (!EditorApplication.isPlaying && EditorApplication.isPlayingOrWillChangePlaymode)
     {
         //TODO: is there a way to figure out which shaders need building?
         var recipeGUIDs = AssetDatabase.FindAssets("t:TextureRecipe");
         foreach (var recipeID in recipeGUIDs)
         {
             string        assetPath = AssetDatabase.GUIDToAssetPath(recipeID);
             TextureRecipe recipe    = AssetDatabase.LoadAssetAtPath <TextureRecipe>(assetPath);
             GeneratorFactory.createMappings();
             bakeSubAssets(recipe);
         }
     }
 }
        void UpdatePreviewTexture(TextureRecipe targetRecipe, Texture2D previewTex)
        {
            if (!refreshPreviewTexture)
            {
                return;
            }

            refreshPreviewTexture = false;

            GeneratorFactory.createMappings();
            RecipeBuildPreProcess.bakeSubAssets(targetRecipe);

            TextureRecipeRenderer renderer = new TextureRecipeRenderer(targetRecipe);

            renderer.renderSetup(previewTex);
            renderer.renderRecipeInternal();

            previewTex.ReadPixels(new Rect(0, 0, previewTex.width, previewTex.height), 0, 0);
            previewTex.Apply();

            RenderTexture.active = null;

            renderer.renderTeardown();
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            TextureRecipe targetRecipe  = (TextureRecipe)target;
            var           texWidthProp  = serializedObject.FindProperty("TextureWidth");
            var           texHeightProp = serializedObject.FindProperty("TextureHeight");

            texWidthProp.intValue  = EditorGUILayout.IntField("Width", texWidthProp.intValue);
            texHeightProp.intValue = EditorGUILayout.IntField("Height", texHeightProp.intValue);
            serializedObject.ApplyModifiedProperties();

            if (GUILayout.Button("Bake"))
            {
                GeneratorFactory.createMappings();
                RecipeBuildPreProcess.bakeSubAssets(targetRecipe);

                TextureRecipeRenderer renderer = new TextureRecipeRenderer(targetRecipe);
                renderer.renderSetup();
                renderer.renderRecipeInternal();

                TextureWriter.WriteRenderBufferToTextureFile(targetRecipe.TextureWidth, targetRecipe.TextureHeight, targetRecipe);
                RenderTexture.active = null;

                renderer.renderTeardown();
            }

            reorderableList.DoLayoutList();

            int listIndex = reorderableList.index;

            var layerList = serializedObject.FindProperty("layerList");

            if (listIndex >= 0 && listIndex < layerList.arraySize)
            {
                var listItem = layerList.GetArrayElementAtIndex(listIndex);
                if (null != listItem.objectReferenceValue)
                {
                    if (subEditorType != listItem.objectReferenceValue.GetType())
                    {
                        subEditor = null;
                    }
                    EditorGUI.BeginChangeCheck();

                    ShaderLayerEditor.recipe = (TextureRecipe)target;
                    CreateCachedEditor(listItem.objectReferenceValue, null, ref subEditor);
                    subEditorType = listItem.objectReferenceValue.GetType();

                    subEditor.serializedObject.Update();
                    subEditor.OnInspectorGUI();
                    subEditor.serializedObject.ApplyModifiedProperties();

                    serializedObject.ApplyModifiedProperties();
                    if (EditorGUI.EndChangeCheck() && targetRecipe.autoRefresh)
                    {
                        //do we need this if we set dirty on the target every frame?
                        EditorUtility.SetDirty(listItem.objectReferenceValue);
                        refreshPreviewTexture = true;
                    }

                    if (ShaderLayerEditor.nodeEditor && ShaderLayerEditor.nodeEditor.refreshShader && targetRecipe.autoRefresh)
                    {
                        refreshPreviewTexture = true;
                        ShaderLayerEditor.nodeEditor.refreshShader = false;
                    }
                }
            }

            //We have to do this every frame otherwise changes to the child objects aren't reflected in the inspector when we Undo them
            //there is perhaps an issue with the order of operations
            EditorUtility.SetDirty(target);
        }