#pragma once #include "server_base.hpp" #include "server_list.hpp" #include "client_list.hpp" #include "service.hpp" class server : public server_base { public: server(const network::address& bind_addr); server_list& get_server_list(); const server_list& get_server_list() const; client_list& get_client_list(); const client_list& get_client_list() const; template T* get_service() { static_assert(std::is_base_of_v, "Type must be a service!"); for (auto& service : this->services_) { const auto& service_ref = *service; if (typeid(service_ref) == typeid(T)) { return reinterpret_cast(service.get()); } } return nullptr; } private: server_list server_list_; client_list client_list_; std::vector> services_; std::unordered_map command_services_; template void register_service(Args&&... args) { static_assert(std::is_base_of_v, "Type must be a service!"); auto service = std::make_unique(*this, std::forward(args)...); auto* const command = service->get_command(); if (command) { command_services_[command] = service.get(); } services_.emplace_back(std::move(service)); } void run_frame() override; void handle_command(const network::address& target, const std::string_view& command, const std::string_view& data) override; };