#pragma once #include #include #include #include struct sockaddr_in6; namespace erebos { using std::vector; using std::unique_ptr; class ServerConfig; class Server { struct Priv; public: Server(const Head &, ServerConfig &&); Server(const std::shared_ptr &); ~Server(); Server(const Server &) = delete; Server & operator=(const Server &) = delete; const Head & localHead() const; const Bhv & localState() const; Identity identity() const; template S & svc(); class PeerList & peerList() const; struct Peer; private: Service & svcHelper(const std::type_info &); const std::shared_ptr p; }; class ServerConfig { public: ServerConfig() = default; ServerConfig(const ServerConfig &) = delete; ServerConfig(ServerConfig &&) = default; ServerConfig & operator=(const ServerConfig &) = delete; ServerConfig & operator=(ServerConfig &&) = default; template typename S::Config & service(); private: friend class Server; vector(const Server &)>> services; }; template S & Server::svc() { return dynamic_cast(svcHelper(typeid(S))); } template typename S::Config & ServerConfig::service() { auto config = make_shared(); auto & configRef = *config; services.push_back([config = move(config)](const Server & server) { return make_unique(move(*config), server); }); return configRef; } class Peer { public: struct Priv; Peer(const std::shared_ptr & p); ~Peer(); Server server() const; const Storage & tempStorage() const; const PartialStorage & partialStorage() const; std::string name() const; std::optional identity() const; const struct sockaddr_in6 & address() const; string addressStr() const; uint16_t port() const; bool hasChannel() const; bool send(UUID, const Ref &) const; bool send(UUID, const Object &) const; bool operator==(const Peer & other) const; bool operator!=(const Peer & other) const; bool operator<(const Peer & other) const; bool operator<=(const Peer & other) const; bool operator>(const Peer & other) const; bool operator>=(const Peer & other) const; private: bool send(UUID, const Ref &, const Object &) const; std::shared_ptr p; }; class PeerList { public: struct Priv; PeerList(); PeerList(const std::shared_ptr & p); ~PeerList(); size_t size() const; Peer at(size_t n) const; void onUpdate(std::function); private: friend Server; const std::shared_ptr p; }; }