mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-24 02:46:33 +01:00
Core/DBLayer: Convert async queries to new query callbacks and remove old callback handling
(cherry picked from commit 8e2634b2b4)
Conflicts:
src/server/bnetserver/Server/Session.cpp
src/server/bnetserver/Server/Session.h
src/server/database/Database/QueryCallback.cpp
src/server/game/Handlers/CharacterHandler.cpp
src/server/game/Handlers/SocialHandler.cpp
src/server/game/Server/WorldSession.cpp
src/server/game/Server/WorldSession.h
src/server/game/Server/WorldSocket.cpp
src/server/game/Server/WorldSocket.h
src/server/game/World/World.cpp
src/server/game/World/World.h
This commit is contained in:
@@ -169,8 +169,7 @@ void AuthSession::Start()
|
||||
stmt->setString(0, ip_address);
|
||||
stmt->setUInt32(1, inet_addr(ip_address.c_str()));
|
||||
|
||||
_queryCallback = std::bind(&AuthSession::CheckIpCallback, this, std::placeholders::_1);
|
||||
_queryFuture = LoginDatabase.AsyncQuery(stmt);
|
||||
_queryCallback = std::move(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::CheckIpCallback, this, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
bool AuthSession::Update()
|
||||
@@ -178,12 +177,8 @@ bool AuthSession::Update()
|
||||
if (!AuthSocket::Update())
|
||||
return false;
|
||||
|
||||
if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
auto callback = _queryCallback;
|
||||
_queryCallback = nullptr;
|
||||
callback(_queryFuture.get());
|
||||
}
|
||||
if (_queryCallback && _queryCallback->InvokeIfReady() == QueryCallback::Completed)
|
||||
_queryCallback = boost::none;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -323,8 +318,7 @@ bool AuthSession::HandleLogonChallenge()
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGONCHALLENGE);
|
||||
stmt->setString(0, login);
|
||||
|
||||
_queryCallback = std::bind(&AuthSession::LogonChallengeCallback, this, std::placeholders::_1);
|
||||
_queryFuture = LoginDatabase.AsyncQuery(stmt);
|
||||
_queryCallback = std::move(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::LogonChallengeCallback, this, std::placeholders::_1)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -737,8 +731,7 @@ bool AuthSession::HandleReconnectChallenge()
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RECONNECTCHALLENGE);
|
||||
stmt->setString(0, login);
|
||||
|
||||
_queryCallback = std::bind(&AuthSession::ReconnectChallengeCallback, this, std::placeholders::_1);
|
||||
_queryFuture = LoginDatabase.AsyncQuery(stmt);
|
||||
_queryCallback = std::move(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::ReconnectChallengeCallback, this, std::placeholders::_1)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -819,8 +812,7 @@ bool AuthSession::HandleRealmList()
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALM_CHARACTER_COUNTS);
|
||||
stmt->setUInt32(0, _accountInfo.Id);
|
||||
|
||||
_queryCallback = std::bind(&AuthSession::RealmListCallback, this, std::placeholders::_1);
|
||||
_queryFuture = LoginDatabase.AsyncQuery(stmt);
|
||||
_queryCallback = std::move(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&AuthSession::RealmListCallback, this, std::placeholders::_1)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,8 +102,7 @@ private:
|
||||
uint16 _build;
|
||||
uint8 _expversion;
|
||||
|
||||
PreparedQueryResultFuture _queryFuture;
|
||||
std::function<void(PreparedQueryResult)> _queryCallback;
|
||||
Optional<QueryCallback> _queryCallback;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "DatabaseWorkerPool.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "QueryCallback.h"
|
||||
|
||||
#define MIN_MYSQL_SERVER_VERSION 50100u
|
||||
#define MIN_MYSQL_CLIENT_VERSION 50100u
|
||||
@@ -146,23 +147,23 @@ PreparedQueryResult DatabaseWorkerPool<T>::Query(PreparedStatement* stmt)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
QueryResultFuture DatabaseWorkerPool<T>::AsyncQuery(const char* sql)
|
||||
QueryCallback DatabaseWorkerPool<T>::AsyncQuery(const char* sql)
|
||||
{
|
||||
BasicStatementTask* task = new BasicStatementTask(sql, true);
|
||||
// Store future result before enqueueing - task might get already processed and deleted before returning from this method
|
||||
QueryResultFuture result = task->GetFuture();
|
||||
Enqueue(task);
|
||||
return result;
|
||||
return QueryCallback(std::move(result));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PreparedQueryResultFuture DatabaseWorkerPool<T>::AsyncQuery(PreparedStatement* stmt)
|
||||
QueryCallback DatabaseWorkerPool<T>::AsyncQuery(PreparedStatement* stmt)
|
||||
{
|
||||
PreparedStatementTask* task = new PreparedStatementTask(stmt, true);
|
||||
// Store future result before enqueueing - task might get already processed and deleted before returning from this method
|
||||
PreparedQueryResultFuture result = task->GetFuture();
|
||||
Enqueue(task);
|
||||
return result;
|
||||
return QueryCallback(std::move(result));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#define _DATABASEWORKERPOOL_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "QueryCallback.h"
|
||||
#include "MySQLConnection.h"
|
||||
#include "Transaction.h"
|
||||
#include "DatabaseWorker.h"
|
||||
@@ -34,6 +33,8 @@
|
||||
#include <memory>
|
||||
#include <array>
|
||||
|
||||
class QueryCallback;
|
||||
|
||||
class PingOperation : public SQLOperation
|
||||
{
|
||||
//! Operation for idle delaythreads
|
||||
@@ -192,12 +193,12 @@ class DatabaseWorkerPool
|
||||
|
||||
//! Enqueues a query in string format that will set the value of the QueryResultFuture return object as soon as the query is executed.
|
||||
//! The return value is then processed in ProcessQueryCallback methods.
|
||||
QueryResultFuture AsyncQuery(const char* sql);
|
||||
QueryCallback AsyncQuery(const char* sql);
|
||||
|
||||
//! Enqueues a query in string format -with variable args- that will set the value of the QueryResultFuture return object as soon as the query is executed.
|
||||
//! The return value is then processed in ProcessQueryCallback methods.
|
||||
template<typename Format, typename... Args>
|
||||
QueryResultFuture AsyncPQuery(Format&& sql, Args&&... args)
|
||||
QueryCallback AsyncPQuery(Format&& sql, Args&&... args)
|
||||
{
|
||||
return AsyncQuery(Trinity::StringFormat(std::forward<Format>(sql), std::forward<Args>(args)...).c_str());
|
||||
}
|
||||
@@ -205,7 +206,7 @@ class DatabaseWorkerPool
|
||||
//! Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed.
|
||||
//! The return value is then processed in ProcessQueryCallback methods.
|
||||
//! Statement must be prepared with CONNECTION_ASYNC flag.
|
||||
PreparedQueryResultFuture AsyncQuery(PreparedStatement* stmt);
|
||||
QueryCallback AsyncQuery(PreparedStatement* stmt);
|
||||
|
||||
//! Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture
|
||||
//! return object as soon as the query is executed.
|
||||
|
||||
@@ -51,7 +51,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
"cb.guid, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? "
|
||||
"LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid "
|
||||
"LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL ORDER BY c.guid", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_FREE_NAME, "SELECT guid, name FROM characters WHERE guid = ? AND account = ? AND (at_login & ?) = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_FREE_NAME, "SELECT guid, name, at_login FROM characters WHERE guid = ? AND account = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_BOTH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_LEVEL, "SELECT level FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_ZONE, "SELECT zone FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
@@ -162,7 +162,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_NAME_CLASS, "SELECT name, class FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_MATCH_MAKER_RATING, "SELECT matchMakerRating FROM character_arena_stats WHERE guid = ? AND slot = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_COUNT, "SELECT account, COUNT(guid) FROM characters WHERE account = ? GROUP BY account", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_NAME, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_NAME_BY_GUID, "UPDATE characters SET name = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -399,7 +398,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_UPD_INSTANCE_RESETTIME, "UPDATE instance SET resettime = ? WHERE id = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_GLOBAL_INSTANCE_RESETTIME, "UPDATE instance_reset SET resettime = ? WHERE mapid = ? AND difficulty = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_ONLINE, "UPDATE characters SET online = 1 WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_NAME_AT_LOGIN, "UPDATE characters set name = ?, at_login = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_WORLDSTATE, "UPDATE worldstates SET value = ? WHERE entry = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_WORLDSTATE, "INSERT INTO worldstates (entry, value) VALUES (?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID, "DELETE FROM character_instance WHERE guid = ? AND instance = ?", CONNECTION_ASYNC);
|
||||
@@ -429,7 +428,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_SEL_POOL_QUEST_SAVE, "SELECT quest_id FROM pool_quest_save WHERE pool_id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_AT_LOGIN, "SELECT at_login FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, "SELECT class, level, at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_AT_LOGIN_TITLES, "SELECT at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_CUSTOMIZE_INFO, "SELECT name, race, class, gender, at_login FROM characters WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS, "SELECT at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_INSTANCE, "SELECT data, completedEncounters FROM instance WHERE map = ? AND id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_PERM_BIND_BY_INSTANCE, "SELECT guid FROM character_instance WHERE instance = ? and permanent = 1", CONNECTION_SYNCH);
|
||||
PrepareStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH);
|
||||
@@ -477,7 +477,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_GUID, "DELETE FROM petition_sign WHERE petitionguid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_DECLINED_NAME, "INSERT INTO character_declinedname (guid, genitive, dative, accusative, instrumental, prepositional) VALUES (?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_FACTION_OR_RACE, "UPDATE characters SET name = ?, race = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_RACE, "UPDATE characters SET race = ? WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_DEL_CHAR_SKILL_LANGUAGES, "DELETE FROM character_skills WHERE skill IN (98, 113, 759, 111, 313, 109, 115, 315, 673, 137) AND guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_CHAR_SKILL_LANGUAGE, "INSERT INTO `character_skills` (guid, skill, value, max) VALUES (?, ?, 300, 300)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_UPD_CHAR_TAXI_PATH, "UPDATE characters SET taxi_path = '' WHERE guid = ?", CONNECTION_ASYNC);
|
||||
|
||||
@@ -148,7 +148,6 @@ enum CharacterDatabaseStatements
|
||||
CHAR_SEL_CHARACTER_NAME_CLASS,
|
||||
CHAR_SEL_MATCH_MAKER_RATING,
|
||||
CHAR_SEL_CHARACTER_COUNT,
|
||||
CHAR_UPD_NAME,
|
||||
CHAR_UPD_NAME_BY_GUID,
|
||||
CHAR_DEL_DECLINED_NAME,
|
||||
|
||||
@@ -360,7 +359,8 @@ enum CharacterDatabaseStatements
|
||||
CHAR_SEL_POOL_QUEST_SAVE,
|
||||
CHAR_SEL_CHARACTER_AT_LOGIN,
|
||||
CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN,
|
||||
CHAR_SEL_CHAR_AT_LOGIN_TITLES,
|
||||
CHAR_SEL_CHAR_CUSTOMIZE_INFO,
|
||||
CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS,
|
||||
CHAR_SEL_INSTANCE,
|
||||
CHAR_SEL_PERM_BIND_BY_INSTANCE,
|
||||
CHAR_SEL_CHAR_COD_ITEM_MAIL,
|
||||
@@ -403,7 +403,7 @@ enum CharacterDatabaseStatements
|
||||
CHAR_DEL_PETITION_SIGNATURE_BY_GUID,
|
||||
CHAR_DEL_CHAR_DECLINED_NAME,
|
||||
CHAR_INS_CHAR_DECLINED_NAME,
|
||||
CHAR_UPD_FACTION_OR_RACE,
|
||||
CHAR_UPD_CHAR_RACE,
|
||||
CHAR_DEL_CHAR_SKILL_LANGUAGES,
|
||||
CHAR_INS_CHAR_SKILL_LANGUAGE,
|
||||
CHAR_UPD_CHAR_TAXI_PATH,
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
|
||||
#include "QueryCallback.h"
|
||||
|
||||
template<typename T>
|
||||
inline void Construct(T& t)
|
||||
{
|
||||
new (&t) T();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void Destroy(T& t)
|
||||
{
|
||||
@@ -24,109 +30,174 @@ inline void Destroy(T& t)
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void DestroyActiveMember(T& obj)
|
||||
void ConstructActiveMember(T* obj)
|
||||
{
|
||||
if (!obj._isPrepared)
|
||||
Destroy(obj._string);
|
||||
if (!obj->_isPrepared)
|
||||
Construct(obj->_string);
|
||||
else
|
||||
Destroy(obj._prepared);
|
||||
Construct(obj->_prepared);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void MoveFrom(T& to, T&& from)
|
||||
void DestroyActiveMember(T* obj)
|
||||
{
|
||||
DestroyActiveMember(to);
|
||||
to._isPrepared = from._isPrepared;
|
||||
if (!to._isPrepared)
|
||||
to._string = std::move(from._string);
|
||||
if (!obj->_isPrepared)
|
||||
Destroy(obj->_string);
|
||||
else
|
||||
to._prepared = std::move(from._prepared);
|
||||
Destroy(obj->_prepared);
|
||||
}
|
||||
|
||||
struct QueryCallbackNew::QueryCallbackData
|
||||
template<typename T>
|
||||
void MoveFrom(T* to, T&& from)
|
||||
{
|
||||
ASSERT(to->_isPrepared == from._isPrepared);
|
||||
|
||||
if (!to->_isPrepared)
|
||||
to->_string = std::move(from._string);
|
||||
else
|
||||
to->_prepared = std::move(from._prepared);
|
||||
}
|
||||
|
||||
struct QueryCallback::QueryCallbackData
|
||||
{
|
||||
public:
|
||||
friend class QueryCallbackNew;
|
||||
friend class QueryCallback;
|
||||
|
||||
QueryCallbackData(std::function<void(QueryResult)>&& callback) : _string(std::move(callback)), _isPrepared(false) { }
|
||||
QueryCallbackData(std::function<void(PreparedQueryResult)>&& callback) : _prepared(std::move(callback)), _isPrepared(true) { }
|
||||
QueryCallbackData(QueryCallbackData&& right) { MoveFrom(*this, std::move(right)); }
|
||||
QueryCallbackData& operator=(QueryCallbackData&& right) { MoveFrom(*this, std::move(right)); }
|
||||
~QueryCallbackData() { DestroyActiveMember(*this); }
|
||||
QueryCallbackData(std::function<void(QueryCallback&, QueryResult)>&& callback) : _string(std::move(callback)), _isPrepared(false) { TC_LOG_ERROR(LOGGER_ROOT, "QueryCallbackData [%p]: Constructing from string query", (void*)this); }
|
||||
QueryCallbackData(std::function<void(QueryCallback&, PreparedQueryResult)>&& callback) : _prepared(std::move(callback)), _isPrepared(true) { TC_LOG_ERROR(LOGGER_ROOT, "QueryCallbackData [%p]: Constructing from prepared query", (void*)this); }
|
||||
QueryCallbackData(QueryCallbackData&& right)
|
||||
{
|
||||
_isPrepared = right._isPrepared;
|
||||
ConstructActiveMember(this);
|
||||
MoveFrom(this, std::move(right));
|
||||
}
|
||||
QueryCallbackData& operator=(QueryCallbackData&& right)
|
||||
{
|
||||
if (this != &right)
|
||||
{
|
||||
if (_isPrepared != right._isPrepared)
|
||||
{
|
||||
DestroyActiveMember(this);
|
||||
_isPrepared = right._isPrepared;
|
||||
ConstructActiveMember(this);
|
||||
}
|
||||
MoveFrom(this, std::move(right));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
~QueryCallbackData() { DestroyActiveMember(this); }
|
||||
|
||||
private:
|
||||
QueryCallbackData(QueryCallbackData const&) = delete;
|
||||
QueryCallbackData& operator=(QueryCallbackData const&) = delete;
|
||||
|
||||
template<typename T> friend void MoveFrom(T& to, T&& from);
|
||||
template<typename T> friend void DestroyActiveMember(T& obj);
|
||||
template<typename T> friend void ConstructActiveMember(T* obj);
|
||||
template<typename T> friend void DestroyActiveMember(T* obj);
|
||||
template<typename T> friend void MoveFrom(T* to, T&& from);
|
||||
|
||||
union
|
||||
{
|
||||
std::function<void(QueryResult)> _string;
|
||||
std::function<void(PreparedQueryResult)> _prepared;
|
||||
std::function<void(QueryCallback&, QueryResult)> _string;
|
||||
std::function<void(QueryCallback&, PreparedQueryResult)> _prepared;
|
||||
};
|
||||
bool _isPrepared;
|
||||
};
|
||||
|
||||
QueryCallbackNew::QueryCallbackNew(std::future<QueryResult>&& result) : _string(std::move(result)), _isPrepared(false)
|
||||
QueryCallback::QueryCallback(std::future<QueryResult>&& result) : _string(std::move(result)), _isPrepared(false)
|
||||
{
|
||||
}
|
||||
|
||||
QueryCallbackNew::QueryCallbackNew(std::future<PreparedQueryResult>&& result) : _prepared(std::move(result)), _isPrepared(true)
|
||||
QueryCallback::QueryCallback(std::future<PreparedQueryResult>&& result) : _prepared(std::move(result)), _isPrepared(true)
|
||||
{
|
||||
}
|
||||
|
||||
QueryCallbackNew::QueryCallbackNew(QueryCallbackNew&& right)
|
||||
QueryCallback::QueryCallback(QueryCallback&& right)
|
||||
{
|
||||
MoveFrom(*this, std::move(right));
|
||||
_isPrepared = right._isPrepared;
|
||||
ConstructActiveMember(this);
|
||||
MoveFrom(this, std::move(right));
|
||||
_callbacks = std::move(right._callbacks);
|
||||
}
|
||||
|
||||
QueryCallbackNew& QueryCallbackNew::operator=(QueryCallbackNew&& right)
|
||||
QueryCallback& QueryCallback::operator=(QueryCallback&& right)
|
||||
{
|
||||
MoveFrom(*this, std::move(right));
|
||||
_callbacks = std::move(right._callbacks);
|
||||
if (this != &right)
|
||||
{
|
||||
if (_isPrepared != right._isPrepared)
|
||||
{
|
||||
DestroyActiveMember(this);
|
||||
_isPrepared = right._isPrepared;
|
||||
ConstructActiveMember(this);
|
||||
}
|
||||
MoveFrom(this, std::move(right));
|
||||
_callbacks = std::move(right._callbacks);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
QueryCallbackNew::~QueryCallbackNew()
|
||||
QueryCallback::~QueryCallback()
|
||||
{
|
||||
DestroyActiveMember(*this);
|
||||
DestroyActiveMember(this);
|
||||
}
|
||||
|
||||
QueryCallbackNew&& QueryCallbackNew::WithCallback(std::function<void(QueryResult)>&& callback)
|
||||
QueryCallback&& QueryCallback::WithCallback(std::function<void(QueryResult)>&& callback)
|
||||
{
|
||||
return WithChainingCallback([callback](QueryCallback& /*this*/, QueryResult result) { callback(std::move(result)); });
|
||||
}
|
||||
|
||||
QueryCallback&& QueryCallback::WithPreparedCallback(std::function<void(PreparedQueryResult)>&& callback)
|
||||
{
|
||||
return WithChainingPreparedCallback([callback](QueryCallback& /*this*/, PreparedQueryResult result) { callback(std::move(result)); });
|
||||
}
|
||||
|
||||
QueryCallback&& QueryCallback::WithChainingCallback(std::function<void(QueryCallback&, QueryResult)>&& callback)
|
||||
{
|
||||
ASSERT(!_callbacks.empty() || !_isPrepared, "Attempted to set callback function for string query on a prepared async query");
|
||||
_callbacks.emplace(std::move(callback));
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
QueryCallbackNew&& QueryCallbackNew::WithPreparedCallback(std::function<void(PreparedQueryResult)>&& callback)
|
||||
QueryCallback&& QueryCallback::WithChainingPreparedCallback(std::function<void(QueryCallback&, PreparedQueryResult)>&& callback)
|
||||
{
|
||||
ASSERT(!_callbacks.empty() || _isPrepared, "Attempted to set callback function for prepared query on a string async query");
|
||||
_callbacks.emplace(std::move(callback));
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
QueryCallbackNew::Status QueryCallbackNew::InvokeIfReady()
|
||||
void QueryCallback::SetNextQuery(QueryCallback&& next)
|
||||
{
|
||||
MoveFrom(this, std::move(next));
|
||||
}
|
||||
|
||||
QueryCallback::Status QueryCallback::InvokeIfReady()
|
||||
{
|
||||
QueryCallbackData& callback = _callbacks.front();
|
||||
auto checkStateAndReturnCompletion = [this]()
|
||||
{
|
||||
_callbacks.pop();
|
||||
bool hasNext = !_isPrepared ? _string.valid() : _prepared.valid();
|
||||
if (_callbacks.empty())
|
||||
{
|
||||
ASSERT(!hasNext);
|
||||
return Completed;
|
||||
}
|
||||
|
||||
// abort chain
|
||||
if (!hasNext)
|
||||
return Completed;
|
||||
|
||||
ASSERT(_isPrepared == _callbacks.front()._isPrepared);
|
||||
return NextStep;
|
||||
};
|
||||
|
||||
if (!_isPrepared)
|
||||
{
|
||||
if (_string.valid() && _string.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
std::function<void(QueryResult)> cb(std::move(callback._string));
|
||||
cb(_string.get());
|
||||
_callbacks.pop();
|
||||
if (_callbacks.empty())
|
||||
{
|
||||
ASSERT(!_isPrepared ? !_string.valid() : !_prepared.valid());
|
||||
return Completed;
|
||||
}
|
||||
|
||||
ASSERT(_isPrepared == _callbacks.front()._isPrepared);
|
||||
return NextStep;
|
||||
std::future<QueryResult> f(std::move(_string));
|
||||
std::function<void(QueryCallback&, QueryResult)> cb(std::move(callback._string));
|
||||
cb(*this, f.get());
|
||||
return checkStateAndReturnCompletion();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -134,17 +205,9 @@ QueryCallbackNew::Status QueryCallbackNew::InvokeIfReady()
|
||||
if (_prepared.valid() && _prepared.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
std::future<PreparedQueryResult> f(std::move(_prepared));
|
||||
std::function<void(PreparedQueryResult)> cb(std::move(callback._prepared));
|
||||
cb(_prepared.get());
|
||||
_callbacks.pop();
|
||||
if (_callbacks.empty())
|
||||
{
|
||||
ASSERT(!_isPrepared ? !_string.valid() : !_prepared.valid());
|
||||
return Completed;
|
||||
}
|
||||
|
||||
ASSERT(_isPrepared == _callbacks.front()._isPrepared);
|
||||
return NextStep;
|
||||
std::function<void(QueryCallback&, PreparedQueryResult)> cb(std::move(callback._prepared));
|
||||
cb(*this, f.get());
|
||||
return checkStateAndReturnCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,27 +18,26 @@
|
||||
#ifndef _QUERY_CALLBACK_H
|
||||
#define _QUERY_CALLBACK_H
|
||||
|
||||
#include <future>
|
||||
#include "QueryResult.h"
|
||||
#include <future>
|
||||
|
||||
typedef std::future<QueryResult> QueryResultFuture;
|
||||
typedef std::promise<QueryResult> QueryResultPromise;
|
||||
typedef std::future<PreparedQueryResult> PreparedQueryResultFuture;
|
||||
typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise;
|
||||
|
||||
#define CALLBACK_STAGE_INVALID uint8(-1)
|
||||
|
||||
class TC_DATABASE_API QueryCallbackNew
|
||||
class TC_DATABASE_API QueryCallback
|
||||
{
|
||||
public:
|
||||
explicit QueryCallbackNew(std::future<QueryResult>&& result);
|
||||
explicit QueryCallbackNew(std::future<PreparedQueryResult>&& result);
|
||||
QueryCallbackNew(QueryCallbackNew&& right);
|
||||
QueryCallbackNew& operator=(QueryCallbackNew&& right);
|
||||
~QueryCallbackNew();
|
||||
explicit QueryCallback(std::future<QueryResult>&& result);
|
||||
explicit QueryCallback(std::future<PreparedQueryResult>&& result);
|
||||
QueryCallback(QueryCallback&& right);
|
||||
QueryCallback& operator=(QueryCallback&& right);
|
||||
~QueryCallback();
|
||||
|
||||
QueryCallbackNew&& WithCallback(std::function<void(QueryResult)>&& callback);
|
||||
QueryCallbackNew&& WithPreparedCallback(std::function<void(PreparedQueryResult)>&& callback);
|
||||
QueryCallback&& WithCallback(std::function<void(QueryResult)>&& callback);
|
||||
QueryCallback&& WithPreparedCallback(std::function<void(PreparedQueryResult)>&& callback);
|
||||
|
||||
QueryCallback&& WithChainingCallback(std::function<void(QueryCallback&, QueryResult)>&& callback);
|
||||
QueryCallback&& WithChainingPreparedCallback(std::function<void(QueryCallback&, PreparedQueryResult)>&& callback);
|
||||
|
||||
// Moves std::future from next to this object
|
||||
void SetNextQuery(QueryCallback&& next);
|
||||
|
||||
enum Status
|
||||
{
|
||||
@@ -50,11 +49,12 @@ public:
|
||||
Status InvokeIfReady();
|
||||
|
||||
private:
|
||||
QueryCallbackNew(QueryCallbackNew const& right) = delete;
|
||||
QueryCallbackNew& operator=(QueryCallbackNew const& right) = delete;
|
||||
QueryCallback(QueryCallback const& right) = delete;
|
||||
QueryCallback& operator=(QueryCallback const& right) = delete;
|
||||
|
||||
template<typename T> friend void MoveFrom(T& to, T&& from);
|
||||
template<typename T> friend void DestroyActiveMember(T& obj);
|
||||
template<typename T> friend void ConstructActiveMember(T* obj);
|
||||
template<typename T> friend void DestroyActiveMember(T* obj);
|
||||
template<typename T> friend void MoveFrom(T* to, T&& from);
|
||||
|
||||
union
|
||||
{
|
||||
@@ -67,182 +67,4 @@ private:
|
||||
std::queue<QueryCallbackData, std::list<QueryCallbackData>> _callbacks;
|
||||
};
|
||||
|
||||
template <typename Result, typename ParamType, bool chain = false>
|
||||
class QueryCallback
|
||||
{
|
||||
public:
|
||||
QueryCallback() : _param(), _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { }
|
||||
|
||||
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
|
||||
void SetFutureResult(std::future<Result> value)
|
||||
{
|
||||
_result = std::move(value);
|
||||
}
|
||||
|
||||
std::future<Result>& GetFutureResult()
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
|
||||
bool IsReady()
|
||||
{
|
||||
return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
|
||||
}
|
||||
|
||||
void GetResult(Result& res)
|
||||
{
|
||||
res = _result.get();
|
||||
}
|
||||
|
||||
void FreeResult()
|
||||
{
|
||||
// Nothing to do here, the constructor of std::future will take care of the cleanup
|
||||
}
|
||||
|
||||
void SetParam(ParamType value)
|
||||
{
|
||||
_param = value;
|
||||
}
|
||||
|
||||
ParamType GetParam()
|
||||
{
|
||||
return _param;
|
||||
}
|
||||
|
||||
//! Resets the stage of the callback chain
|
||||
void ResetStage()
|
||||
{
|
||||
if (!chain)
|
||||
return;
|
||||
|
||||
_stage = 0;
|
||||
}
|
||||
|
||||
//! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
|
||||
void NextStage()
|
||||
{
|
||||
if (!chain)
|
||||
return;
|
||||
|
||||
++_stage;
|
||||
}
|
||||
|
||||
//! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
|
||||
uint8 GetStage()
|
||||
{
|
||||
return _stage;
|
||||
}
|
||||
|
||||
//! Resets all underlying variables (param, result and stage)
|
||||
void Reset()
|
||||
{
|
||||
SetParam(ParamType());
|
||||
FreeResult();
|
||||
ResetStage();
|
||||
}
|
||||
|
||||
private:
|
||||
std::future<Result> _result;
|
||||
ParamType _param;
|
||||
uint8 _stage;
|
||||
|
||||
QueryCallback(QueryCallback const& right) = delete;
|
||||
QueryCallback& operator=(QueryCallback const& right) = delete;
|
||||
};
|
||||
|
||||
template <typename Result, typename ParamType1, typename ParamType2, bool chain = false>
|
||||
class QueryCallback_2
|
||||
{
|
||||
public:
|
||||
QueryCallback_2() : _stage(chain ? 0 : CALLBACK_STAGE_INVALID) { }
|
||||
|
||||
//! The parameter of this function should be a resultset returned from either .AsyncQuery or .AsyncPQuery
|
||||
void SetFutureResult(std::future<Result> value)
|
||||
{
|
||||
_result = std::move(value);
|
||||
}
|
||||
|
||||
std::future<Result>& GetFutureResult()
|
||||
{
|
||||
return _result;
|
||||
}
|
||||
|
||||
bool IsReady()
|
||||
{
|
||||
return _result.valid() && _result.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
|
||||
}
|
||||
|
||||
void GetResult(Result& res)
|
||||
{
|
||||
res = _result.get();
|
||||
}
|
||||
|
||||
void FreeResult()
|
||||
{
|
||||
// Nothing to do here, the constructor of std::future will take care of the cleanup
|
||||
}
|
||||
|
||||
void SetFirstParam(ParamType1 value)
|
||||
{
|
||||
_param_1 = value;
|
||||
}
|
||||
|
||||
void SetSecondParam(ParamType2 value)
|
||||
{
|
||||
_param_2 = value;
|
||||
}
|
||||
|
||||
ParamType1 GetFirstParam()
|
||||
{
|
||||
return _param_1;
|
||||
}
|
||||
|
||||
ParamType2 GetSecondParam()
|
||||
{
|
||||
return _param_2;
|
||||
}
|
||||
|
||||
//! Resets the stage of the callback chain
|
||||
void ResetStage()
|
||||
{
|
||||
if (!chain)
|
||||
return;
|
||||
|
||||
_stage = 0;
|
||||
}
|
||||
|
||||
//! Advances the callback chain to the next stage, so upper level code can act on its results accordingly
|
||||
void NextStage()
|
||||
{
|
||||
if (!chain)
|
||||
return;
|
||||
|
||||
++_stage;
|
||||
}
|
||||
|
||||
//! Returns the callback stage (or CALLBACK_STAGE_INVALID if invalid)
|
||||
uint8 GetStage()
|
||||
{
|
||||
return _stage;
|
||||
}
|
||||
|
||||
//! Resets all underlying variables (param, result and stage)
|
||||
void Reset()
|
||||
{
|
||||
SetFirstParam(NULL);
|
||||
SetSecondParam(NULL);
|
||||
FreeResult();
|
||||
ResetStage();
|
||||
}
|
||||
|
||||
private:
|
||||
std::future<Result> _result;
|
||||
ParamType1 _param_1;
|
||||
ParamType2 _param_2;
|
||||
uint8 _stage;
|
||||
|
||||
QueryCallback_2(QueryCallback_2 const& right) = delete;
|
||||
QueryCallback_2& operator=(QueryCallback_2 const& right) = delete;
|
||||
};
|
||||
|
||||
#endif // _QUERY_CALLBACK_H
|
||||
|
||||
@@ -27,15 +27,22 @@ QueryCallbackProcessor::~QueryCallbackProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
void QueryCallbackProcessor::AddQuery(QueryCallbackNew&& query)
|
||||
void QueryCallbackProcessor::AddQuery(QueryCallback&& query)
|
||||
{
|
||||
_callbacks.emplace_back(std::move(query));
|
||||
}
|
||||
|
||||
void QueryCallbackProcessor::ProcessReadyQueries()
|
||||
{
|
||||
_callbacks.erase(std::remove_if(_callbacks.begin(), _callbacks.end(), [](QueryCallbackNew& callback)
|
||||
if (_callbacks.empty())
|
||||
return;
|
||||
|
||||
std::vector<QueryCallback> updateCallbacks{ std::move(_callbacks) };
|
||||
|
||||
updateCallbacks.erase(std::remove_if(updateCallbacks.begin(), updateCallbacks.end(), [](QueryCallback& callback)
|
||||
{
|
||||
return callback.InvokeIfReady() == QueryCallbackNew::Completed;
|
||||
}), _callbacks.end());
|
||||
return callback.InvokeIfReady() == QueryCallback::Completed;
|
||||
}), updateCallbacks.end());
|
||||
|
||||
_callbacks.insert(_callbacks.end(), std::make_move_iterator(updateCallbacks.begin()), std::make_move_iterator(updateCallbacks.end()));
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "Define.h"
|
||||
#include <vector>
|
||||
|
||||
class QueryCallbackNew;
|
||||
class QueryCallback;
|
||||
|
||||
class TC_DATABASE_API QueryCallbackProcessor
|
||||
{
|
||||
@@ -29,14 +29,14 @@ public:
|
||||
QueryCallbackProcessor();
|
||||
~QueryCallbackProcessor();
|
||||
|
||||
void AddQuery(QueryCallbackNew&& query);
|
||||
void AddQuery(QueryCallback&& query);
|
||||
void ProcessReadyQueries();
|
||||
|
||||
private:
|
||||
QueryCallbackProcessor(QueryCallbackProcessor const&) = delete;
|
||||
QueryCallbackProcessor& operator=(QueryCallbackProcessor const&) = delete;
|
||||
|
||||
std::vector<QueryCallbackNew> _callbacks;
|
||||
std::vector<QueryCallback> _callbacks;
|
||||
};
|
||||
|
||||
#endif // QueryCallbackProcessor_h__
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "RBAC.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "Log.h"
|
||||
#include "QueryCallback.h"
|
||||
|
||||
namespace rbac
|
||||
{
|
||||
@@ -182,7 +183,7 @@ void RBACData::LoadFromDB()
|
||||
LoadFromDBCallback(LoginDatabase.Query(stmt));
|
||||
}
|
||||
|
||||
PreparedQueryResultFuture RBACData::LoadFromDBAsync()
|
||||
QueryCallback RBACData::LoadFromDBAsync()
|
||||
{
|
||||
ClearData();
|
||||
|
||||
|
||||
@@ -918,7 +918,7 @@ class TC_GAME_API RBACData
|
||||
|
||||
/// Loads all permissions assigned to current account
|
||||
void LoadFromDB();
|
||||
PreparedQueryResultFuture LoadFromDBAsync();
|
||||
QueryCallback LoadFromDBAsync();
|
||||
void LoadFromDBCallback(PreparedQueryResult result);
|
||||
|
||||
/// Sets security level
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@
|
||||
#include "Common.h"
|
||||
#include "Language.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "QueryCallback.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
@@ -469,11 +470,10 @@ void WorldSession::SendStablePet(ObjectGuid guid)
|
||||
stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
|
||||
stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
|
||||
|
||||
_sendStabledPetCallback.SetParam(guid);
|
||||
_sendStabledPetCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
|
||||
_queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::SendStablePetCallback, this, guid, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void WorldSession::SendStablePetCallback(PreparedQueryResult result, ObjectGuid guid)
|
||||
void WorldSession::SendStablePetCallback(ObjectGuid guid, PreparedQueryResult result)
|
||||
{
|
||||
if (!GetPlayer())
|
||||
return;
|
||||
@@ -571,7 +571,7 @@ void WorldSession::HandleStablePet(WorldPacket& recvData)
|
||||
stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT);
|
||||
stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT);
|
||||
|
||||
_stablePetCallback = CharacterDatabase.AsyncQuery(stmt);
|
||||
_queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleStablePetCallback, this, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void WorldSession::HandleStablePetCallback(PreparedQueryResult result)
|
||||
@@ -633,11 +633,10 @@ void WorldSession::HandleUnstablePet(WorldPacket& recvData)
|
||||
stmt->setUInt8(2, PET_SAVE_FIRST_STABLE_SLOT);
|
||||
stmt->setUInt8(3, PET_SAVE_LAST_STABLE_SLOT);
|
||||
|
||||
_unstablePetCallback.SetParam(petnumber);
|
||||
_unstablePetCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
|
||||
_queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleUnstablePetCallback, this, petnumber, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void WorldSession::HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId)
|
||||
void WorldSession::HandleUnstablePetCallback(uint32 petId, PreparedQueryResult result)
|
||||
{
|
||||
if (!GetPlayer())
|
||||
return;
|
||||
@@ -760,11 +759,10 @@ void WorldSession::HandleStableSwapPet(WorldPacket& recvData)
|
||||
stmt->setUInt32(0, _player->GetGUID().GetCounter());
|
||||
stmt->setUInt32(1, petId);
|
||||
|
||||
_stableSwapCallback.SetParam(petId);
|
||||
_stableSwapCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
|
||||
_queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleStableSwapPetCallback, this, petId, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void WorldSession::HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId)
|
||||
void WorldSession::HandleStableSwapPetCallback(uint32 petId, PreparedQueryResult result)
|
||||
{
|
||||
if (!GetPlayer())
|
||||
return;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "WorldSession.h"
|
||||
#include "Player.h"
|
||||
#include "QueryCallback.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
|
||||
@@ -42,11 +43,11 @@ void WorldSession::HandleAddFriendOpcode(WorldPacket& recvData)
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME);
|
||||
stmt->setString(0, friendName);
|
||||
|
||||
_addFriendCallback.SetParam(friendNote);
|
||||
_addFriendCallback.SetFutureResult(CharacterDatabase.AsyncQuery(stmt));
|
||||
_queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt)
|
||||
.WithPreparedCallback(std::bind(&WorldSession::HandleAddFriendOpcodeCallback, this, std::move(friendNote), std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void WorldSession::HandleAddFriendOpcodeCallback(PreparedQueryResult result, std::string const& friendNote)
|
||||
void WorldSession::HandleAddFriendOpcodeCallback(std::string const& friendNote, PreparedQueryResult result)
|
||||
{
|
||||
if (!GetPlayer())
|
||||
return;
|
||||
@@ -116,7 +117,7 @@ void WorldSession::HandleAddIgnoreOpcode(WorldPacket& recvData)
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUID_BY_NAME);
|
||||
stmt->setString(0, ignoreName);
|
||||
|
||||
_addIgnoreCallback = CharacterDatabase.AsyncQuery(stmt);
|
||||
_queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSession::HandleAddIgnoreOpcodeCallback, this, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void WorldSession::HandleAddIgnoreOpcodeCallback(PreparedQueryResult result)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Config.h"
|
||||
#include "Common.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "QueryCallback.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "Log.h"
|
||||
#include "Opcodes.h"
|
||||
@@ -137,7 +138,6 @@ WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldS
|
||||
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId()); // One-time query
|
||||
}
|
||||
|
||||
InitializeQueryCallbackParameters();
|
||||
}
|
||||
|
||||
/// WorldSession destructor
|
||||
@@ -1085,99 +1085,16 @@ void WorldSession::SetPlayer(Player* player)
|
||||
m_GUIDLow = _player->GetGUID().GetCounter();
|
||||
}
|
||||
|
||||
void WorldSession::InitializeQueryCallbackParameters()
|
||||
{
|
||||
// Callback parameters that have pointers in them should be properly
|
||||
// initialized to NULL here.
|
||||
_charCreateCallback.SetParam(NULL);
|
||||
}
|
||||
|
||||
void WorldSession::ProcessQueryCallbacks()
|
||||
{
|
||||
PreparedQueryResult result;
|
||||
_queryProcessor.ProcessReadyQueries();
|
||||
|
||||
if (_realmAccountLoginCallback.valid() && _realmAccountLoginCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
InitializeSessionCallback(_realmAccountLoginCallback.get());
|
||||
|
||||
//! HandleCharEnumOpcode
|
||||
if (_charEnumCallback.valid() && _charEnumCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
result = _charEnumCallback.get();
|
||||
HandleCharEnum(result);
|
||||
}
|
||||
|
||||
if (_charCreateCallback.IsReady())
|
||||
{
|
||||
_charCreateCallback.GetResult(result);
|
||||
HandleCharCreateCallback(result, _charCreateCallback.GetParam());
|
||||
}
|
||||
|
||||
//! HandlePlayerLoginOpcode
|
||||
if (_charLoginCallback.valid() && _charLoginCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
SQLQueryHolder* param = _charLoginCallback.get();
|
||||
HandlePlayerLogin((LoginQueryHolder*)param);
|
||||
}
|
||||
|
||||
//! HandleAddFriendOpcode
|
||||
if (_addFriendCallback.IsReady())
|
||||
{
|
||||
std::string param = _addFriendCallback.GetParam();
|
||||
_addFriendCallback.GetResult(result);
|
||||
HandleAddFriendOpcodeCallback(result, param);
|
||||
_addFriendCallback.FreeResult();
|
||||
}
|
||||
|
||||
//- HandleCharRenameOpcode
|
||||
if (_charRenameCallback.IsReady())
|
||||
{
|
||||
_charRenameCallback.GetResult(result);
|
||||
CharacterRenameInfo* renameInfo = _charRenameCallback.GetParam();
|
||||
HandleChangePlayerNameOpcodeCallBack(result, renameInfo);
|
||||
delete renameInfo;
|
||||
_charRenameCallback.Reset();
|
||||
}
|
||||
|
||||
//- HandleCharAddIgnoreOpcode
|
||||
if (_addIgnoreCallback.valid() && _addIgnoreCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
result = _addIgnoreCallback.get();
|
||||
HandleAddIgnoreOpcodeCallback(result);
|
||||
}
|
||||
|
||||
//- SendStabledPet
|
||||
if (_sendStabledPetCallback.IsReady())
|
||||
{
|
||||
ObjectGuid param = _sendStabledPetCallback.GetParam();
|
||||
_sendStabledPetCallback.GetResult(result);
|
||||
SendStablePetCallback(result, param);
|
||||
_sendStabledPetCallback.FreeResult();
|
||||
}
|
||||
|
||||
//- HandleStablePet
|
||||
if (_stablePetCallback.valid() && _stablePetCallback.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
result = _stablePetCallback.get();
|
||||
HandleStablePetCallback(result);
|
||||
}
|
||||
|
||||
//- HandleUnstablePet
|
||||
if (_unstablePetCallback.IsReady())
|
||||
{
|
||||
uint32 param = _unstablePetCallback.GetParam();
|
||||
_unstablePetCallback.GetResult(result);
|
||||
HandleUnstablePetCallback(result, param);
|
||||
_unstablePetCallback.FreeResult();
|
||||
}
|
||||
|
||||
//- HandleStableSwapPet
|
||||
if (_stableSwapCallback.IsReady())
|
||||
{
|
||||
uint32 param = _stableSwapCallback.GetParam();
|
||||
_stableSwapCallback.GetResult(result);
|
||||
HandleStableSwapPetCallback(result, param);
|
||||
_stableSwapCallback.FreeResult();
|
||||
}
|
||||
HandlePlayerLogin(reinterpret_cast<LoginQueryHolder*>(_charLoginCallback.get()));
|
||||
}
|
||||
|
||||
void WorldSession::InitWarden(BigNumber* k, std::string const& os)
|
||||
@@ -1204,7 +1121,7 @@ void WorldSession::LoadPermissions()
|
||||
_RBACData->LoadFromDB();
|
||||
}
|
||||
|
||||
PreparedQueryResultFuture WorldSession::LoadPermissionsAsync()
|
||||
QueryCallback WorldSession::LoadPermissionsAsync()
|
||||
{
|
||||
uint32 id = GetAccountId();
|
||||
uint8 secLevel = GetSecurity();
|
||||
|
||||
@@ -239,6 +239,7 @@ struct CharacterFactionChangeInfo : public CharacterCustomizeInfo
|
||||
|
||||
protected:
|
||||
uint8 Race = 0;
|
||||
bool FactionChange = false;
|
||||
};
|
||||
|
||||
struct PacketCounter
|
||||
@@ -284,7 +285,7 @@ class TC_GAME_API WorldSession
|
||||
rbac::RBACData* GetRBACData();
|
||||
bool HasPermission(uint32 permissionId);
|
||||
void LoadPermissions();
|
||||
PreparedQueryResultFuture LoadPermissionsAsync();
|
||||
QueryCallback LoadPermissionsAsync();
|
||||
void InvalidateRBACData(); // Used to force LoadPermissions at next HasPermission check
|
||||
|
||||
AccountTypes GetSecurity() const { return _security; }
|
||||
@@ -356,7 +357,7 @@ class TC_GAME_API WorldSession
|
||||
// Pet
|
||||
void SendPetNameQuery(ObjectGuid guid, uint32 petnumber);
|
||||
void SendStablePet(ObjectGuid guid);
|
||||
void SendStablePetCallback(PreparedQueryResult result, ObjectGuid guid);
|
||||
void SendStablePetCallback(ObjectGuid guid, PreparedQueryResult result);
|
||||
void SendStableResult(uint8 guid);
|
||||
bool CheckStableMaster(ObjectGuid guid);
|
||||
|
||||
@@ -449,16 +450,23 @@ class TC_GAME_API WorldSession
|
||||
void HandleCharEnumOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharDeleteOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharCreateOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharCreateCallback(PreparedQueryResult result, CharacterCreateInfo* createInfo);
|
||||
void HandlePlayerLoginOpcode(WorldPacket& recvPacket);
|
||||
void HandleCharEnum(PreparedQueryResult result);
|
||||
void HandlePlayerLogin(LoginQueryHolder * holder);
|
||||
void HandlePlayerLogin(LoginQueryHolder* holder);
|
||||
void HandleCharFactionOrRaceChange(WorldPacket& recvData);
|
||||
void HandleCharFactionOrRaceChangeCallback(std::shared_ptr<CharacterFactionChangeInfo> factionChangeInfo, PreparedQueryResult result);
|
||||
void HandleCharRenameOpcode(WorldPacket& recvData);
|
||||
void HandleCharRenameCallback(std::shared_ptr<CharacterRenameInfo> renameInfo, PreparedQueryResult result);
|
||||
void HandleSetPlayerDeclinedNames(WorldPacket& recvData);
|
||||
void HandleAlterAppearance(WorldPacket& recvData);
|
||||
void HandleCharCustomize(WorldPacket& recvData);
|
||||
void HandleCharCustomizeCallback(std::shared_ptr<CharacterCustomizeInfo> customizeInfo, PreparedQueryResult result);
|
||||
|
||||
void SendCharCreate(ResponseCodes result);
|
||||
void SendCharDelete(ResponseCodes result);
|
||||
void SendCharRename(ResponseCodes result, CharacterRenameInfo const& renameInfo);
|
||||
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const& customizeInfo);
|
||||
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const& factionChangeInfo);
|
||||
void SendCharRename(ResponseCodes result, CharacterRenameInfo const* renameInfo);
|
||||
void SendCharCustomize(ResponseCodes result, CharacterCustomizeInfo const* customizeInfo);
|
||||
void SendCharFactionChange(ResponseCodes result, CharacterFactionChangeInfo const* factionChangeInfo);
|
||||
void SendSetPlayerDeclinedNamesResult(DeclinedNameResult result, ObjectGuid guid);
|
||||
void SendBarberShopResult(BarberShopResult result);
|
||||
|
||||
@@ -528,7 +536,7 @@ class TC_GAME_API WorldSession
|
||||
// Social
|
||||
void HandleContactListOpcode(WorldPacket& recvPacket);
|
||||
void HandleAddFriendOpcode(WorldPacket& recvPacket);
|
||||
void HandleAddFriendOpcodeCallback(PreparedQueryResult result, std::string const& friendNote);
|
||||
void HandleAddFriendOpcodeCallback(std::string const& friendNote, PreparedQueryResult result);
|
||||
void HandleDelFriendOpcode(WorldPacket& recvPacket);
|
||||
void HandleAddIgnoreOpcode(WorldPacket& recvPacket);
|
||||
void HandleAddIgnoreOpcodeCallback(PreparedQueryResult result);
|
||||
@@ -651,11 +659,11 @@ class TC_GAME_API WorldSession
|
||||
void HandleStablePet(WorldPacket& recvPacket);
|
||||
void HandleStablePetCallback(PreparedQueryResult result);
|
||||
void HandleUnstablePet(WorldPacket& recvPacket);
|
||||
void HandleUnstablePetCallback(PreparedQueryResult result, uint32 petId);
|
||||
void HandleUnstablePetCallback(uint32 petId, PreparedQueryResult result);
|
||||
void HandleBuyStableSlot(WorldPacket& recvPacket);
|
||||
void HandleStableRevivePet(WorldPacket& recvPacket);
|
||||
void HandleStableSwapPet(WorldPacket& recvPacket);
|
||||
void HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId);
|
||||
void HandleStableSwapPetCallback(uint32 petId, PreparedQueryResult result);
|
||||
|
||||
void HandleDuelAcceptedOpcode(WorldPacket& recvPacket);
|
||||
void HandleDuelCancelledOpcode(WorldPacket& recvPacket);
|
||||
@@ -805,10 +813,6 @@ class TC_GAME_API WorldSession
|
||||
|
||||
void HandleSetActionBarToggles(WorldPacket& recvData);
|
||||
|
||||
void HandleCharRenameOpcode(WorldPacket& recvData);
|
||||
void HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult result, CharacterRenameInfo const* renameInfo);
|
||||
void HandleSetPlayerDeclinedNames(WorldPacket& recvData);
|
||||
|
||||
void HandleTotemDestroyed(WorldPacket& recvData);
|
||||
void HandleDismissCritter(WorldPacket& recvData);
|
||||
|
||||
@@ -952,9 +956,7 @@ class TC_GAME_API WorldSession
|
||||
|
||||
void HandleSpellClick(WorldPacket& recvData);
|
||||
void HandleMirrorImageDataRequest(WorldPacket& recvData);
|
||||
void HandleAlterAppearance(WorldPacket& recvData);
|
||||
void HandleRemoveGlyph(WorldPacket& recvData);
|
||||
void HandleCharCustomize(WorldPacket& recvData);
|
||||
void HandleQueryInspectAchievements(WorldPacket& recvData);
|
||||
void HandleEquipmentSetSave(WorldPacket& recvData);
|
||||
void HandleEquipmentSetDelete(WorldPacket& recvData);
|
||||
@@ -969,21 +971,13 @@ class TC_GAME_API WorldSession
|
||||
void HandleUpdateMissileTrajectory(WorldPacket& recvPacket);
|
||||
|
||||
private:
|
||||
void InitializeQueryCallbackParameters();
|
||||
void ProcessQueryCallbacks();
|
||||
|
||||
QueryResultHolderFuture _realmAccountLoginCallback;
|
||||
PreparedQueryResultFuture _charEnumCallback;
|
||||
PreparedQueryResultFuture _addIgnoreCallback;
|
||||
PreparedQueryResultFuture _stablePetCallback;
|
||||
QueryCallback<PreparedQueryResult, CharacterRenameInfo*> _charRenameCallback;
|
||||
QueryCallback<PreparedQueryResult, std::string> _addFriendCallback;
|
||||
QueryCallback<PreparedQueryResult, uint32> _unstablePetCallback;
|
||||
QueryCallback<PreparedQueryResult, uint32> _stableSwapCallback;
|
||||
QueryCallback<PreparedQueryResult, ObjectGuid> _sendStabledPetCallback;
|
||||
QueryCallback<PreparedQueryResult, CharacterCreateInfo*, true> _charCreateCallback;
|
||||
QueryResultHolderFuture _charLoginCallback;
|
||||
|
||||
QueryCallbackProcessor _queryProcessor;
|
||||
|
||||
friend class World;
|
||||
protected:
|
||||
class DosProtection
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "WorldSocket.h"
|
||||
#include "BigNumber.h"
|
||||
#include "Opcodes.h"
|
||||
#include "QueryCallback.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SHA1.h"
|
||||
#include "PacketLog.h"
|
||||
@@ -51,8 +52,7 @@ void WorldSocket::Start()
|
||||
stmt->setString(0, ip_address);
|
||||
stmt->setUInt32(1, inet_addr(ip_address.c_str()));
|
||||
|
||||
_queryCallback = std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1);
|
||||
_queryFuture = LoginDatabase.AsyncQuery(stmt);
|
||||
_queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::CheckIpCallback, this, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void WorldSocket::CheckIpCallback(PreparedQueryResult result)
|
||||
@@ -125,12 +125,7 @@ bool WorldSocket::Update()
|
||||
if (!BaseSocket::Update())
|
||||
return false;
|
||||
|
||||
if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
|
||||
{
|
||||
auto callback = _queryCallback;
|
||||
_queryCallback = nullptr;
|
||||
callback(_queryFuture.get());
|
||||
}
|
||||
_queryProcessor.ProcessReadyQueries();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -444,8 +439,7 @@ void WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
|
||||
stmt->setInt32(0, int32(realm.Id.Realm));
|
||||
stmt->setString(1, authSession->Account);
|
||||
|
||||
_queryCallback = std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1);
|
||||
_queryFuture = LoginDatabase.AsyncQuery(stmt);
|
||||
_queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&WorldSocket::HandleAuthSessionCallback, this, authSession, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSession, PreparedQueryResult result)
|
||||
@@ -603,8 +597,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes
|
||||
if (wardenActive)
|
||||
_worldSession->InitWarden(&account.SessionKey, account.OS);
|
||||
|
||||
_queryCallback = std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1);
|
||||
_queryFuture = _worldSession->LoadPermissionsAsync();
|
||||
_queryProcessor.AddQuery(_worldSession->LoadPermissionsAsync().WithPreparedCallback(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1)));
|
||||
AsyncRead();
|
||||
}
|
||||
|
||||
|
||||
@@ -111,8 +111,7 @@ private:
|
||||
MessageBuffer _packetBuffer;
|
||||
MPSCQueue<EncryptablePacket> _bufferQueue;
|
||||
|
||||
PreparedQueryResultFuture _queryFuture;
|
||||
std::function<void(PreparedQueryResult&&)> _queryCallback;
|
||||
QueryCallbackProcessor _queryProcessor;
|
||||
std::string _ipCountry;
|
||||
};
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "DisableMgr.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "GameObjectModel.h"
|
||||
#include "GitRevision.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "GuildMgr.h"
|
||||
@@ -52,7 +53,7 @@
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "Player.h"
|
||||
#include "PoolMgr.h"
|
||||
#include "GitRevision.h"
|
||||
#include "QueryCallback.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptReloadMgr.h"
|
||||
#include "SkillDiscovery.h"
|
||||
@@ -2909,7 +2910,7 @@ void World::UpdateRealmCharCount(uint32 accountId)
|
||||
{
|
||||
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_COUNT);
|
||||
stmt->setUInt32(0, accountId);
|
||||
m_realmCharCallbacks.push_back(CharacterDatabase.AsyncQuery(stmt));
|
||||
_queryProcessor.AddQuery(CharacterDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&World::_UpdateRealmCharCount, this, std::placeholders::_1)));
|
||||
}
|
||||
|
||||
void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount)
|
||||
@@ -3271,20 +3272,7 @@ uint64 World::getWorldState(uint32 index) const
|
||||
|
||||
void World::ProcessQueryCallbacks()
|
||||
{
|
||||
PreparedQueryResult result;
|
||||
|
||||
for (std::deque<std::future<PreparedQueryResult>>::iterator itr = m_realmCharCallbacks.begin(); itr != m_realmCharCallbacks.end(); )
|
||||
{
|
||||
if ((*itr).wait_for(std::chrono::seconds(0)) != std::future_status::ready)
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
result = (*itr).get();
|
||||
_UpdateRealmCharCount(result);
|
||||
itr = m_realmCharCallbacks.erase(itr);
|
||||
}
|
||||
_queryProcessor.ProcessReadyQueries();
|
||||
}
|
||||
|
||||
CharacterInfo const* World::GetCharacterInfo(ObjectGuid const& guid) const
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "Timer.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "QueryResult.h"
|
||||
#include "QueryCallback.h"
|
||||
#include "QueryCallbackProcessor.h"
|
||||
#include "Realm/Realm.h"
|
||||
|
||||
#include <atomic>
|
||||
@@ -882,7 +882,7 @@ class TC_GAME_API World
|
||||
void LoadCharacterInfoStore();
|
||||
|
||||
void ProcessQueryCallbacks();
|
||||
std::deque<std::future<PreparedQueryResult>> m_realmCharCallbacks;
|
||||
QueryCallbackProcessor _queryProcessor;
|
||||
};
|
||||
|
||||
TC_GAME_API extern Realm realm;
|
||||
|
||||
Reference in New Issue
Block a user