feat(Core/Database): port TrinityCore database API (#5611)

This commit is contained in:
Kargatum
2021-06-22 11:21:07 +07:00
committed by GitHub
parent 2a2e54d8c5
commit 9ac6fddcae
155 changed files with 5818 additions and 4321 deletions

View File

@@ -0,0 +1,100 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
*/
#ifndef _PCQ_H
#define _PCQ_H
#include <condition_variable>
#include <mutex>
#include <queue>
#include <atomic>
#include <type_traits>
template <typename T>
class ProducerConsumerQueue
{
private:
std::mutex _queueLock;
std::queue<T> _queue;
std::condition_variable _condition;
std::atomic<bool> _shutdown;
public:
ProducerConsumerQueue<T>() : _shutdown(false) { }
void Push(const T& value)
{
std::lock_guard<std::mutex> lock(_queueLock);
_queue.push(std::move(value));
_condition.notify_one();
}
bool Empty()
{
std::lock_guard<std::mutex> lock(_queueLock);
return _queue.empty();
}
bool Pop(T& value)
{
std::lock_guard<std::mutex> lock(_queueLock);
if (_queue.empty() || _shutdown)
return false;
value = _queue.front();
_queue.pop();
return true;
}
void WaitAndPop(T& value)
{
std::unique_lock<std::mutex> lock(_queueLock);
// we could be using .wait(lock, predicate) overload here but it is broken
// https://connect.microsoft.com/VisualStudio/feedback/details/1098841
while (_queue.empty() && !_shutdown)
_condition.wait(lock);
if (_queue.empty() || _shutdown)
return;
value = _queue.front();
_queue.pop();
}
void Cancel()
{
std::unique_lock<std::mutex> lock(_queueLock);
while (!_queue.empty())
{
T& value = _queue.front();
DeleteQueuedObject(value);
_queue.pop();
}
_shutdown = true;
_condition.notify_all();
}
private:
template<typename E = T>
typename std::enable_if<std::is_pointer<E>::value>::type DeleteQueuedObject(E& obj) { delete obj; }
template<typename E = T>
typename std::enable_if<!std::is_pointer<E>::value>::type DeleteQueuedObject(E const& /*packet*/) { }
};
#endif

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2021+ WarheadCore <https://github.com/WarheadCore>
*/
#ifndef AsyncCallbackProcessor_h__
#define AsyncCallbackProcessor_h__
#include "Define.h"
#include <algorithm>
#include <vector>
//template <class T>
//concept AsyncCallback = requires(T t) { { t.InvokeIfReady() } -> std::convertible_to<bool> };
template<typename T> // requires AsyncCallback<T>
class AsyncCallbackProcessor
{
public:
AsyncCallbackProcessor() = default;
~AsyncCallbackProcessor() = default;
T& AddCallback(T&& query)
{
_callbacks.emplace_back(std::move(query));
return _callbacks.back();
}
void ProcessReadyCallbacks()
{
if (_callbacks.empty())
return;
std::vector<T> updateCallbacks{ std::move(_callbacks) };
updateCallbacks.erase(std::remove_if(updateCallbacks.begin(), updateCallbacks.end(), [](T& callback)
{
return callback.InvokeIfReady();
}), updateCallbacks.end());
_callbacks.insert(_callbacks.end(), std::make_move_iterator(updateCallbacks.begin()), std::make_move_iterator(updateCallbacks.end()));
}
private:
AsyncCallbackProcessor(AsyncCallbackProcessor const&) = delete;
AsyncCallbackProcessor& operator=(AsyncCallbackProcessor const&) = delete;
std::vector<T> _callbacks;
};
#endif // AsyncCallbackProcessor_h__