#pragma once
#include <ableton/discovery/AsioTypes.hpp>
#include <ableton/util/Injected.hpp>
#include <chrono>
#include <vector>
namespace ableton
{
namespace discovery
{
template <typename Callback, typename IoContext>
class InterfaceScanner
{
public:
using Timer = typename util::Injected<IoContext>::type::Timer;
InterfaceScanner(const std::chrono::seconds period,
util::Injected<Callback> callback,
util::Injected<IoContext> io)
: mPeriod(period)
, mCallback(std::move(callback))
, mIo(std::move(io))
, mTimer(mIo->makeTimer())
{
}
void enable(const bool bEnable)
{
if (bEnable)
{
scan();
}
else
{
mTimer.cancel();
}
}
void scan()
{
using namespace std;
debug(mIo->log()) << "Scanning network interfaces";
vector<IpAddress> addrs = mIo->scanNetworkInterfaces();
sort(begin(addrs), end(addrs));
addrs.erase(unique(begin(addrs), end(addrs)), end(addrs));
(*mCallback)(std::move(addrs));
mTimer.expires_from_now(mPeriod);
using ErrorCode = typename Timer::ErrorCode;
mTimer.async_wait(
[this](const ErrorCode e)
{
if (!e)
{
scan();
}
});
}
private:
const std::chrono::seconds mPeriod;
util::Injected<Callback> mCallback;
util::Injected<IoContext> mIo;
Timer mTimer;
};
template <typename Callback, typename IoContext>
InterfaceScanner<Callback, IoContext> makeInterfaceScanner(
const std::chrono::seconds period,
util::Injected<Callback> callback,
util::Injected<IoContext> io)
{
return {period, std::move(callback), std::move(io)};
}
} }