/src/Settings.cpp

https://github.com/hduregger/crowd · C++ · 339 lines · 251 code · 88 blank · 0 comment · 18 complexity · 393eeb39ac6cc50f75f7b9ed49d08540 MD5 · raw file

  1. #include "Settings.h"
  2. #include <QSettings>
  3. #include "Exception.h"
  4. #include "MainWindow.h"
  5. const float Settings::MINIMAL_RADIUS = 0.4f;
  6. const QString Settings::DEFAULT_CONFIG_FILE = "default.cfg";
  7. const QString Settings::MAP_MAP_FILE = "Map/mapFile";
  8. const QString Settings::MAP_DISCOMFORT_FILE = "Map/discomfortFile";
  9. const QString Settings::MAP_EXIT_FILE = "Map/exitFile";
  10. const QString Settings::SOLVER_WORK_GROUP_SIDE_LENGTH = "Solver/workGroupSideLength";
  11. const QString Settings::SOLVER_IS_USING_GPU = "Solver/isUsingGPU";
  12. const QString Settings::SOLVER_OUTER_ITERATIONS = "Solver/outerIterations";
  13. const QString Settings::SOLVER_COST_WEIGHT_LENGTH = "Solver/costWeightLength";
  14. const QString Settings::SOLVER_COST_WEIGHT_TIME = "Solver/costWeightTime";
  15. const QString Settings::SOLVER_COST_WEIGHT_DISCOMFORT = "Solver/costWeightDiscomfort";
  16. const QString Settings::AGENT_COUNT = "Agents/count";
  17. const QString Settings::AGENT_MINIMUM_RADIUS = "Agents/minimumRadius";
  18. const QString Settings::AGENT_MAXIMUM_RADIUS = "Agents/maximumRadius";
  19. const QString Settings::AGENT_SEED = "Agents/seed";
  20. const QString Settings::AGENT_GROUP0_TEXTURE = "Agents/group0Texture";
  21. const QString Settings::AGENT_GROUP1_TEXTURE = "Agents/group1Texture";
  22. const QString Settings::AGENT_GROUP2_TEXTURE = "Agents/group2Texture";
  23. const QString Settings::AGENT_GROUP3_TEXTURE = "Agents/group3Texture";
  24. const QString Settings::AGENT_ENTRY0_LOWER_LEFT_X = "Agents.Entry1/lowerLeftX";
  25. const QString Settings::AGENT_ENTRY0_LOWER_LEFT_Y = "Agents.Entry1/lowerLeftY";
  26. const QString Settings::AGENT_ENTRY0_UPPER_RIGHT_X = "Agents.Entry1/upperRightX";
  27. const QString Settings::AGENT_ENTRY0_UPPER_RIGHT_Y = "Agents.Entry1/upperRightY";
  28. const QString Settings::AGENT_ENTRY1_LOWER_LEFT_X = "Agents.Entry2/lowerLeftX";
  29. const QString Settings::AGENT_ENTRY1_LOWER_LEFT_Y = "Agents.Entry2/lowerLeftY";
  30. const QString Settings::AGENT_ENTRY1_UPPER_RIGHT_X = "Agents.Entry2/upperRightX";
  31. const QString Settings::AGENT_ENTRY1_UPPER_RIGHT_Y = "Agents.Entry2/upperRightY";
  32. const QString Settings::AGENT_ENTRY2_LOWER_LEFT_X = "Agents.Entry3/lowerLeftX";
  33. const QString Settings::AGENT_ENTRY2_LOWER_LEFT_Y = "Agents.Entry3/lowerLeftY";
  34. const QString Settings::AGENT_ENTRY2_UPPER_RIGHT_X = "Agents.Entry3/upperRightX";
  35. const QString Settings::AGENT_ENTRY2_UPPER_RIGHT_Y = "Agents.Entry3/upperRightY";
  36. const QString Settings::AGENT_ENTRY3_LOWER_LEFT_X = "Agents.Entry4/lowerLeftX";
  37. const QString Settings::AGENT_ENTRY3_LOWER_LEFT_Y = "Agents.Entry4/lowerLeftY";
  38. const QString Settings::AGENT_ENTRY3_UPPER_RIGHT_X = "Agents.Entry4/upperRightX";
  39. const QString Settings::AGENT_ENTRY3_UPPER_RIGHT_Y = "Agents.Entry4/upperRightY";
  40. const QString Settings::AGENT_META_MOVEMENT_MODE = "Agents/movementMode";
  41. const QString Settings::DEBUG_IS_PROFILING_QUEUE = "Debug/isProfilingQueue";
  42. Settings::Settings(QString filename)
  43. : mapFile(""),
  44. discomfortFile(""),
  45. exitFile(""),
  46. workGroupSideLength(0),
  47. isUsingGPU(true),
  48. isProfilingQueue(false),
  49. agentCount(0),
  50. agentSeed(0),
  51. agentEntry0(Vector4i(0, 0, 0, 0)),
  52. agentEntry1(Vector4i(0, 0, 0, 0)),
  53. agentEntry2(Vector4i(0, 0, 0, 0)),
  54. agentEntry3(Vector4i(0, 0, 0, 0)),
  55. agentsGroup0Texture(""),
  56. agentsGroup1Texture(""),
  57. agentsGroup2Texture(""),
  58. agentsGroup3Texture(""),
  59. minimumRadius(0.0f),
  60. maximumRadius(0.0f),
  61. outerIterations(1),
  62. costWeightLength(1.0f),
  63. costWeightTime(1.0f),
  64. costWeightDiscomfort(1.0f),
  65. movementMode(0)
  66. {
  67. QSettings* settings = new QSettings(filename, QSettings::IniFormat);
  68. checkExist(settings, Settings::MAP_MAP_FILE);
  69. mapFile = settings->value(Settings::MAP_MAP_FILE).toString();
  70. checkExist(settings, Settings::MAP_DISCOMFORT_FILE);
  71. discomfortFile = settings->value(Settings::MAP_DISCOMFORT_FILE).toString();
  72. checkExist(settings, Settings::MAP_EXIT_FILE);
  73. exitFile = settings->value(Settings::MAP_EXIT_FILE).toString();
  74. bool isValid = true;
  75. checkExist(settings, Settings::AGENT_COUNT);
  76. agentCount = settings->value(Settings::AGENT_COUNT).toUInt(&isValid);
  77. checkValid(isValid, "Invalid agent count!");
  78. checkExist(settings, Settings::AGENT_SEED);
  79. agentSeed = settings->value(Settings::AGENT_SEED).toInt(&isValid);
  80. checkValid(isValid, "Invalid agent seed!");
  81. checkExist(settings, Settings::AGENT_META_MOVEMENT_MODE);
  82. movementMode = settings->value(Settings::AGENT_META_MOVEMENT_MODE).toInt(&isValid);
  83. checkValid(isValid, "Invalid agent movement mode!");
  84. checkExist(settings, Settings::SOLVER_WORK_GROUP_SIDE_LENGTH);
  85. workGroupSideLength = static_cast<size_t> (settings->value(Settings::SOLVER_WORK_GROUP_SIDE_LENGTH).toUInt(&isValid));
  86. checkValid(isValid, "Invalid work group side length!");
  87. checkExist(settings, Settings::SOLVER_OUTER_ITERATIONS);
  88. outerIterations = static_cast<size_t> (settings->value(Settings::SOLVER_OUTER_ITERATIONS).toInt(&isValid));
  89. checkValid(isValid, "Invalid number of outer iterations!");
  90. checkExist(settings, Settings::SOLVER_IS_USING_GPU);
  91. isUsingGPU = settings->value(Settings::SOLVER_IS_USING_GPU).toBool();
  92. checkExist(settings, Settings::SOLVER_COST_WEIGHT_LENGTH);
  93. costWeightLength = settings->value(Settings::SOLVER_COST_WEIGHT_LENGTH).toFloat(&isValid);
  94. checkValid(isValid, "Invalid cost weight for length!");
  95. checkExist(settings, Settings::SOLVER_COST_WEIGHT_TIME);
  96. costWeightTime = settings->value(Settings::SOLVER_COST_WEIGHT_TIME).toFloat(&isValid);
  97. checkValid(isValid, "Invalid cost weight for time!");
  98. checkExist(settings, Settings::SOLVER_COST_WEIGHT_DISCOMFORT);
  99. costWeightDiscomfort = settings->value(Settings::SOLVER_COST_WEIGHT_DISCOMFORT).toFloat(&isValid);
  100. checkValid(isValid, "Invalid cost weight for discomfort!");
  101. checkExist(settings, Settings::AGENT_ENTRY0_LOWER_LEFT_X);
  102. agentEntry0.x = settings->value(Settings::AGENT_ENTRY0_LOWER_LEFT_X).toInt(&isValid);
  103. checkValid(isValid, "Invalid agent entry 1!");
  104. checkExist(settings, Settings::AGENT_ENTRY0_LOWER_LEFT_Y);
  105. agentEntry0.y = settings->value(Settings::AGENT_ENTRY0_LOWER_LEFT_Y).toInt(&isValid);
  106. checkValid(isValid, "Invalid agent entry 1!");
  107. checkExist(settings, Settings::AGENT_ENTRY0_UPPER_RIGHT_X);
  108. agentEntry0.z = settings->value(Settings::AGENT_ENTRY0_UPPER_RIGHT_X).toInt(&isValid);
  109. checkValid(isValid, "Invalid agent entry 1!");
  110. checkExist(settings, Settings::AGENT_ENTRY0_UPPER_RIGHT_Y);
  111. agentEntry0.w = settings->value(Settings::AGENT_ENTRY0_UPPER_RIGHT_Y).toInt(&isValid);
  112. checkValid(isValid, "Invalid agent entry 1!");
  113. checkExist(settings, Settings::AGENT_ENTRY1_LOWER_LEFT_X);
  114. agentEntry1.x = settings->value(Settings::AGENT_ENTRY1_LOWER_LEFT_X).toInt(&isValid);
  115. checkValid(isValid, "Invalid agent entry 2!");
  116. checkExist(settings, Settings::AGENT_ENTRY1_LOWER_LEFT_Y);
  117. agentEntry1.y = settings->value(Settings::AGENT_ENTRY1_LOWER_LEFT_Y).toInt(&isValid);
  118. checkValid(isValid, "Invalid agent entry 2!");
  119. checkExist(settings, Settings::AGENT_ENTRY1_UPPER_RIGHT_X);
  120. agentEntry1.z = settings->value(Settings::AGENT_ENTRY1_UPPER_RIGHT_X).toInt(&isValid);
  121. checkValid(isValid, "Invalid agent entry 2!");
  122. checkExist(settings, Settings::AGENT_ENTRY1_UPPER_RIGHT_Y);
  123. agentEntry1.w = settings->value(Settings::AGENT_ENTRY1_UPPER_RIGHT_Y).toInt(&isValid);
  124. checkValid(isValid, "Invalid agent entry 2!");
  125. checkExist(settings, Settings::AGENT_ENTRY2_LOWER_LEFT_X);
  126. agentEntry2.x = settings->value(Settings::AGENT_ENTRY2_LOWER_LEFT_X).toInt(&isValid);
  127. checkValid(isValid, "Invalid agent entry 3!");
  128. checkExist(settings, Settings::AGENT_ENTRY2_LOWER_LEFT_Y);
  129. agentEntry2.y = settings->value(Settings::AGENT_ENTRY2_LOWER_LEFT_Y).toInt(&isValid);
  130. checkValid(isValid, "Invalid agent entry 3!");
  131. checkExist(settings, Settings::AGENT_ENTRY2_UPPER_RIGHT_X);
  132. agentEntry2.z = settings->value(Settings::AGENT_ENTRY2_UPPER_RIGHT_X).toInt(&isValid);
  133. checkValid(isValid, "Invalid agent entry 3!");
  134. checkExist(settings, Settings::AGENT_ENTRY2_UPPER_RIGHT_Y);
  135. agentEntry2.w = settings->value(Settings::AGENT_ENTRY2_UPPER_RIGHT_Y).toInt(&isValid);
  136. checkValid(isValid, "Invalid agent entry 3!");
  137. checkExist(settings, Settings::AGENT_ENTRY3_LOWER_LEFT_X);
  138. agentEntry3.x = settings->value(Settings::AGENT_ENTRY3_LOWER_LEFT_X).toInt(&isValid);
  139. checkValid(isValid, "Invalid agent entry 4!");
  140. checkExist(settings, Settings::AGENT_ENTRY3_LOWER_LEFT_Y);
  141. agentEntry3.y = settings->value(Settings::AGENT_ENTRY3_LOWER_LEFT_Y).toInt(&isValid);
  142. checkValid(isValid, "Invalid agent entry 4!");
  143. checkExist(settings, Settings::AGENT_ENTRY3_UPPER_RIGHT_X);
  144. agentEntry3.z = settings->value(Settings::AGENT_ENTRY3_UPPER_RIGHT_X).toInt(&isValid);
  145. checkValid(isValid, "Invalid agent entry 4!");
  146. checkExist(settings, Settings::AGENT_ENTRY3_UPPER_RIGHT_Y);
  147. agentEntry3.w = settings->value(Settings::AGENT_ENTRY3_UPPER_RIGHT_Y).toInt(&isValid);
  148. checkValid(isValid, "Invalid agent entry 4!");
  149. checkExist(settings, Settings::AGENT_GROUP0_TEXTURE);
  150. agentsGroup0Texture = settings->value(Settings::AGENT_GROUP0_TEXTURE).toString();
  151. checkExist(settings, Settings::AGENT_GROUP1_TEXTURE);
  152. agentsGroup1Texture = settings->value(Settings::AGENT_GROUP1_TEXTURE).toString();
  153. checkExist(settings, Settings::AGENT_GROUP2_TEXTURE);
  154. agentsGroup2Texture = settings->value(Settings::AGENT_GROUP2_TEXTURE).toString();
  155. checkExist(settings, Settings::AGENT_GROUP3_TEXTURE);
  156. agentsGroup3Texture = settings->value(Settings::AGENT_GROUP3_TEXTURE).toString();
  157. checkExist(settings, Settings::DEBUG_IS_PROFILING_QUEUE);
  158. isProfilingQueue = settings->value(Settings::DEBUG_IS_PROFILING_QUEUE).toBool();
  159. checkExist(settings, Settings::AGENT_MINIMUM_RADIUS);
  160. minimumRadius = settings->value(Settings::AGENT_MINIMUM_RADIUS).toFloat(&isValid);
  161. checkValid(isValid, "Invalid minimum agent radius!");
  162. checkExist(settings, Settings::AGENT_MAXIMUM_RADIUS);
  163. maximumRadius = settings->value(Settings::AGENT_MAXIMUM_RADIUS).toFloat(&isValid);
  164. checkValid(isValid, "Invalid maximum agent radius!");
  165. if (minimumRadius < Settings::MINIMAL_RADIUS)
  166. {
  167. throw Exception("Minimum radius is less than " + QString::number(Settings::MINIMAL_RADIUS) + ". Check your config file!");
  168. }
  169. if (maximumRadius < minimumRadius)
  170. {
  171. throw Exception("Maximum radius is less than minimum radius. Check your config file!");
  172. }
  173. if ((outerIterations < 1) || (outerIterations > 200))
  174. {
  175. throw Exception("Outer iteration count must be inside [1, 200]. Check your config file!");
  176. }
  177. if ((costWeightLength < MainWindow::WEIGHT_LOWER_BOUND) || (costWeightLength > MainWindow::WEIGHT_UPPER_BOUND))
  178. {
  179. throw Exception("Cost weight length must be inside [1, 200]. Check your config file!");
  180. }
  181. if ((costWeightTime < MainWindow::WEIGHT_LOWER_BOUND) || (costWeightTime > MainWindow::WEIGHT_UPPER_BOUND))
  182. {
  183. throw Exception("Cost weight time must be inside [1, 200]. Check your config file!");
  184. }
  185. if ((costWeightDiscomfort < MainWindow::WEIGHT_LOWER_BOUND) || (costWeightDiscomfort > MainWindow::WEIGHT_UPPER_BOUND))
  186. {
  187. throw Exception("Cost weight discomfort must be inside [1, 200]. Check your config file!");
  188. }
  189. if ((movementMode != 0) && (movementMode != 1) && (movementMode != 2))
  190. {
  191. throw Exception("Agent movement mode must be 0 (Park), 1 (Change Group), or 2 (Respawn). Check your config file!");
  192. }
  193. delete settings;
  194. }
  195. Settings::~Settings()
  196. {
  197. }
  198. void Settings::checkValid(bool isValid, QString errorMessage)
  199. {
  200. if (!isValid)
  201. {
  202. throw Exception(errorMessage);
  203. }
  204. }
  205. void Settings::checkExist(const QSettings* settings, QString keyName)
  206. {
  207. if (!settings->contains(keyName))
  208. {
  209. throw Exception("Settings do not contain an entry for \"" + keyName + "\"");
  210. }
  211. }
  212. void Settings::createDefault()
  213. {
  214. QSettings* settings = new QSettings(Settings::DEFAULT_CONFIG_FILE, QSettings::IniFormat);
  215. settings->setValue(Settings::MAP_MAP_FILE, "");
  216. settings->setValue(Settings::MAP_DISCOMFORT_FILE, "");
  217. settings->setValue(Settings::MAP_EXIT_FILE, "");
  218. settings->setValue(Settings::AGENT_COUNT, 64);
  219. settings->setValue(Settings::AGENT_MINIMUM_RADIUS, 0.5);
  220. settings->setValue(Settings::AGENT_MAXIMUM_RADIUS, 1.0);
  221. settings->setValue(Settings::AGENT_SEED, -1);
  222. settings->setValue(Settings::AGENT_META_MOVEMENT_MODE, 0);
  223. settings->setValue(Settings::AGENT_GROUP0_TEXTURE, "");
  224. settings->setValue(Settings::AGENT_GROUP1_TEXTURE, "");
  225. settings->setValue(Settings::AGENT_GROUP2_TEXTURE, "");
  226. settings->setValue(Settings::AGENT_GROUP3_TEXTURE, "");
  227. settings->setValue(Settings::AGENT_ENTRY0_LOWER_LEFT_X, 100);
  228. settings->setValue(Settings::AGENT_ENTRY0_LOWER_LEFT_Y, 100);
  229. settings->setValue(Settings::AGENT_ENTRY0_UPPER_RIGHT_X, 110);
  230. settings->setValue(Settings::AGENT_ENTRY0_UPPER_RIGHT_Y, 110);
  231. settings->setValue(Settings::AGENT_ENTRY1_LOWER_LEFT_X, 100);
  232. settings->setValue(Settings::AGENT_ENTRY1_LOWER_LEFT_Y, 100);
  233. settings->setValue(Settings::AGENT_ENTRY1_UPPER_RIGHT_X, 110);
  234. settings->setValue(Settings::AGENT_ENTRY1_UPPER_RIGHT_Y, 110);
  235. settings->setValue(Settings::AGENT_ENTRY2_LOWER_LEFT_X, 100);
  236. settings->setValue(Settings::AGENT_ENTRY2_LOWER_LEFT_Y, 100);
  237. settings->setValue(Settings::AGENT_ENTRY2_UPPER_RIGHT_X, 110);
  238. settings->setValue(Settings::AGENT_ENTRY2_UPPER_RIGHT_Y, 110);
  239. settings->setValue(Settings::AGENT_ENTRY3_LOWER_LEFT_X, 100);
  240. settings->setValue(Settings::AGENT_ENTRY3_LOWER_LEFT_Y, 100);
  241. settings->setValue(Settings::AGENT_ENTRY3_UPPER_RIGHT_X, 110);
  242. settings->setValue(Settings::AGENT_ENTRY3_UPPER_RIGHT_Y, 110);
  243. settings->setValue(Settings::SOLVER_WORK_GROUP_SIDE_LENGTH, 16);
  244. settings->setValue(Settings::SOLVER_IS_USING_GPU, true);
  245. settings->setValue(Settings::SOLVER_OUTER_ITERATIONS, 75);
  246. settings->setValue(Settings::SOLVER_COST_WEIGHT_LENGTH, 1.0);
  247. settings->setValue(Settings::SOLVER_COST_WEIGHT_TIME, 1.0);
  248. settings->setValue(Settings::SOLVER_COST_WEIGHT_DISCOMFORT, 1.0);
  249. settings->setValue(Settings::DEBUG_IS_PROFILING_QUEUE, true);
  250. delete settings;
  251. }