Core/CallOnExit: Rework to use template instead of std::function

This commit is contained in:
Jérôme Leclercq 2022-01-23 00:16:09 +01:00
parent 29786765c6
commit 2ebcddf9de
5 changed files with 85 additions and 100 deletions

View File

@ -8,29 +8,32 @@
#define NAZARA_CORE_CALLONEXIT_HPP #define NAZARA_CORE_CALLONEXIT_HPP
#include <Nazara/Prerequisites.hpp> #include <Nazara/Prerequisites.hpp>
#include <functional> #include <optional>
namespace Nz namespace Nz
{ {
template<typename F>
class CallOnExit class CallOnExit
{ {
using Func = std::function<void()>;
public: public:
CallOnExit(Func func = nullptr); CallOnExit() = default;
CallOnExit(F&& functor);
CallOnExit(const CallOnExit&) = delete; CallOnExit(const CallOnExit&) = delete;
CallOnExit(CallOnExit&&) noexcept = delete; CallOnExit(CallOnExit&&) noexcept = delete;
~CallOnExit(); ~CallOnExit();
void CallAndReset(Func func = nullptr); void CallAndReset();
void Reset(Func func = nullptr); void Reset();
CallOnExit& operator=(const CallOnExit&) = delete; CallOnExit& operator=(const CallOnExit&) = delete;
CallOnExit& operator=(CallOnExit&&) noexcept = default; CallOnExit& operator=(CallOnExit&&) noexcept = default;
private: private:
Func m_func; std::optional<F> m_functor;
}; };
template<typename F>
CallOnExit(F) -> CallOnExit<F>;
} }
#include <Nazara/Core/CallOnExit.inl> #include <Nazara/Core/CallOnExit.inl>

View File

@ -15,24 +15,24 @@ namespace Nz
*/ */
/*! /*!
* \brief Constructs a CallOnExit object with a function * \brief Constructs a CallOnExit object with a functor
* *
* \param func Function to call on exit * \param func Function to call on exit
*/ */
template<typename F>
inline CallOnExit::CallOnExit(Func func) : CallOnExit<F>::CallOnExit(F&& functor) :
m_func(func) m_functor(std::move(functor))
{ {
} }
/*! /*!
* \brief Destructs the object and calls the function * \brief Destructs the object and calls the function
*/ */
template<typename F>
inline CallOnExit::~CallOnExit() CallOnExit<F>::~CallOnExit()
{ {
if (m_func) if (m_functor)
m_func(); (*m_functor)();
} }
/*! /*!
@ -40,13 +40,13 @@ namespace Nz
* *
* \param func Function to call on exit * \param func Function to call on exit
*/ */
template<typename F>
inline void CallOnExit::CallAndReset(Func func) void CallOnExit<F>::CallAndReset()
{ {
if (m_func) if (m_functor)
m_func(); (*m_functor)();
Reset(func); m_functor.reset();
} }
/*! /*!
@ -54,10 +54,10 @@ namespace Nz
* *
* \param func Function to call on exit * \param func Function to call on exit
*/ */
template<typename F>
inline void CallOnExit::Reset(Func func) void CallOnExit<F>::Reset()
{ {
m_func = func; m_functor.reset();
} }
} }

View File

@ -45,15 +45,11 @@ namespace Nz
Disconnect(); Disconnect();
Open(remoteAddress.GetProtocol()); Open(remoteAddress.GetProtocol());
CallOnExit restoreBlocking; CallOnExit restoreBlocking([this] { SocketImpl::SetBlocking(m_handle, true); });
if (m_isBlockingEnabled) if (m_isBlockingEnabled)
{
SocketImpl::SetBlocking(m_handle, false); SocketImpl::SetBlocking(m_handle, false);
restoreBlocking.Reset([this] () else
{ restoreBlocking.Reset();
SocketImpl::SetBlocking(m_handle, true);
});
}
SocketState state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError); SocketState state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError);
m_peerAddress = (state != SocketState::NotConnected) ? remoteAddress : IpAddress::Invalid; m_peerAddress = (state != SocketState::NotConnected) ? remoteAddress : IpAddress::Invalid;
@ -363,14 +359,13 @@ namespace Nz
std::size_t totalByteSent = 0; std::size_t totalByteSent = 0;
CallOnExit updateSent; CallOnExit updateSent([sent, &totalByteSent]
if (sent)
{ {
updateSent.Reset([sent, &totalByteSent] () *sent = totalByteSent;
{ });
*sent = totalByteSent;
}); if (!sent)
} updateSent.Reset();
while (totalByteSent < size || !IsBlockingEnabled()) while (totalByteSent < size || !IsBlockingEnabled())
{ {
@ -582,15 +577,11 @@ namespace Nz
{ {
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
CallOnExit restoreBlocking; CallOnExit restoreBlocking([this] { SocketImpl::SetBlocking(m_handle, true); });
if (!m_isBlockingEnabled) if (m_isBlockingEnabled)
{ SocketImpl::SetBlocking(m_handle, false);
SocketImpl::SetBlocking(m_handle, true); else
restoreBlocking.Reset([this] () restoreBlocking.Reset();
{
SocketImpl::SetBlocking(m_handle, false);
});
}
std::size_t received; std::size_t received;
if (!Receive(buffer, size, &received)) if (!Receive(buffer, size, &received))
@ -630,15 +621,11 @@ namespace Nz
NazaraAssert(buffer, "Invalid buffer"); NazaraAssert(buffer, "Invalid buffer");
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
CallOnExit restoreBlocking; CallOnExit restoreBlocking([this] { SocketImpl::SetBlocking(m_handle, true); });
if (!m_isBlockingEnabled) if (m_isBlockingEnabled)
{ SocketImpl::SetBlocking(m_handle, false);
SocketImpl::SetBlocking(m_handle, true); else
restoreBlocking.Reset([this] () restoreBlocking.Reset();
{
SocketImpl::SetBlocking(m_handle, false);
});
}
std::size_t sent; std::size_t sent;
if (!Send(buffer, size, &sent)) if (!Send(buffer, size, &sent))

View File

@ -33,17 +33,16 @@ namespace Nz
{ {
m_currentStream = &stream; m_currentStream = &stream;
// Force stream in text mode, reset it at the end // force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode; CallOnExit resetTextMode([&stream]
if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ {
stream.EnableTextMode(true); stream.EnableTextMode(false);
});
resetTextMode.Reset([&stream] () if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ stream.EnableTextMode(true);
stream.EnableTextMode(false); else
}); resetTextMode.Reset();
}
m_keepLastLine = false; m_keepLastLine = false;
m_lineCount = 0; m_lineCount = 0;
@ -489,17 +488,16 @@ namespace Nz
{ {
m_currentStream = &stream; m_currentStream = &stream;
// Force stream in text mode, reset it at the end // force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode; CallOnExit resetTextMode([&stream]
if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ {
stream.EnableTextMode(true); stream.EnableTextMode(false);
});
resetTextMode.Reset([&stream] () if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ stream.EnableTextMode(true);
stream.EnableTextMode(false); else
}); resetTextMode.Reset();
}
m_outputStream.str({}); m_outputStream.str({});

View File

@ -21,17 +21,16 @@ namespace Nz
m_keepLastLine = false; m_keepLastLine = false;
m_lineCount = 0; m_lineCount = 0;
// Force stream in text mode, reset it at the end // force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode; CallOnExit resetTextMode([&stream]
if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ {
stream.EnableTextMode(true); stream.EnableTextMode(false);
});
resetTextMode.Reset([&stream] () if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ stream.EnableTextMode(true);
stream.EnableTextMode(false); else
}); resetTextMode.Reset();
}
unsigned int failureCount = 0; unsigned int failureCount = 0;
while (Advance(false)) while (Advance(false))
@ -93,17 +92,16 @@ namespace Nz
m_keepLastLine = false; m_keepLastLine = false;
m_lineCount = 0; m_lineCount = 0;
// Force stream in text mode, reset it at the end // force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode; CallOnExit resetTextMode([&stream]
if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ {
stream.EnableTextMode(true); stream.EnableTextMode(false);
});
resetTextMode.Reset([&stream] () if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ stream.EnableTextMode(true);
stream.EnableTextMode(false); else
}); resetTextMode.Reset();
}
std::string matName, meshName; std::string matName, meshName;
matName = meshName = "default"; matName = meshName = "default";
@ -491,17 +489,16 @@ namespace Nz
{ {
m_currentStream = &stream; m_currentStream = &stream;
// Force stream in text mode, reset it at the end // force stream in text mode, reset it at the end
Nz::CallOnExit resetTextMode; CallOnExit resetTextMode([&stream]
if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ {
stream.EnableTextMode(true); stream.EnableTextMode(false);
});
resetTextMode.Reset([&stream] () if ((stream.GetStreamOptions() & StreamOption::Text) == 0)
{ stream.EnableTextMode(true);
stream.EnableTextMode(false); else
}); resetTextMode.Reset();
}
m_outputStream.str({}); m_outputStream.str({});