-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScriptableSingletonFileReloader.cs
More file actions
96 lines (81 loc) · 3.03 KB
/
Copy pathScriptableSingletonFileReloader.cs
File metadata and controls
96 lines (81 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace FishingCactus.CommonCode
{
/// <summary>
/// Reloads the instance of the target scriptable singleton when the file is modified outside of Unity
/// </summary>
public class ScriptableSingletonFileReloader<T> : IDisposable
where T : ScriptableObject
{
private readonly string _filePath = string.Empty;
private readonly FileSystemWatcher _fileSystemWatcher = null;
private readonly FieldInfo _instanceField = null;
public bool IgnoreNextEvent { get; set; }
public ScriptableSingletonFileReloader(
string file_path
)
{
_instanceField = typeof( ScriptableSingleton<T> ).GetField( "s_Instance", BindingFlags.Static | BindingFlags.NonPublic );
if( string.IsNullOrEmpty( file_path ) )
{
throw new ArgumentNullException( nameof( file_path ) );
}
_filePath = Path.GetFullPath( Path.Combine( Path.GetDirectoryName( Application.dataPath ), file_path ) );
string directory_full_path = Path.GetDirectoryName( _filePath );
if( !Directory.Exists( directory_full_path ) )
{
Directory.CreateDirectory( directory_full_path );
}
_fileSystemWatcher = new( directory_full_path )
{
NotifyFilter = NotifyFilters.LastWrite,
EnableRaisingEvents = true,
};
_fileSystemWatcher.Changed += FileSystemWatcher_Changed;
}
public void Dispose()
{
_fileSystemWatcher.Changed -= FileSystemWatcher_Changed;
}
public void ReloadSingleton()
{
EditorApplication.update -= ReloadSingleton;
if( File.Exists( _filePath ) )
{
UnityEngine.Object.DestroyImmediate( ScriptableSingleton<T>.instance );
_instanceField.SetValue( null, null );
string relative_path = Path.GetRelativePath( Path.GetDirectoryName( Application.dataPath ), _filePath );
AssetDatabase.LoadAssetAtPath<T>( relative_path );
}
}
private void FileSystemWatcher_Changed(
object sender,
FileSystemEventArgs args
)
{
if( IgnoreNextEvent )
{
IgnoreNextEvent = false;
return;
}
try
{
string full_path = Path.GetFullPath( args.FullPath );
if( full_path.Equals( _filePath, StringComparison.OrdinalIgnoreCase ) )
{
// NOTE: return to main thread
EditorApplication.update += ReloadSingleton;
_fileSystemWatcher.Changed -= FileSystemWatcher_Changed;
}
}
catch( Exception exception )
{
Debug.LogException( exception );
}
}
}
}