#include #include #ifndef ctx_HEADER #define ctx_HEADER template class ctx_Controller { T context; std::list callbacks; std::list functions; bool isProcessingQueue = false; std::list queue; ctx_Controller(const T &c) { context = c; } void executeFunctions() { T c = queue.front(); queue.pop_front(); for (int i = 0; i < functions.size(); ++i) { T ctx = functions[i](c); if (ctx.recentField != "none") { queue.push_back(ctx); } } context = c; reportContext(); } void processQueue() { // Decline recursion. if (isProcessingQueue) { return; } isProcessingQueue = true; while (!queue.empty()) { executeFunctions(); } isProcessingQueue = false; } void registerCallback(void (*cb)(T)) { callbacks.push_back(cb); } void registerFunction(T (*f)(T)) { functions.push_back(f); } void reportContext() { for (int i = 0; i < callbacks.size(); ++i) { callbacks[i](context); } } template void set(const std::string &fieldName, const U &value) { T c = context; c.setField(fieldName, value); c.recentField = fieldName; queue.push_back(c); processQueue(); } }; #endif // ctx_HEADER