Skip to content

Commit

Permalink
Include TidyBehaviour to ensure we clean up references in editor
Browse files Browse the repository at this point in the history
  • Loading branch information
neilsarkar committed Jul 20, 2020
1 parent 6e4bc8e commit 1a084d4
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 57 deletions.
7 changes: 4 additions & 3 deletions Runtime/Navigation/NavigationController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using UnityEngine;

public class NavigationController : MonoBehaviour {

}
namespace VioletUI {
public class NavigationController : TidyBehaviour {
}
}
35 changes: 19 additions & 16 deletions Runtime/Navigation/NavigationScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,27 @@
using UnityEditor;
#endif

public class NavigationScreen : MonoBehaviour {
#if UNITY_EDITOR
public static bool IsSavingPrefab;
namespace VioletUI {

public class NavigationScreen : TidyBehaviour {
#if UNITY_EDITOR
public static bool IsSavingPrefab;

public void StartEditing() {
IsSavingPrefab = false;
try {
PrefabUtility.UnpackPrefabInstance(gameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction);
} catch (ArgumentException e) {
UnityEngine.Debug.LogWarning($"VioletUI: Couldn't unpack prefab for {name}. Make sure the NavigationScreen is a prefab. {e}");
public void StartEditing() {
IsSavingPrefab = false;
try {
PrefabUtility.UnpackPrefabInstance(gameObject, PrefabUnpackMode.OutermostRoot, InteractionMode.AutomatedAction);
} catch (ArgumentException e) {
UnityEngine.Debug.LogWarning($"VioletUI: Couldn't unpack prefab for {name}. Make sure the NavigationScreen is a prefab. {e}");
}
gameObject.SetActive(true);
}
gameObject.SetActive(true);
}

public void StopEditing() {
IsSavingPrefab = true;
PrefabUtility.SaveAsPrefabAssetAndConnect(gameObject, $"Assets/Implementation/Menus/{name}.prefab", InteractionMode.AutomatedAction);
gameObject.SetActive(false);
public void StopEditing() {
IsSavingPrefab = true;
PrefabUtility.SaveAsPrefabAssetAndConnect(gameObject, $"Assets/Implementation/Menus/{name}.prefab", InteractionMode.AutomatedAction);
gameObject.SetActive(false);
}
#endif
}
#endif
}
77 changes: 40 additions & 37 deletions Runtime/PrefabApplier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,49 +15,52 @@
/// It does this by hooking into the scene save event, so when the designer saves the scene
/// all the prefab overrides will be automatically applied.
/// </summary>
[ExecuteAlways]
public class PrefabApplier : MonoBehaviour {
void OnDestroy() {
EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved;
}

// tried this in Awake and OnDestroy but apparently these get blown away
// when the project recompiles sooo why not here!
void Update() {
EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved;
EditorSceneManager.sceneSaved += EditorSceneManager_sceneSaved;
}
namespace VioletUI {

bool isAutosaving = false;
[ExecuteAlways]
public class PrefabApplier : TidyBehaviour {
void OnDestroy() {
EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved;
}

void EditorSceneManager_sceneSaved(Scene scene) {
if (Application.isPlaying) { return; }
if (isAutosaving) {
isAutosaving = false;
return;
// tried this in Awake and OnDestroy but apparently these get blown away
// when the project recompiles sooo why not here!
void Update() {
EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved;
EditorSceneManager.sceneSaved += EditorSceneManager_sceneSaved;
}
UpdatePrefabs();
}

[Button, GUIColor(0.898f, 0.745f, 0.935f)]
public void UpdatePrefabs() {
bool hasChanges = false;
foreach (Transform child in transform) {
if (PrefabUtility.HasPrefabInstanceAnyOverrides(child.gameObject, false)) {
PrefabUtility.ApplyPrefabInstance(child.gameObject, InteractionMode.AutomatedAction);
hasChanges = true;
bool isAutosaving = false;

void EditorSceneManager_sceneSaved(Scene scene) {
if (Application.isPlaying) { return; }
if (isAutosaving) {
isAutosaving = false;
return;
}
UpdatePrefabs();
}
if (!hasChanges) { return; }

[Button, GUIColor(0.898f, 0.745f, 0.935f)]
public void UpdatePrefabs() {
bool hasChanges = false;
foreach (Transform child in transform) {
if (PrefabUtility.HasPrefabInstanceAnyOverrides(child.gameObject, false)) {
PrefabUtility.ApplyPrefabInstance(child.gameObject, InteractionMode.AutomatedAction);
hasChanges = true;
}
}
if (!hasChanges) { return; }


var scene = SceneManager.GetActiveScene();
EditorSceneManager.MarkSceneDirty(scene);
isAutosaving = true;
EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved;
EditorSceneManager.SaveScene(scene);
EditorSceneManager.sceneSaved += EditorSceneManager_sceneSaved;
isAutosaving = false;
var scene = SceneManager.GetActiveScene();
EditorSceneManager.MarkSceneDirty(scene);
isAutosaving = true;
EditorSceneManager.sceneSaved -= EditorSceneManager_sceneSaved;
EditorSceneManager.SaveScene(scene);
EditorSceneManager.sceneSaved += EditorSceneManager_sceneSaved;
isAutosaving = false;
}
}
}
#endif
#endif
}
46 changes: 46 additions & 0 deletions Runtime/TidyBehaviour.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Diagnostics;
using System.Reflection;

namespace VioletUI {

public class TidyBehaviour : MonoBehaviour {
protected virtual void OnDestroy() {
ReleaseReferences();
}

[Conditional("UNITY_EDITOR")]
void ReleaseReferences() {
foreach (FieldInfo field in this.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
Type fieldType = field.FieldType;

if (typeof(IList).IsAssignableFrom(fieldType)) {
IList list = field.GetValue(this) as IList;
list?.Clear();
} else if (typeof(IDictionary).IsAssignableFrom(fieldType)) {
IDictionary dictionary = field.GetValue(this) as IDictionary;
dictionary?.Clear();
}

if (!fieldType.IsPrimitive) {
field.SetValue(this, null);
}
}

foreach (PropertyInfo property in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
Type fieldType = property.PropertyType;

if (typeof(IList).IsAssignableFrom(fieldType)) {
IList list = property.GetValue(this) as IList;
list?.Clear();
} else if (typeof(IDictionary).IsAssignableFrom(fieldType)) {
IDictionary dictionary = property.GetValue(this) as IDictionary;
dictionary?.Clear();
}
}
}
}
}
11 changes: 11 additions & 0 deletions Runtime/TidyBehaviour.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Runtime/Views/View.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace VioletUI {
[ExecuteAlways]
public abstract class View<TState> : MonoBehaviour, IView<TState> where TState : IState {
public abstract class View<TState> : TidyBehaviour, IView<TState> where TState : IState {
public abstract TState State { get; }
public abstract TState LastState { get; }
[NonSerialized] public int Index;
Expand Down

0 comments on commit 1a084d4

Please sign in to comment.