mirror of
https://github.com/ZmnSCPxj/clboss.git
synced 2026-08-17 13:07:24 +02:00
89 lines
1.9 KiB
C++
89 lines
1.9 KiB
C++
#ifndef BOSS_MOD_WAITER_HPP
|
|
#define BOSS_MOD_WAITER_HPP
|
|
|
|
#include"Ev/Io.hpp"
|
|
#include"Util/make_unique.hpp"
|
|
#include<memory>
|
|
#include<stdexcept>
|
|
|
|
namespace Ev { template<typename a> class Io;}
|
|
namespace S { class Bus; }
|
|
|
|
namespace Boss { namespace Mod {
|
|
|
|
class Waiter {
|
|
private:
|
|
class Impl;
|
|
std::unique_ptr<Impl> pimpl;
|
|
|
|
public:
|
|
explicit
|
|
Waiter(S::Bus& bus);
|
|
~Waiter();
|
|
|
|
/** Boss::Mod::Waiter::wait
|
|
*
|
|
* @brief Waits for the specified number of
|
|
* seconds, then the action returns.
|
|
* Throws a Boss::Shutdown exception if a
|
|
* shutdown is broadcasted on the bus.
|
|
*/
|
|
Ev::Io<void> wait(double seconds);
|
|
|
|
/** Boss::Mod::Waiter::timed
|
|
*
|
|
* @brief performs the action, but if it does
|
|
* not complete before the given timeout,
|
|
* throws a `TimedOut` exception within the
|
|
* `Ev::Io` system.
|
|
*
|
|
* @desc `Ev::Io` does not really allow for
|
|
* cancelling of ongoing tasks, so the given
|
|
* action will still run to completion even if
|
|
* the timeout is reached, but the result will
|
|
* be destructed as soon as the action
|
|
* completes.
|
|
*/
|
|
template<typename a>
|
|
Ev::Io<a> timed( double timeout
|
|
, Ev::Io<a> action
|
|
);
|
|
struct TimedOut { };
|
|
|
|
private:
|
|
Ev::Io<void> timed_core( double timeout
|
|
, Ev::Io<void> action
|
|
);
|
|
};
|
|
|
|
template<typename a>
|
|
inline
|
|
Ev::Io<a> Waiter::timed( double timeout
|
|
, Ev::Io<a> action
|
|
) {
|
|
auto paction = std::make_shared<Ev::Io<a>>(
|
|
std::move(action)
|
|
);
|
|
auto presult = std::make_shared<std::unique_ptr<a>>();
|
|
return timed_core(timeout, Ev::lift().then([paction, presult]() {
|
|
return std::move(*paction).then([presult](a value) {
|
|
*presult = Util::make_unique<a>(
|
|
std::move(value)
|
|
);
|
|
return Ev::lift();
|
|
});
|
|
})).then([presult]() {
|
|
return Ev::lift(std::move(**presult));
|
|
});
|
|
}
|
|
template<>
|
|
inline
|
|
Ev::Io<void> Waiter::timed<void>( double timeout
|
|
, Ev::Io<void> action
|
|
) {
|
|
return timed_core(timeout, action);
|
|
}
|
|
|
|
}}
|
|
|
|
#endif /* !defined(BOSS_MOD_WAITER_HPP) */
|