Skip to content
Merged
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions template/framework/__PROJECT_NAME__/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ protected override async void OnLaunched(LaunchActivatedEventArgs e)
void ShowMainWindow()
{
StartPump();
#if DEBUG
_runtimeHost.WatchLiveSync(DispatcherQueue.GetForCurrentThread());
#endif

try
{
Expand Down
56 changes: 56 additions & 0 deletions template/framework/__PROJECT_NAME__/RuntimeHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,60 @@ public void PumpTimers()
private const string InspectorMarker = "ns-inspector";
private const string DebugBreakMarker = "ns-debugbreak";
private const string DebuggerStartedMarker = "ns-debugger-started";
// The CLI writes LiveSyncMarker after syncing files into app\ (webpack HMR), but only
// while LiveSyncReadyMarker says this host is watching for it.
private const string LiveSyncMarker = "ns-livesync";
private const string LiveSyncReadyMarker = "ns-livesync-ready";

private bool _waitForDebugger;
private FileSystemWatcher _liveSyncWatcher;

/// Applies CLI file syncs while the app runs, by calling global.__onLiveSync() on the UI
/// thread, as the Android and iOS runtimes do after a LiveSync.
public void WatchLiveSync(Microsoft.UI.Dispatching.DispatcherQueue dispatcherQueue)
{
if (!_initialized || _liveSyncWatcher != null || dispatcherQueue == null) return;
try
{
DeleteMarker(LiveSyncMarker);
var watcher = new FileSystemWatcher(LocalFolderPath, LiveSyncMarker)
{
NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite,
};
FileSystemEventHandler onMarker = (_, _) => dispatcherQueue.TryEnqueue(ApplyLiveSync);
watcher.Created += onMarker;
watcher.Changed += onMarker;
watcher.EnableRaisingEvents = true;
_liveSyncWatcher = watcher;
WriteMarker(LiveSyncReadyMarker, "");
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"[NativeScript LiveSync] Watch failed: {ex.Message}");
}
}

private void ApplyLiveSync()
{
// One write raises several events; the first one consumes the marker.
if (!_initialized || !ConsumeMarker(LiveSyncMarker)) return;
try
{
runtime_runscript(_runtime, "typeof __onLiveSync === 'function' && __onLiveSync();", "ns-livesync.js");
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"[NativeScript LiveSync] Apply failed: {ex.Message}");
}
}

private void StopWatchingLiveSync()
{
if (_liveSyncWatcher == null) return;
_liveSyncWatcher.Dispose();
_liveSyncWatcher = null;
DeleteMarker(LiveSyncReadyMarker);
}

public string DevtoolsFrontendUrl { get; private set; }

Expand Down Expand Up @@ -235,6 +287,7 @@ public void Initialize()
}
catch { }
DeleteMarker(DebuggerStartedMarker);
DeleteMarker(LiveSyncReadyMarker);
var debugBreak = ConsumeMarker(DebugBreakMarker);
if (ConsumeMarker(InspectorMarker) || debugBreak)
{
Expand Down Expand Up @@ -476,6 +529,9 @@ public string GetLastJsError()
public void Dispose()
{
if (!_initialized) return;
#if DEBUG
StopWatchingLiveSync();
#endif
runtime_deinit(_runtime);
_runtime = 0;
_initialized = false;
Expand Down