DungeonValidator.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. using DunGen.Graph;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using UnityEngine;
  7. namespace DunGen.Editor.Validation
  8. {
  9. public sealed class DungeonValidator
  10. {
  11. public static readonly DungeonValidator Instance = new DungeonValidator();
  12. #region Nested Types
  13. public enum MessageType
  14. {
  15. Warning,
  16. Error,
  17. }
  18. public sealed class Message
  19. {
  20. public MessageType Type { get; private set; }
  21. public string Text { get; private set; }
  22. public UnityEngine.Object Context { get; private set; }
  23. public int Count { get; set; }
  24. public Message(MessageType messageType, string text, UnityEngine.Object context = null)
  25. {
  26. Type = messageType;
  27. Text = text;
  28. Context = context;
  29. Count = 1;
  30. }
  31. }
  32. #endregion
  33. private readonly List<IValidationRule> rules = new List<IValidationRule>();
  34. private readonly List<Message> messages = new List<Message>();
  35. public DungeonValidator()
  36. {
  37. var ruleTypes = Assembly.GetExecutingAssembly().GetTypes()
  38. .Where(t => typeof(IValidationRule).IsAssignableFrom(t) && !t.IsAbstract);
  39. foreach (var type in ruleTypes)
  40. rules.Add((IValidationRule)Activator.CreateInstance(type));
  41. }
  42. public bool Validate(DungeonFlow dungeonFlow)
  43. {
  44. messages.Clear();
  45. foreach (var rule in rules)
  46. rule.Validate(dungeonFlow, this);
  47. PrintMessages(dungeonFlow);
  48. return !messages.Any(m => m.Type == MessageType.Error);
  49. }
  50. #region AddMessage Helpers
  51. public void AddWarning(string format, params object[] args)
  52. {
  53. AddMessage(MessageType.Warning, string.Format(format, args));
  54. }
  55. public void AddWarning(string format, UnityEngine.Object context, params object[] args)
  56. {
  57. AddMessage(MessageType.Warning, string.Format(format, args), context);
  58. }
  59. public void AddWarning(string text, UnityEngine.Object context = null)
  60. {
  61. AddMessage(MessageType.Warning, text, context);
  62. }
  63. public void AddError(string format, params object[] args)
  64. {
  65. AddMessage(MessageType.Error, string.Format(format, args));
  66. }
  67. public void AddError(string format, UnityEngine.Object context = null, params object[] args)
  68. {
  69. AddMessage(MessageType.Error, string.Format(format, args), context);
  70. }
  71. public void AddError(string text, UnityEngine.Object context = null)
  72. {
  73. AddMessage(MessageType.Error, text, context);
  74. }
  75. #endregion
  76. private void AddMessage(MessageType type, string text, UnityEngine.Object context = null)
  77. {
  78. foreach (var message in messages)
  79. {
  80. if (message.Type == type &&
  81. message.Text == text &&
  82. message.Context == context)
  83. {
  84. message.Count++;
  85. return;
  86. }
  87. }
  88. messages.Add(new Message(type, text, context));
  89. }
  90. private void PrintMessages(UnityEngine.Object defaultContext)
  91. {
  92. var orderedMessages = messages.OrderByDescending(m => m.Type);
  93. if (orderedMessages.Any())
  94. {
  95. foreach (var message in orderedMessages)
  96. {
  97. string text = (message.Count < 2) ? message.Text : message.Text + " (x" + message.Count + ")";
  98. var context = (message.Context == null) ? defaultContext : message.Context;
  99. switch (message.Type)
  100. {
  101. case MessageType.Warning:
  102. Debug.LogWarning(text, context);
  103. break;
  104. case MessageType.Error:
  105. Debug.LogError(text, context);
  106. break;
  107. default:
  108. throw new Exception(typeof(MessageType).Name + "." + message.Type + " is not implemented");
  109. }
  110. }
  111. }
  112. else
  113. {
  114. Debug.Log("No issues were found in the dungeon flow");
  115. }
  116. }
  117. }
  118. }