#pragma once #include #include "servers/service_server.hpp" namespace demonware { class service { using callback_t = std::function; uint8_t id_; std::string name_; std::mutex mutex_; uint8_t task_id_; std::map tasks_; public: virtual ~service() = default; service(service&&) = delete; service(const service&) = delete; service& operator=(const service&) = delete; service(const uint8_t id, std::string name) : id_(id), name_(std::move(name)), task_id_(0) { } uint8_t id() const { return this->id_; } const std::string& name() const { return this->name_; } uint8_t task_id() const { return this->task_id_; } virtual void exec_task(service_server* server, const std::string& data) { std::lock_guard _(this->mutex_); byte_buffer buffer(data); buffer.read_ubyte(&this->task_id_); const auto& it = this->tasks_.find(this->task_id_); if (it != this->tasks_.end()) { #ifndef NDEBUG logger::write(logger::LOG_TYPE_DEBUG, "[DW] %s: executing task '%d'", name_.data(), this->task_id_); #endif it->second(server, &buffer); } else { logger::write(logger::LOG_TYPE_DEBUG, "[DW] %s: missing task '%d'", name_.data(), this->task_id_); // return no error server->create_reply(this->task_id_)->send(); } } protected: template void register_task(const uint8_t id, T (Class::* callback)(Args ...) const) { this->tasks_[id] = [this, callback](Args ... args) -> T { return (reinterpret_cast(this)->*callback)(args...); }; } template void register_task(const uint8_t id, T (Class::* callback)(Args ...)) { this->tasks_[id] = [this, callback](Args ... args) -> T { return (reinterpret_cast(this)->*callback)(args...); }; } }; }