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.

93 lines
1.9KB

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