Research portable Memory game | Исследовать портируемую игру Память
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
1.7KB

  1. #include <list>
  2. #include <string>
  3. #ifndef ctx_HEADER
  4. #define ctx_HEADER
  5. template <class T> class ctx_Controller {
  6. T context;
  7. std::list<void *(T)> callbacks;
  8. std::list<T *(T)> functions;
  9. bool isProcessingQueue = false;
  10. std::list<T> queue;
  11. ctx_Controller(const T &c) {
  12. context = c;
  13. }
  14. void executeFunctions() {
  15. T c = queue.front();
  16. queue.pop_front();
  17. for (const auto &f : functions) {
  18. T ctx = f(c);
  19. if (ctx.recentField != "none") {
  20. queue.push_back(ctx);
  21. }
  22. }
  23. context.recentField = c.recentField;
  24. context.setField(c.recentField, c.field(c.recentField));
  25. reportContext();
  26. }
  27. void processQueue() {
  28. // Decline recursion.
  29. if (isProcessingQueue) {
  30. return;
  31. }
  32. isProcessingQueue = true;
  33. while (!queue.empty()) {
  34. executeFunctions();
  35. }
  36. isProcessingQueue = false;
  37. }
  38. void registerCallback(void (*cb)(T)) {
  39. callbacks.push_back(cb);
  40. }
  41. void registerFieldCallback(const std::string &fieldName, void (*cb)(T)) {
  42. auto execCB = [fieldName, cb](T c) {
  43. if (c.recentField == fieldName) {
  44. cb(c);
  45. }
  46. };
  47. callbacks.push_back(execCB);
  48. }
  49. void registerFunction(T (*f)(T)) {
  50. functions.push_back(f);
  51. }
  52. void registerFunctions(const std::list<T *(T)> funcs) {
  53. for (const auto &f : funcs) {
  54. functions.push_back(f);
  55. }
  56. }
  57. void reportContext() {
  58. for (const auto &cb : callbacks) {
  59. cb(context);
  60. }
  61. }
  62. template <typename U> void set(const std::string &fieldName, const U &value) {
  63. T c = context;
  64. c.setField(fieldName, value);
  65. c.recentField = fieldName;
  66. queue.push_back(c);
  67. processQueue();
  68. }
  69. };
  70. #endif // ctx_HEADER