Skip to content

Instantly share code, notes, and snippets.

@mcspr
Last active March 17, 2020 20:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcspr/b402d22c3fb0dcc7520489f7266c902c to your computer and use it in GitHub Desktop.
Save mcspr/b402d22c3fb0dcc7520489f7266c902c to your computer and use it in GitHub Desktop.
#include <cstdint>
#include <functional>
#include <iostream>
#include <memory>
#include <queue>
#include <vector>
struct JsonObject {};
using ws_on_send_callback_f = std::function<void(JsonObject& root)>;
using ws_on_send_callback_list_t = std::vector<ws_on_send_callback_f>;
struct ws_data_t {
enum mode_t {
SEQUENCE,
ALL
};
ws_data_t(const ws_on_send_callback_f& cb) :
storage(new ws_on_send_callback_list_t {cb}),
client_id(0),
mode(ALL),
callbacks(*storage.get()),
current(callbacks.begin())
{}
ws_data_t(uint32_t client_id, const ws_on_send_callback_f& cb) :
storage(new ws_on_send_callback_list_t {cb}),
client_id(client_id),
mode(ALL),
callbacks(*storage.get()),
current(callbacks.begin())
{}
ws_data_t(const uint32_t client_id, ws_on_send_callback_list_t&& callbacks, mode_t mode = SEQUENCE) :
storage(new ws_on_send_callback_list_t(std::move(callbacks))),
client_id(client_id),
mode(mode),
callbacks(*storage.get()),
current(callbacks.begin())
{}
ws_data_t(const uint32_t client_id, const ws_on_send_callback_list_t& callbacks, mode_t mode = SEQUENCE) :
client_id(client_id),
mode(mode),
callbacks(callbacks),
current(callbacks.begin())
{}
bool done() {
return current == callbacks.end();
}
void sendAll(JsonObject& root) {
current = callbacks.end();
for (auto& callback : callbacks) {
callback(root);
}
}
void sendCurrent(JsonObject& root) {
if (current == callbacks.end()) return;
(*current)(root);
++current;
}
void send(JsonObject& root) {
switch (mode) {
case SEQUENCE: sendCurrent(root); break;
case ALL: sendAll(root); break;
}
}
std::unique_ptr<ws_on_send_callback_list_t> storage;
const uint32_t client_id;
const mode_t mode;
const ws_on_send_callback_list_t& callbacks;
ws_on_send_callback_list_t::const_iterator current;
};
std::queue<ws_data_t> _ws_client_data;
void wsPost(const ws_on_send_callback_f& cb) {
_ws_client_data.emplace(cb);
}
void wsPost(uint32_t client_id, const ws_on_send_callback_f& cb) {
_ws_client_data.emplace(client_id, cb);
}
void wsPostAll(uint32_t client_id, const ws_on_send_callback_list_t& cbs) {
_ws_client_data.emplace(client_id, cbs, ws_data_t::ALL);
}
void wsPostAll(const ws_on_send_callback_list_t& cbs) {
_ws_client_data.emplace(0, cbs, ws_data_t::ALL);
}
void wsPostSequence(uint32_t client_id, const ws_on_send_callback_list_t& cbs) {
_ws_client_data.emplace(client_id, cbs, ws_data_t::SEQUENCE);
}
void wsPostSequence(uint32_t client_id, ws_on_send_callback_list_t&& cbs) {
_ws_client_data.emplace(client_id, std::forward<ws_on_send_callback_list_t>(cbs), ws_data_t::SEQUENCE);
}
void wsPostSequence(const ws_on_send_callback_list_t& cbs) {
_ws_client_data.emplace(0, cbs, ws_data_t::SEQUENCE);
}
void check_all(ws_on_send_callback_list_t& list) {
wsPostAll(list);
auto& data = _ws_client_data.front();
JsonObject root;
data.send(root);
_ws_client_data.pop();
}
void check_sequence(ws_on_send_callback_list_t& list) {
wsPostSequence(list);
auto& data = _ws_client_data.front();
while (!data.done()) {
JsonObject root;
data.send(root);
}
_ws_client_data.pop();
}
int main() {
ws_on_send_callback_list_t empty;
ws_on_send_callback_list_t cbs {
[](JsonObject&) {
std::cout << "one" << std::endl;
},
[](JsonObject&) {
std::cout << "two" << std::endl;
},
[](JsonObject&) {
std::cout << "three" << std::endl;
}
};
check_sequence(empty);
check_sequence(cbs);
check_all(empty);
check_all(cbs);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment