Commit 01ecb83e authored by louiz’'s avatar louiz’

Create a Repeater class and simplify the main loop of batajelo_game_server

parent 79a90ebc
......@@ -7,6 +7,8 @@
#include <utils/time.hpp>
#include <iostream>
#include <network/repetitive_task.hpp>
#include <boost/program_options.hpp>
int main(int ac, char** av)
......@@ -70,17 +72,21 @@ int main(int ac, char** av)
utils::Time last_update = utils::now();
std::chrono::steady_clock::duration dt{0};
while (true)
{
auto now = utils::now();
dt += now - last_update;
last_update = now;
auto ticks = utils::get_number_of_ticks(dt);
for (; ticks > 0; --ticks)
s.tick();
s.poll(10);
}
Repeater ticks_doer([&last_update, &dt, &s]()
{
auto now = utils::now();
dt += now - last_update;
last_update = now;
auto ticks = utils::get_number_of_ticks(dt);
for (; ticks > 0; --ticks)
s.tick();
return true;
},
75ms);
s.run();
log_debug("Exiting...");
return 0;
}
......@@ -83,8 +83,7 @@ public:
*/
void poll()
{
while (IoService::get().poll() != 0)
;
IoService::get().poll();
}
virtual void on_connection_closed() = 0;
......
#include <network/repetitive_task.hpp>
#include <network/ioservice.hpp>
#include <logging/logging.hpp>
#include <boost/chrono.hpp>
Repeater::Repeater(const FuncType& f,
const DurationType& duration):
f(f),
timer(IoService::get()),
duration(duration)
{
this->repeat_forever();
}
void Repeater::repeat_forever()
{
this->timer.expires_at(std::chrono::steady_clock::now() + this->duration);
auto cb = [this](const boost::system::error_code& ec)
{
if (ec)
log_error("Async wait failed: " << ec);
else if (f() == true)
this->repeat_forever();
};
this->timer.async_wait(cb);
}
#ifndef REPETITIVE_TASK_HPP_INCLUDED
#define REPETITIVE_TASK_HPP_INCLUDED
#include <chrono>
#include <functional>
#include <boost/asio/steady_timer.hpp>
/**
* Calls the given function every interval of time, until the function
* returns false.
*/
class Repeater
{
using FuncType = std::function<bool()>;
using TimerType = boost::asio::steady_timer;
using DurationType = std::chrono::milliseconds;
public:
Repeater(const FuncType& f, const DurationType& duration);
~Repeater() = default;
private:
void repeat_forever();
const FuncType f;
TimerType timer;
const DurationType duration;
Repeater(const Repeater&) = delete;
Repeater(Repeater&&) = delete;
Repeater& operator=(const Repeater&) = delete;
Repeater& operator=(Repeater&&) = delete;
};
#endif /* REPETITIVE_TASK_HPP_INCLUDED */
......@@ -65,26 +65,13 @@ public:
* The timeout argument makes this call block for that amount
* of milliseconds.
*/
void poll(long t)
void poll()
{
if (t == 0)
{
while (IoService::get().poll())
;
return ;
}
if (this->timeout.expires_from_now(boost::asio::steady_timer::duration(t)) == 0)
// The last run_one() call returned because the timeout expired, so
// we reinstall it. If that's not the case
// (something actually happened on the socket)
// we just need to reset the time of expiration, but not reinstall it.
this->timeout.async_wait([](const boost::system::error_code&){});
// Wait for one event to happen (either a timeout or something
// on the socket).
IoService::get().run_one();
while (IoService::get().poll() != 0)
; // Execute all other available handlers, if any
IoService::get().poll();
}
void run()
{
IoService::get().run();
}
/**
* To be called by the a RemoteClient instance, to delete itself from
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment