impr: Added once execution and task progress increment helpers
This commit is contained in:
parent
e6854d6a6a
commit
a271658154
@ -9,6 +9,7 @@
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <condition_variable>
|
||||
#include <source_location>
|
||||
|
||||
namespace hex {
|
||||
|
||||
@ -33,6 +34,7 @@ namespace hex {
|
||||
*/
|
||||
void update(u64 value);
|
||||
void update() const;
|
||||
void increment();
|
||||
|
||||
/**
|
||||
* @brief Sets the maximum value of the task
|
||||
@ -149,6 +151,13 @@ namespace hex {
|
||||
*/
|
||||
static void doLater(const std::function<void()> &function);
|
||||
|
||||
/**
|
||||
* @brief Creates a new synchronous task that will execute the given function at the start of the next frame
|
||||
* @param function Function to be executed
|
||||
* @param location Source location of the function call. This is used to make sure repeated calls to the function at the same location are only executed once
|
||||
*/
|
||||
static void doLaterOnce(const std::function<void()> &function, std::source_location location = std::source_location::current());
|
||||
|
||||
/**
|
||||
* @brief Creates a callback that will be executed when all tasks are finished
|
||||
* @param function Function to be executed
|
||||
|
@ -16,14 +16,41 @@
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
struct SourceLocationWrapper {
|
||||
std::source_location location;
|
||||
|
||||
bool operator==(const SourceLocationWrapper &other) const {
|
||||
return location.file_name() == other.location.file_name() &&
|
||||
location.function_name() == other.location.function_name() &&
|
||||
location.column() == other.location.column() &&
|
||||
location.line() == other.location.line();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template<>
|
||||
struct std::hash<SourceLocationWrapper> {
|
||||
std::size_t operator()(const SourceLocationWrapper& s) const noexcept {
|
||||
auto h1 = std::hash<std::string>{}(s.location.file_name());
|
||||
auto h2 = std::hash<std::string>{}(s.location.function_name());
|
||||
auto h3 = std::hash<u32>{}(s.location.column());
|
||||
auto h4 = std::hash<u32>{}(s.location.line());
|
||||
return (h1 << 0) ^ (h2 << 1) ^ (h3 << 2) ^ (h4 << 3);
|
||||
}
|
||||
};
|
||||
|
||||
namespace hex {
|
||||
|
||||
namespace {
|
||||
|
||||
std::mutex s_deferredCallsMutex, s_tasksFinishedMutex;
|
||||
std::recursive_mutex s_deferredCallsMutex, s_tasksFinishedMutex;
|
||||
|
||||
std::list<std::shared_ptr<Task>> s_tasks, s_taskQueue;
|
||||
std::list<std::function<void()>> s_deferredCalls;
|
||||
std::unordered_map<SourceLocationWrapper, std::function<void()>> s_onceDeferredCalls;
|
||||
std::list<std::function<void()>> s_tasksFinishedCallbacks;
|
||||
|
||||
std::mutex s_queueMutex;
|
||||
@ -77,6 +104,13 @@ namespace hex {
|
||||
throw TaskInterruptor();
|
||||
}
|
||||
|
||||
void Task::increment() {
|
||||
m_currValue.fetch_add(1, std::memory_order_relaxed);
|
||||
|
||||
if (m_shouldInterrupt.load(std::memory_order_relaxed)) [[unlikely]]
|
||||
throw TaskInterruptor();
|
||||
}
|
||||
|
||||
|
||||
void Task::setMaxValue(u64 value) {
|
||||
m_maxValue = value;
|
||||
@ -289,6 +323,7 @@ namespace hex {
|
||||
s_taskQueue.clear();
|
||||
|
||||
s_deferredCalls.clear();
|
||||
s_onceDeferredCalls.clear();
|
||||
s_tasksFinishedCallbacks.clear();
|
||||
}
|
||||
|
||||
@ -368,13 +403,22 @@ namespace hex {
|
||||
s_deferredCalls.push_back(function);
|
||||
}
|
||||
|
||||
void TaskManager::doLaterOnce(const std::function<void()> &function, std::source_location location) {
|
||||
std::scoped_lock lock(s_deferredCallsMutex);
|
||||
|
||||
s_onceDeferredCalls[SourceLocationWrapper{ location }] = function;
|
||||
}
|
||||
|
||||
void TaskManager::runDeferredCalls() {
|
||||
std::scoped_lock lock(s_deferredCallsMutex);
|
||||
|
||||
for (const auto &call : s_deferredCalls)
|
||||
call();
|
||||
for (const auto &[location, call] : s_onceDeferredCalls)
|
||||
call();
|
||||
|
||||
s_deferredCalls.clear();
|
||||
s_onceDeferredCalls.clear();
|
||||
}
|
||||
|
||||
void TaskManager::runWhenTasksFinished(const std::function<void()> &function) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user