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.

87 lines
1.8KB

  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 registerFunction(std::function<T(T)> f) {
  41. functions.push_back(f);
  42. }
  43. void registerCallback(std::function<void(T)> cb) {
  44. callbacks.push_back(cb);
  45. }
  46. void registerFieldCallback(
  47. const std::string &fieldName,
  48. std::function<void(T)> cb
  49. ) {
  50. auto execCB = [fieldName, cb](T c) {
  51. if (c.recentField == fieldName) {
  52. cb(c);
  53. }
  54. };
  55. callbacks.push_back(execCB);
  56. }
  57. void reportContext() {
  58. for (const auto &cb : callbacks) {
  59. cb(context);
  60. }
  61. }
  62. template <typename U> void set(
  63. const std::string &fieldName,
  64. const U &value
  65. ) {
  66. auto c = context;
  67. c.setField(fieldName, value);
  68. c.recentField = fieldName;
  69. queue.push(c);
  70. processQueue();
  71. }
  72. };
  73. #endif // ctx_HEADER