Skip to content

Instantly share code, notes, and snippets.

@JPGygax68
Last active November 3, 2020 10:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JPGygax68/616d2b8c01b334088824fb9c43c14187 to your computer and use it in GitHub Desktop.
Save JPGygax68/616d2b8c01b334088824fb9c43c14187 to your computer and use it in GitHub Desktop.
A template class for obtaining data in the background, based on std::async() and std::future<>
#pragma once
#include <future>
/**
* Class template based on std::async and std::future<> to help in fetching data asynchronously.
*/
template <typename T>
struct async_data {
bool ready() {
if (_done) return true;
_check_future();
return _done;
}
bool busy() {
return _future.valid();
}
template <typename Func, typename... Args>
void obtain(Func fn, Args... args) {
assert(!_done && "Do not call obtain() again once the data is ready - did you forget to check with ready() ?");
if (!busy()) {
_future = std::async(std::launch::async, fn, args...);
}
}
auto& value() {
assert(_done && "Do not try to access the value before ready() reports true!");
return _result;
}
private:
bool _done = false;
std::future<T> _future;
T _result;
void _check_future() {
if (_future.valid() && _future.wait_for(std::chrono::nanoseconds(1)) == std::future_status::ready) {
_done = true;
_result = _future.get();
}
}
};
@JPGygax68
Copy link
Author

JPGygax68 commented Oct 31, 2020

TODO: a way to repeat the fetch
TODO: reimplement as a subclass of std::promise<> ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment