]> git.localhorst.tv Git - blank.git/commitdiff
let the server wait a little more efficiently
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 5 Nov 2015 14:32:51 +0000 (15:32 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 5 Nov 2015 14:32:51 +0000 (15:32 +0100)
src/app/IntervalTimer.hpp
src/server/Server.hpp
src/server/ServerState.cpp
src/server/net.cpp

index ee84c65e1b02c068c2de7ae1c5de9ec237e52c9e..2f465ad92880787aa42c4f7f07e4494e30433819 100644 (file)
@@ -35,7 +35,7 @@ public:
        }
        /// true if an interval boundary was passed by the last call to Update()
        bool Hit() const noexcept {
-               return Running() && mod(value, intv) < last_dt;
+               return Running() && IntervalElapsed() < last_dt;
        }
        bool HitOnce() const noexcept {
                return Running() && value >= intv;
@@ -46,6 +46,12 @@ public:
        Time Interval() const noexcept {
                return intv;
        }
+       Time IntervalElapsed() const noexcept {
+               return mod(value, intv);
+       }
+       Time IntervalRemain() const noexcept {
+               return intv - IntervalElapsed();
+       }
        int Iteration() const noexcept {
                return value / intv;
        }
index 3bffafc29d2ada80307be32b5cab2269c49a6a65..40905c8ff7943b1fb4824a6b9830d436c2a8dbc0 100644 (file)
@@ -29,6 +29,10 @@ public:
        Server(const Config::Network &, World &, const World::Config &, const WorldSave &);
        ~Server();
 
+       // wait for data to arrive for at most dt milliseconds
+       void Wait(int dt) noexcept;
+       // true if there's data waiting to be handled
+       bool Ready() noexcept;
        void Handle();
 
        void Update(int dt);
@@ -63,6 +67,7 @@ private:
 private:
        UDPsocket serv_sock;
        UDPpacket serv_pack;
+       SDLNet_SocketSet serv_set;
        std::list<ClientConnection> clients;
 
        World &world;
index 0bec3918c0345bc0e3e836157d3d148ba0ddcac2..7e645edf4a9c55c7f9262ddfe7763f134f3afd4c 100644 (file)
@@ -58,6 +58,15 @@ void ServerState::Handle(const SDL_Event &event) {
 
 void ServerState::Update(int dt) {
        loop_timer.Update(dt);
+       if (!loop_timer.HitOnce() && loop_timer.IntervalRemain() > 1) {
+               server.Wait(loop_timer.IntervalRemain() - 1);
+               return;
+       }
+       if (dt == 0 && !server.Ready()) {
+               // effectively wait in a spin loop
+               return;
+       }
+
        server.Handle();
        int world_dt = 0;
        while (loop_timer.HitOnce()) {
index 47342ffad130b0a2edc6337797fa458eee9863ec..7947c221beb13d803a9b6c6a0c9d14a56f190e8d 100644 (file)
@@ -633,28 +633,54 @@ Server::Server(
        const WorldSave &save)
 : serv_sock(nullptr)
 , serv_pack{ -1, nullptr, 0 }
+, serv_set(SDLNet_AllocSocketSet(1))
 , clients()
 , world(world)
 , spawn_index(world.Chunks().MakeIndex(wc.spawn, 3))
 , save(save)
 , player_model(nullptr)
 , cli(world) {
+       if (!serv_set) {
+               throw NetError("SDLNet_AllocSocketSet");
+       }
+
        serv_sock = SDLNet_UDP_Open(conf.port);
        if (!serv_sock) {
+               SDLNet_FreeSocketSet(serv_set);
                throw NetError("SDLNet_UDP_Open");
        }
 
+       if (SDLNet_UDP_AddSocket(serv_set, serv_sock) == -1) {
+               SDLNet_UDP_Close(serv_sock);
+               SDLNet_FreeSocketSet(serv_set);
+               throw NetError("SDLNet_UDP_AddSocket");
+       }
+
        serv_pack.data = new Uint8[sizeof(Packet)];
        serv_pack.maxlen = sizeof(Packet);
 }
 
 Server::~Server() {
+       for (ClientConnection &client : clients) {
+               client.Disconnected();
+       }
+       clients.clear();
        world.Chunks().UnregisterIndex(spawn_index);
        delete[] serv_pack.data;
+       SDLNet_UDP_DelSocket(serv_set, serv_sock);
        SDLNet_UDP_Close(serv_sock);
+       SDLNet_FreeSocketSet(serv_set);
 }
 
 
+void Server::Wait(int dt) noexcept {
+       SDLNet_CheckSockets(serv_set, dt);
+}
+
+bool Server::Ready() noexcept {
+       return SDLNet_CheckSockets(serv_set, 0) > 0;
+}
+
 void Server::Handle() {
        int result = SDLNet_UDP_Recv(serv_sock, &serv_pack);
        while (result > 0) {