Research portable Memory game | Исследовать портируемую игру Память
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

93 wiersze
1.9KB

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