com.wallstop-studios.unity-helpers 2.0.1 → 2.0.2

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
- bool stopLooping = false;
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
- for (int i = 0; i < entry.Value.Count; i++)
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
- ) existingDecoration = entry.Value[i];
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
- entry.Value[i] = (tag, editorOnly, predicate, format);
429
- return true;
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
- if (stopLooping)
435
- {
436
- break;
437
- }
406
+ RemoveDecorationInternal(existing.priority, existing.index);
438
407
  }
439
408
 
440
- if (
441
- !_matchingDecorations.TryGetValue(
442
- priority,
443
- out List<(
444
- string tag,
445
- bool editorOnly,
446
- Func<string, bool> predicate,
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
- _matchingDecorations[priority] = new List<(
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
- foreach (
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
- for (int i = 0; i < entry.Value.Count; ++i)
497
- {
498
- decoration = entry.Value[i];
499
- if (string.Equals(tag, decoration.tag, StringComparison.OrdinalIgnoreCase))
500
- {
501
- entry.Value.RemoveAt(i);
502
- if (entry.Value.Count == 0)
503
- {
504
- _matchingDecorations.Remove(entry.Key);
505
- }
506
- return true;
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
- decoration = default;
512
- return false;
498
+ return removed;
513
499
  }
514
500
 
515
501
  [HideInCallstack]
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},