Skip to content

Commit 9ce3b37

Browse files
committed
fix: allow XAML HR when debugging with mono runtime
1 parent 8e56298 commit 9ce3b37

File tree

4 files changed

+53
-30
lines changed

4 files changed

+53
-30
lines changed

src/Uno.UI.RemoteControl.Server.Processors/HotReload/ServerHotReloadProcessor.MetadataUpdate.cs

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -401,53 +401,68 @@ async Task SendUpdates(ImmutableArray<WatchHotReloadService.Update> updates)
401401

402402
for (var i = 0; i < updates.Length; i++)
403403
{
404+
var update = updates[i];
405+
var moduleId = update.ModuleId.ToString();
406+
var metadataDelta = Convert.ToBase64String(update.MetadataDelta.AsSpan());
407+
var ilDelta = Convert.ToBase64String(update.ILDelta.AsSpan());
408+
var pdbDelta = Convert.ToBase64String(update.PdbDelta.AsSpan());
409+
var updatedTypes = Convert.ToBase64String(GetLengthPrefixedArray(update.UpdatedTypes));
410+
411+
// if the app is running from VSCode with the mono debugger attached
404412
if (_useHotReloadThruDebugger)
405413
{
414+
// send metadataDelta, ilDelta and pdbDelta thru the IDE channel to be applied by the debugger
406415
if (!await _remoteControlServer.TrySendMessageToIDEAsync(
407416
new Uno.UI.RemoteControl.Messaging.IdeChannel.HotReloadThruDebuggerIdeMessage(
408-
updates[i].ModuleId.ToString(),
409-
Convert.ToBase64String(updates[i].MetadataDelta.ToArray()),
410-
Convert.ToBase64String(updates[i].ILDelta.ToArray()),
411-
Convert.ToBase64String(updates[i].PdbDelta.ToArray())
417+
moduleId,
418+
metadataDelta,
419+
ilDelta,
420+
pdbDelta
412421
),
413422
ct))
414423
{
415424
throw new InvalidOperationException("No active connection with the IDE to send update thru debugger.");
416425
}
426+
// send the updatedTypes thru the regular hot reload channel to notify the app about the changes
427+
await _remoteControlServer.SendFrame(
428+
new AssemblyDeltaReload
429+
{
430+
FilePaths = files,
431+
ModuleId = moduleId,
432+
UpdatedTypes = updatedTypes,
433+
});
417434
}
418435
else
419436
{
420-
var updateTypesWriterStream = new MemoryStream();
421-
var updateTypesWriter = new BinaryWriter(updateTypesWriterStream);
422-
WriteIntArray(updateTypesWriter, updates[i].UpdatedTypes.ToArray());
423-
424437
await _remoteControlServer.SendFrame(
425438
new AssemblyDeltaReload
426439
{
427440
FilePaths = files,
428-
ModuleId = updates[i].ModuleId.ToString(),
429-
PdbDelta = Convert.ToBase64String(updates[i].PdbDelta.ToArray()),
430-
ILDelta = Convert.ToBase64String(updates[i].ILDelta.ToArray()),
431-
MetadataDelta = Convert.ToBase64String(updates[i].MetadataDelta.ToArray()),
432-
UpdatedTypes = Convert.ToBase64String(updateTypesWriterStream.ToArray()),
441+
ModuleId = moduleId,
442+
PdbDelta = pdbDelta,
443+
ILDelta = ilDelta,
444+
MetadataDelta = metadataDelta,
445+
UpdatedTypes = updatedTypes,
433446
});
434447
}
435448
}
436449
}
437450

438-
static void WriteIntArray(BinaryWriter binaryWriter, int[] values)
451+
static byte[] GetLengthPrefixedArray(ImmutableArray<int> values)
439452
{
440-
if (values is null)
453+
if (values.Length == 0)
441454
{
442-
binaryWriter.Write(0);
443-
return;
455+
return [0, 0, 0, 0]; // length (empty)
444456
}
445457

446-
binaryWriter.Write(values.Length);
458+
var stream = new MemoryStream(sizeof(int) /* length */ + values.Length * sizeof(int));
459+
var writer = new BinaryWriter(stream);
460+
writer.Write(values.Length);
447461
foreach (var value in values)
448462
{
449-
binaryWriter.Write(value);
463+
writer.Write(value);
450464
}
465+
return stream.ToArray();
451466
}
452467
}
453468

src/Uno.UI.RemoteControl/HotReload/ClientHotReloadProcessor.Agent.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,11 @@ private void ProcessAssemblyReload(AssemblyDeltaReload assemblyDeltaReload)
179179
this.Log().Error("Hot Reload is not supported when the debugger is attached.");
180180
}
181181
_status.ReportLocalStarting([]).ReportIgnored("Hot Reload is not supported when the debugger is attached");
182+
return;
182183
}
183-
184-
return;
185184
}
186185

187-
if (assemblyDeltaReload.IsValid())
186+
if (assemblyDeltaReload.IsValid(_runningInsideVSCodeExtension))
188187
{
189188
if (this.Log().IsEnabled(LogLevel.Trace))
190189
{
@@ -194,17 +193,23 @@ private void ProcessAssemblyReload(AssemblyDeltaReload assemblyDeltaReload)
194193
var changedTypesStreams = new MemoryStream(Convert.FromBase64String(assemblyDeltaReload.UpdatedTypes));
195194
var changedTypesReader = new BinaryReader(changedTypesStreams);
196195

196+
// when executing in VSCode extension / mono runtime the MetadataDelta, ILDelta and PdbBytes are processed thru the debugger
197+
// however we still need to apply the updated types (e.g. for XAML HR to work properly)
197198
var delta = new UpdateDelta
198199
{
199-
MetadataDelta = Convert.FromBase64String(assemblyDeltaReload.MetadataDelta),
200-
ILDelta = Convert.FromBase64String(assemblyDeltaReload.ILDelta),
201-
PdbBytes = Convert.FromBase64String(assemblyDeltaReload.PdbDelta),
200+
MetadataDelta = _runningInsideVSCodeExtension ? Array.Empty<byte>() : Convert.FromBase64String(assemblyDeltaReload.MetadataDelta),
201+
ILDelta = _runningInsideVSCodeExtension ? Array.Empty<byte>() : Convert.FromBase64String(assemblyDeltaReload.ILDelta),
202+
PdbBytes = _runningInsideVSCodeExtension ? Array.Empty<byte>() : Convert.FromBase64String(assemblyDeltaReload.PdbDelta),
202203
ModuleId = Guid.Parse(assemblyDeltaReload.ModuleId),
203204
UpdatedTypes = ReadIntArray(changedTypesReader)
204205
};
205206

206207
_status.ConfigureSourceForNextOperation(HotReloadSource.DevServer);
207-
_agent?.ApplyDeltas(new[] { delta });
208+
if (!_runningInsideVSCodeExtension)
209+
{
210+
_agent?.ApplyDeltas([delta]);
211+
}
212+
_agent?.ApplyUpdatedTypes([delta]);
208213

209214
if (this.Log().IsEnabled(LogLevel.Trace))
210215
{

src/Uno.UI.RemoteControl/HotReload/Messages/AssemblyDeltaReload.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ internal class AssemblyDeltaReload : IMessage
3333
string IMessage.Name => Name;
3434

3535
[MemberNotNullWhen(true, nameof(UpdatedTypes), nameof(MetadataDelta), nameof(ILDelta), nameof(PdbDelta), nameof(ModuleId))]
36-
public bool IsValid()
36+
public bool IsValid(bool runningInsideVSCodeExtension)
3737
{
3838
return FilePaths is { IsEmpty: false }
3939
&& UpdatedTypes is not null
40-
&& MetadataDelta is not null
41-
&& ILDelta is not null
42-
&& PdbDelta is not null
40+
&& (MetadataDelta is not null || runningInsideVSCodeExtension)
41+
&& (ILDelta is not null || runningInsideVSCodeExtension)
42+
&& (PdbDelta is not null || runningInsideVSCodeExtension)
4343
&& ModuleId is not null;
4444
}
4545
}

src/Uno.UI.RemoteControl/HotReload/MetadataUpdater/HotReloadAgent.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,10 @@ public void ApplyDeltas(IReadOnlyList<UpdateDelta> deltas)
225225
var cachedDeltas = _deltas.GetOrAdd(item.ModuleId, static _ => new());
226226
cachedDeltas.Add(item);
227227
}
228+
}
228229

230+
public void ApplyUpdatedTypes(IReadOnlyList<UpdateDelta> deltas)
231+
{
229232
try
230233
{
231234
// Defer discovering metadata update handlers until after hot reload deltas have been applied.

0 commit comments

Comments
 (0)