Last active
November 3, 2020 10:19
-
-
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<>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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(); | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
TODO: a way to repeat the fetch
TODO: reimplement as a subclass of std::promise<> ?