com.wallstop-studios.unity-helpers 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -60,6 +60,9 @@ namespace WallstopStudios.UnityHelpers.Core.Helper.Logging
|
|
|
60
60
|
Func<string, object, string> formatter
|
|
61
61
|
)>
|
|
62
62
|
> _matchingDecorations = new();
|
|
63
|
+
private readonly Dictionary<string, (int priority, int index)> _decorationLookup = new(
|
|
64
|
+
StringComparer.OrdinalIgnoreCase
|
|
65
|
+
);
|
|
63
66
|
private readonly StringBuilder _cachedStringBuilder = new();
|
|
64
67
|
private readonly List<string> _cachedDecorators = new();
|
|
65
68
|
private readonly HashSet<string> _appliedTags = new(StringComparer.OrdinalIgnoreCase);
|
|
@@ -379,89 +382,50 @@ namespace WallstopStudios.UnityHelpers.Core.Helper.Logging
|
|
|
379
382
|
bool force = false
|
|
380
383
|
)
|
|
381
384
|
{
|
|
382
|
-
|
|
383
|
-
foreach (
|
|
384
|
-
KeyValuePair<
|
|
385
|
-
int,
|
|
386
|
-
List<(
|
|
387
|
-
string tag,
|
|
388
|
-
bool editorOnly,
|
|
389
|
-
Func<string, bool> predicate,
|
|
390
|
-
Func<string, object, string> formatter
|
|
391
|
-
)>
|
|
392
|
-
> entry in _matchingDecorations
|
|
393
|
-
)
|
|
385
|
+
if (_decorationLookup.TryGetValue(tag, out (int priority, int index) existing))
|
|
394
386
|
{
|
|
395
|
-
|
|
387
|
+
if (!force)
|
|
388
|
+
{
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (existing.priority == priority)
|
|
396
393
|
{
|
|
397
|
-
(
|
|
394
|
+
List<(
|
|
398
395
|
string tag,
|
|
399
396
|
bool editorOnly,
|
|
400
397
|
Func<string, bool> predicate,
|
|
401
398
|
Func<string, object, string> formatter
|
|
402
|
-
)
|
|
403
|
-
if (
|
|
404
|
-
!string.Equals(
|
|
405
|
-
existingDecoration.tag,
|
|
406
|
-
tag,
|
|
407
|
-
StringComparison.OrdinalIgnoreCase
|
|
408
|
-
)
|
|
409
|
-
)
|
|
410
|
-
{
|
|
411
|
-
continue;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
if (force)
|
|
415
|
-
{
|
|
416
|
-
if (priority != entry.Key)
|
|
417
|
-
{
|
|
418
|
-
entry.Value.RemoveAt(i);
|
|
419
|
-
if (entry.Value.Count == 0)
|
|
420
|
-
{
|
|
421
|
-
_matchingDecorations.Remove(entry.Key);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
stopLooping = true;
|
|
425
|
-
break;
|
|
426
|
-
}
|
|
399
|
+
)> decorationsAtPriority = _matchingDecorations[priority];
|
|
427
400
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
return false;
|
|
401
|
+
decorationsAtPriority[existing.index] = (tag, editorOnly, predicate, format);
|
|
402
|
+
_decorationLookup[tag] = (priority, existing.index);
|
|
403
|
+
return true;
|
|
432
404
|
}
|
|
433
405
|
|
|
434
|
-
|
|
435
|
-
{
|
|
436
|
-
break;
|
|
437
|
-
}
|
|
406
|
+
RemoveDecorationInternal(existing.priority, existing.index);
|
|
438
407
|
}
|
|
439
408
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
Func<string, object, string> formatter
|
|
448
|
-
)> matchingDecorations
|
|
449
|
-
)
|
|
450
|
-
)
|
|
409
|
+
List<(
|
|
410
|
+
string tag,
|
|
411
|
+
bool editorOnly,
|
|
412
|
+
Func<string, bool> predicate,
|
|
413
|
+
Func<string, object, string> formatter
|
|
414
|
+
)> matchingDecorations;
|
|
415
|
+
if (!_matchingDecorations.TryGetValue(priority, out matchingDecorations))
|
|
451
416
|
{
|
|
452
|
-
|
|
417
|
+
matchingDecorations = new List<(
|
|
453
418
|
string tag,
|
|
454
419
|
bool editorOnly,
|
|
455
420
|
Func<string, bool> predicate,
|
|
456
421
|
Func<string, object, string> formatter
|
|
457
|
-
)>
|
|
458
|
-
|
|
459
|
-
(tag, editorOnly, predicate, format),
|
|
460
|
-
};
|
|
461
|
-
return true;
|
|
422
|
+
)>(1);
|
|
423
|
+
_matchingDecorations[priority] = matchingDecorations;
|
|
462
424
|
}
|
|
463
425
|
|
|
426
|
+
int indexToInsert = matchingDecorations.Count;
|
|
464
427
|
matchingDecorations.Add((tag, editorOnly, predicate, format));
|
|
428
|
+
_decorationLookup[tag] = (priority, indexToInsert);
|
|
465
429
|
return true;
|
|
466
430
|
}
|
|
467
431
|
|
|
@@ -481,35 +445,57 @@ namespace WallstopStudios.UnityHelpers.Core.Helper.Logging
|
|
|
481
445
|
) decoration
|
|
482
446
|
)
|
|
483
447
|
{
|
|
484
|
-
|
|
485
|
-
KeyValuePair<
|
|
486
|
-
int,
|
|
487
|
-
List<(
|
|
488
|
-
string tag,
|
|
489
|
-
bool editorOnly,
|
|
490
|
-
Func<string, bool> predicate,
|
|
491
|
-
Func<string, object, string> formatter
|
|
492
|
-
)>
|
|
493
|
-
> entry in _matchingDecorations
|
|
494
|
-
)
|
|
448
|
+
if (!_decorationLookup.TryGetValue(tag, out (int priority, int index) existing))
|
|
495
449
|
{
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
450
|
+
decoration = default;
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
decoration = RemoveDecorationInternal(existing.priority, existing.index);
|
|
455
|
+
return true;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private (
|
|
459
|
+
string tag,
|
|
460
|
+
bool editorOnly,
|
|
461
|
+
Func<string, bool> predicate,
|
|
462
|
+
Func<string, object, string> formatter
|
|
463
|
+
) RemoveDecorationInternal(int priority, int index)
|
|
464
|
+
{
|
|
465
|
+
List<(
|
|
466
|
+
string tag,
|
|
467
|
+
bool editorOnly,
|
|
468
|
+
Func<string, bool> predicate,
|
|
469
|
+
Func<string, object, string> formatter
|
|
470
|
+
)> decorationsAtPriority = _matchingDecorations[priority];
|
|
471
|
+
|
|
472
|
+
(
|
|
473
|
+
string tag,
|
|
474
|
+
bool editorOnly,
|
|
475
|
+
Func<string, bool> predicate,
|
|
476
|
+
Func<string, object, string> formatter
|
|
477
|
+
) removed = decorationsAtPriority[index];
|
|
478
|
+
|
|
479
|
+
decorationsAtPriority.RemoveAt(index);
|
|
480
|
+
_decorationLookup.Remove(removed.tag);
|
|
481
|
+
|
|
482
|
+
for (int i = index; i < decorationsAtPriority.Count; ++i)
|
|
483
|
+
{
|
|
484
|
+
(
|
|
485
|
+
string tag,
|
|
486
|
+
bool editorOnly,
|
|
487
|
+
Func<string, bool> predicate,
|
|
488
|
+
Func<string, object, string> formatter
|
|
489
|
+
) entry = decorationsAtPriority[i];
|
|
490
|
+
_decorationLookup[entry.tag] = (priority, i);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (decorationsAtPriority.Count == 0)
|
|
494
|
+
{
|
|
495
|
+
_matchingDecorations.Remove(priority);
|
|
509
496
|
}
|
|
510
497
|
|
|
511
|
-
|
|
512
|
-
return false;
|
|
498
|
+
return removed;
|
|
513
499
|
}
|
|
514
500
|
|
|
515
501
|
[HideInCallstack]
|
|
@@ -48,7 +48,7 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
48
48
|
/// </summary>
|
|
49
49
|
public event Action<string, float, float> OnAttributeModified;
|
|
50
50
|
|
|
51
|
-
private
|
|
51
|
+
private Dictionary<string, Func<object, Attribute>> _attributeFieldGetters;
|
|
52
52
|
private readonly HashSet<EffectHandle> _effectHandles;
|
|
53
53
|
|
|
54
54
|
[SiblingComponent]
|
|
@@ -62,7 +62,6 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
62
62
|
/// </summary>
|
|
63
63
|
protected AttributesComponent()
|
|
64
64
|
{
|
|
65
|
-
_attributeFieldGetters = AttributeUtilities.GetOptimizedAttributeFields(GetType());
|
|
66
65
|
_effectHandles = new HashSet<EffectHandle>();
|
|
67
66
|
}
|
|
68
67
|
|
|
@@ -72,6 +71,7 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
72
71
|
/// </summary>
|
|
73
72
|
protected virtual void Awake()
|
|
74
73
|
{
|
|
74
|
+
EnsureAttributeFieldGettersInitialized();
|
|
75
75
|
this.AssignSiblingComponents();
|
|
76
76
|
_effectHandler.Register(this);
|
|
77
77
|
}
|
|
@@ -217,8 +217,9 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
protected bool TryGetAttribute(string attributeName, out Attribute attribute)
|
|
221
221
|
{
|
|
222
|
+
EnsureAttributeFieldGettersInitialized();
|
|
222
223
|
if (
|
|
223
224
|
!_attributeFieldGetters.TryGetValue(
|
|
224
225
|
attributeName,
|
|
@@ -233,5 +234,15 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
233
234
|
attribute = getter(this);
|
|
234
235
|
return true;
|
|
235
236
|
}
|
|
237
|
+
|
|
238
|
+
protected void EnsureAttributeFieldGettersInitialized()
|
|
239
|
+
{
|
|
240
|
+
if (_attributeFieldGetters != null)
|
|
241
|
+
{
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
_attributeFieldGetters = AttributeUtilities.GetOptimizedAttributeFields(GetType());
|
|
246
|
+
}
|
|
236
247
|
}
|
|
237
248
|
}
|
|
@@ -256,5 +256,89 @@ namespace WallstopStudios.UnityHelpers.Tests.Extensions
|
|
|
256
256
|
formatted = formatter.Log($"{"value":demo}", pretty: false);
|
|
257
257
|
Assert.AreEqual("<P1>value</P1>", formatted);
|
|
258
258
|
}
|
|
259
|
+
|
|
260
|
+
[Test]
|
|
261
|
+
public void ForceOverrideAtSamePriorityReplacesFormatter()
|
|
262
|
+
{
|
|
263
|
+
UnityLogTagFormatter formatter = new(createDefaultDecorators: false);
|
|
264
|
+
|
|
265
|
+
formatter.AddDecoration(
|
|
266
|
+
match: "demo",
|
|
267
|
+
format: value => $"<Initial>{value}</Initial>",
|
|
268
|
+
tag: "Demo",
|
|
269
|
+
priority: 3,
|
|
270
|
+
editorOnly: false,
|
|
271
|
+
force: true
|
|
272
|
+
);
|
|
273
|
+
formatter.AddDecoration(
|
|
274
|
+
match: "demo",
|
|
275
|
+
format: value => $"<Updated>{value}</Updated>",
|
|
276
|
+
tag: "Demo",
|
|
277
|
+
priority: 3,
|
|
278
|
+
editorOnly: false,
|
|
279
|
+
force: true
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
string formatted = formatter.Log($"{"value":demo}", pretty: false);
|
|
283
|
+
Assert.AreEqual("<Updated>value</Updated>", formatted);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
[Test]
|
|
287
|
+
public void DuplicateTagWithoutForceReturnsFalse()
|
|
288
|
+
{
|
|
289
|
+
UnityLogTagFormatter formatter = new(createDefaultDecorators: false);
|
|
290
|
+
|
|
291
|
+
bool firstResult = formatter.AddDecoration(
|
|
292
|
+
match: "demo",
|
|
293
|
+
format: value => $"<Initial>{value}</Initial>",
|
|
294
|
+
tag: "Demo",
|
|
295
|
+
priority: 0,
|
|
296
|
+
editorOnly: false,
|
|
297
|
+
force: false
|
|
298
|
+
);
|
|
299
|
+
Assert.IsTrue(firstResult);
|
|
300
|
+
|
|
301
|
+
bool secondResult = formatter.AddDecoration(
|
|
302
|
+
match: "demo",
|
|
303
|
+
format: value => $"<Ignored>{value}</Ignored>",
|
|
304
|
+
tag: "Demo",
|
|
305
|
+
priority: 10,
|
|
306
|
+
editorOnly: false,
|
|
307
|
+
force: false
|
|
308
|
+
);
|
|
309
|
+
Assert.IsFalse(secondResult);
|
|
310
|
+
|
|
311
|
+
string formatted = formatter.Log($"{"value":demo}", pretty: false);
|
|
312
|
+
Assert.AreEqual("<Initial>value</Initial>", formatted);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
[Test]
|
|
316
|
+
public void RemoveDecorationRemovesFormatter()
|
|
317
|
+
{
|
|
318
|
+
UnityLogTagFormatter formatter = new(createDefaultDecorators: false);
|
|
319
|
+
|
|
320
|
+
formatter.AddDecoration(
|
|
321
|
+
match: "demo",
|
|
322
|
+
format: value => $"<Removed>{value}</Removed>",
|
|
323
|
+
tag: "Demo",
|
|
324
|
+
priority: 0,
|
|
325
|
+
editorOnly: false,
|
|
326
|
+
force: true
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
(
|
|
330
|
+
string tag,
|
|
331
|
+
bool editorOnly,
|
|
332
|
+
Func<string, bool> predicate,
|
|
333
|
+
Func<string, object, string> formatterDelegate
|
|
334
|
+
) removedDecoration;
|
|
335
|
+
bool removed = formatter.RemoveDecoration("Demo", out removedDecoration);
|
|
336
|
+
|
|
337
|
+
Assert.IsTrue(removed);
|
|
338
|
+
Assert.AreEqual("Demo", removedDecoration.tag);
|
|
339
|
+
|
|
340
|
+
string formatted = formatter.Log($"{"value":demo}", pretty: false);
|
|
341
|
+
Assert.AreEqual("value", formatted);
|
|
342
|
+
}
|
|
259
343
|
}
|
|
260
344
|
}
|