Skip to content

Commit a2efccb

Browse files
committed
Improve warning system
1 parent 0a5163a commit a2efccb

File tree

3 files changed

+125
-60
lines changed

3 files changed

+125
-60
lines changed

src/Laylua.Tests/Tests/Library/LuaTests.cs

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -298,38 +298,48 @@ public void Warn_OnePieceMessage_TriggersWarningEvent()
298298
{
299299
// Arrange
300300
const string Message = "This is a warning message.";
301-
var collectedMessages = new List<string>();
301+
var expectedWarnings = new[]
302+
{
303+
Message
304+
};
305+
306+
var actualWarnings = new List<string>();
302307

303308
Lua.OpenLibrary(LuaLibraries.Standard.Base);
304309
Lua.WarningEmitted += (_, e) =>
305310
{
306-
collectedMessages.Add(e.Message.ToString());
311+
actualWarnings.Add(e.Message.ToString());
307312
};
308313

309314
// Act
310315
Lua.Execute($"warn('{Message}')");
311316

312317
// Assert
313-
Assert.That(collectedMessages, Is.EqualTo(new[] { Message }));
318+
Assert.That(actualWarnings, Is.EqualTo(expectedWarnings));
314319
}
315320

316321
[Test]
317322
public void EmitWarning_OnePieceMessage_TriggersWarningEvent()
318323
{
319324
// Arrange
320325
const string Message = "This is a warning message.";
321-
var collectedMessages = new List<string>();
326+
var expectedWarnings = new[]
327+
{
328+
Message
329+
};
330+
331+
var actualWarnings = new List<string>();
322332

323333
Lua.WarningEmitted += (_, e) =>
324334
{
325-
collectedMessages.Add(e.Message.ToString());
335+
actualWarnings.Add(e.Message.ToString());
326336
};
327337

328338
// Act
329339
Lua.EmitWarning(Message);
330340

331341
// Assert
332-
Assert.That(collectedMessages, Is.EqualTo(new[] { Message }));
342+
Assert.That(actualWarnings, Is.EqualTo(expectedWarnings));
333343
}
334344

335345
[Test]
@@ -338,41 +348,84 @@ public void Warn_MultiPieceMessage_TriggersSingleWarningEvent()
338348
// Arrange
339349
const string Message = "Youshallnotpass.";
340350
const string SplitMessage = "'You', 'shall', 'not', 'pass.'";
341-
var collectedMessages = new List<string>();
351+
var expectedWarnings = new[]
352+
{
353+
Message
354+
};
355+
356+
var actualWarnings = new List<string>();
342357

343358
Lua.OpenLibrary(LuaLibraries.Standard.Base);
344359
Lua.WarningEmitted += (_, e) =>
345360
{
346-
collectedMessages.Add(e.Message.ToString());
361+
actualWarnings.Add(e.Message.ToString());
347362
};
348363

349364
// Act
350365
Lua.Execute($"warn({SplitMessage})"); //
351366

352367
// Assert
353-
Assert.That(collectedMessages, Is.EqualTo(new[] { Message }));
368+
Assert.That(actualWarnings, Is.EqualTo(expectedWarnings));
354369
}
355370

356371
[Test]
357372
public void Warn_OffOnControlMessages_TogglesEmitsWarningsAccordingly()
358373
{
359374
// Arrange
360375
const string Message = "This is a warning message.";
361-
var collectedMessages = new List<string>();
376+
var expectedWarnings = new[]
377+
{
378+
"@off",
379+
"@off",
380+
"@on",
381+
Message
382+
};
383+
384+
var actualWarnings = new List<string>();
362385

363386
Lua.OpenLibrary(LuaLibraries.Standard.Base);
364387
Lua.WarningEmitted += (_, e) =>
365388
{
366-
collectedMessages.Add(e.Message.ToString());
389+
actualWarnings.Add(e.Message.ToString());
367390
};
368391

369-
// Act
392+
// Act & Assert
393+
Lua.Execute("warn('@off')");
394+
Assert.That(Lua.EmitsWarnings, Is.False);
395+
370396
Lua.Execute("warn('@off')");
371397
Lua.Execute($"warn('{Message}')");
398+
372399
Lua.Execute("warn('@on')");
400+
Assert.That(Lua.EmitsWarnings, Is.True);
401+
402+
Lua.Execute($"warn('{Message}')");
403+
404+
Assert.That(actualWarnings, Is.EqualTo(expectedWarnings));
405+
}
406+
407+
[Test]
408+
public void Warn_CustomControlMessage_TriggersWarningEventWithIsControlTrue()
409+
{
410+
// Arrange
411+
const string Message = "@custom-control-message";
412+
var expectedWarnings = new[]
413+
{
414+
Message
415+
};
416+
417+
var actualWarnings = new List<string>();
418+
419+
Lua.OpenLibrary(LuaLibraries.Standard.Base);
420+
Lua.WarningEmitted += (_, e) =>
421+
{
422+
actualWarnings.Add(e.Message.ToString());
423+
};
424+
425+
// Act
373426
Lua.Execute($"warn('{Message}')");
374427

375428
// Assert
376-
Assert.That(collectedMessages, Is.EqualTo(new[] { Message }));
429+
Assert.That(actualWarnings, Is.EqualTo(expectedWarnings));
377430
}
378431
}

src/Laylua/Library/Lua.Warnings.cs

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public sealed unsafe partial class Lua
1212
{
1313
/// <summary>
1414
/// Gets or sets whether <see cref="WarningEmitted"/> should fire for emitted warnings. <br/>
15+
/// Control messages ignore this property. <br/>
16+
/// Defaults to <see langword="true"/>. <br/>
1517
/// See <a href="https://www.lua.org/manual/5.4/manual.html#2.3">Error Handling (Lua manual)</a> and
1618
/// <a href="https://www.lua.org/manual/5.4/manual.html#pdf-warn"><c>warn (msg1, ···) (Lua Manual)</c></a> for more information about warnings.
1719
/// </summary>
@@ -29,7 +31,7 @@ public sealed unsafe partial class Lua
2931
/// <remarks>
3032
/// Subscribed event handlers must not throw any exceptions.
3133
/// </remarks>
32-
public event EventHandler<LuaWarningEmittedEventArgs>? WarningEmitted;
34+
public event LuaWarningEventHandler? WarningEmitted;
3335

3436
private MemoryStream? _warningBuffer;
3537

@@ -38,43 +40,27 @@ private static void WarningHandler(void* ud, byte* msg, int tocont)
3840
{
3941
var lua = FromExtraSpace((lua_State*) ud);
4042
var msgSpan = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(msg);
41-
if (msgSpan.StartsWith("@"u8))
43+
bool isControl;
44+
if (tocont == 0)
4245
{
43-
ProcessControlWarningMessage(lua, msgSpan[1..]);
44-
return;
45-
}
46-
47-
if (!lua.EmitsWarnings || lua.WarningEmitted == null)
48-
{
49-
return;
46+
if ((isControl = msgSpan.StartsWith("@"u8)))
47+
{
48+
ProcessControlWarningMessage(lua, msgSpan[1..]);
49+
}
5050
}
51-
52-
if (tocont != 0)
51+
else
5352
{
5453
(lua._warningBuffer ??= new(capacity: 128)).Write(msgSpan);
5554
return;
5655
}
5756

58-
RentedArray<char> message;
59-
var warningBuffer = lua._warningBuffer;
60-
if (warningBuffer == null || warningBuffer.Length == 0)
57+
if (!isControl && (!lua.EmitsWarnings || lua.WarningEmitted == null))
6158
{
62-
message = CreateWarningMessage(msgSpan);
63-
}
64-
else
65-
{
66-
warningBuffer.Write(msgSpan);
67-
_ = warningBuffer.TryGetBuffer(out var buffer);
68-
69-
message = CreateWarningMessage(buffer);
70-
71-
ClearWarningBuffer(warningBuffer);
59+
return;
7260
}
7361

74-
using (message)
75-
{
76-
lua.WarningEmitted?.Invoke(lua, new LuaWarningEmittedEventArgs(message));
77-
}
62+
InvokeWarningEmitted(lua, msgSpan);
63+
return;
7864

7965
static void ProcessControlWarningMessage(Lua lua, ReadOnlySpan<byte> controlMsg)
8066
{
@@ -93,6 +79,30 @@ static void ProcessControlWarningMessage(Lua lua, ReadOnlySpan<byte> controlMsg)
9379
}
9480
}
9581

82+
static void InvokeWarningEmitted(Lua lua, ReadOnlySpan<byte> msgSpan)
83+
{
84+
RentedArray<char> message;
85+
var warningBuffer = lua._warningBuffer;
86+
if (warningBuffer == null || warningBuffer.Length == 0)
87+
{
88+
message = CreateWarningMessage(msgSpan);
89+
}
90+
else
91+
{
92+
warningBuffer.Write(msgSpan);
93+
_ = warningBuffer.TryGetBuffer(out var buffer);
94+
95+
message = CreateWarningMessage(buffer);
96+
97+
ClearWarningBuffer(warningBuffer);
98+
}
99+
100+
using (message)
101+
{
102+
lua.WarningEmitted?.Invoke(lua, new LuaWarningEmittedEventArgs(message));
103+
}
104+
}
105+
96106
static RentedArray<char> CreateWarningMessage(ReadOnlySpan<byte> msg)
97107
{
98108
var message = RentedArray<char>.Rent(Encoding.UTF8.GetCharCount(msg));
@@ -124,3 +134,24 @@ public void EmitWarning(ReadOnlySpan<char> message)
124134
lua_warning(State.L, message, false);
125135
}
126136
}
137+
138+
/// <summary>
139+
/// Represents a method that will handle the <see cref="Lua.WarningEmitted"/> <see langword="event"/>.
140+
/// </summary>
141+
public delegate void LuaWarningEventHandler(object? sender, LuaWarningEmittedEventArgs e);
142+
143+
/// <summary>
144+
/// Represents event data for <see cref="Lua.WarningEmitted"/>.
145+
/// </summary>
146+
public readonly ref struct LuaWarningEmittedEventArgs
147+
{
148+
/// <summary>
149+
/// Gets the warning message Lua emitted.
150+
/// </summary>
151+
public ReadOnlySpan<char> Message { get; }
152+
153+
internal LuaWarningEmittedEventArgs(ReadOnlySpan<char> message)
154+
{
155+
Message = message;
156+
}
157+
}

src/Laylua/Library/LuaWarningEmittedEventArgs.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)