Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 50 additions & 18 deletions UnityMcpBridge/Editor/Tools/ManageScript.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2178,36 +2178,68 @@ private static void ValidateSemanticRules(string contents, System.Collections.Ge
static class RefreshDebounce
{
private static int _pending;
private static DateTime _last;
private static readonly object _lock = new object();
private static readonly HashSet<string> _paths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

// The timestamp of the most recent schedule request.
private static DateTime _lastRequest;

// Guard to ensure we only have a single ticking callback running.
private static bool _scheduled;

public static void Schedule(string relPath, TimeSpan window)
{
// Record that work is pending and track the path in a threadsafe way.
Interlocked.Exchange(ref _pending, 1);
lock (_lock) { _paths.Add(relPath); }
var now = DateTime.UtcNow;
if (_scheduled && (now - _last) < window) return;
_last = now;
_scheduled = true;
lock (_lock)
{
_paths.Add(relPath);
_lastRequest = DateTime.UtcNow;

EditorApplication.delayCall += () =>
// If a debounce timer is already scheduled it will pick up the new request.
if (_scheduled)
return;

_scheduled = true;
}

// Kick off a ticking callback that waits until the window has elapsed
// from the last request before performing the refresh.
EditorApplication.delayCall += () => Tick(window);
}

private static void Tick(TimeSpan window)
{
bool ready;
lock (_lock)
{
_scheduled = false;
if (Interlocked.Exchange(ref _pending, 0) == 1)
// Only proceed once the debounce window has fully elapsed.
ready = (DateTime.UtcNow - _lastRequest) >= window;
if (ready)
{
string[] toImport;
lock (_lock) { toImport = _paths.ToArray(); _paths.Clear(); }
foreach (var p in toImport)
AssetDatabase.ImportAsset(p, ImportAssetOptions.ForceUpdate);
_scheduled = false;
}
}

if (!ready)
{
// Window has not yet elapsed; check again on the next editor tick.
EditorApplication.delayCall += () => Tick(window);
return;
}

if (Interlocked.Exchange(ref _pending, 0) == 1)
{
string[] toImport;
lock (_lock) { toImport = _paths.ToArray(); _paths.Clear(); }
foreach (var p in toImport)
AssetDatabase.ImportAsset(p, ImportAssetOptions.ForceUpdate);
#if UNITY_EDITOR
UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();
UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();
#endif
// Fallback if needed:
// AssetDatabase.Refresh();
}
};
// Fallback if needed:
// AssetDatabase.Refresh();
}
}
}

Expand Down