diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..387a07f77 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "extensions/src/ACRE2Profiling/tracy"] + path = extensions/src/ACRE2Profiling/tracy + url = https://github.com/wolfpld/tracy.git diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index 03d9dc0f2..059bdc1ed 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -6,6 +6,7 @@ include(${PROJECT_SOURCE_DIR}/CMakeModules/cxx_compiler_functions.cmake) option(USE_64BIT_BUILD "USE_64BIT_BUILD" OFF) option(USE_STATIC_LINKING "USE_STATIC_LINKING" ON) +option(ENABLE_TRACING "ENABLE_TRACING" OFF) set(CMAKE_BUILD_TYPE "RelWithDebInfo") @@ -58,6 +59,13 @@ if(MSVC) set(GLOBAL_SOURCES ${GLOBAL_RC}) endif() +if(ENABLE_TRACING) + message(STATUS "Enabling tracing (beware of excessively verbose log output)") + add_compile_definitions(_TRACE=1) +endif() + +add_subdirectory(src/ACRE2Profiling) + include_directories(src/ACRE2Shared) include_directories(src/ACRE2Core) diff --git a/extensions/src/ACRE2Core/CMakeLists.txt b/extensions/src/ACRE2Core/CMakeLists.txt index 3f7489a8e..48cb77b0b 100644 --- a/extensions/src/ACRE2Core/CMakeLists.txt +++ b/extensions/src/ACRE2Core/CMakeLists.txt @@ -8,5 +8,5 @@ file(GLOB SOURCES *.h *.hpp *.c *.cpp) file(GLOB DSP_SOURCES DspFilters/*.h DspFilters/*.hpp DspFilters/*.c DspFilters/*.cpp) add_library( ${ACRE_NAME} STATIC ${SOURCES} ${GLOBAL_SOURCES} ${DSP_SOURCES}) -target_link_libraries( ${ACRE_NAME} ACRE2Shared) +target_link_libraries( ${ACRE_NAME} ACRE2Shared ACRE2Profiling) set_target_properties(${ACRE_NAME} PROPERTIES FOLDER ACRE2) diff --git a/extensions/src/ACRE2Core/Engine.cpp b/extensions/src/ACRE2Core/Engine.cpp index d8f329c75..0a0b5a6e2 100644 --- a/extensions/src/ACRE2Core/Engine.cpp +++ b/extensions/src/ACRE2Core/Engine.cpp @@ -31,7 +31,10 @@ #include "setChannelDetails.h" #include +#include + acre::Result CEngine::initialize(IClient *client, IServer *externalServer, std::string fromPipeName, std::string toPipeName) { + ZoneScoped; if (!g_Log) { std::string acrePluginLog{"acre2_plugin.log"}; @@ -92,6 +95,7 @@ acre::Result CEngine::initialize(IClient *client, IServer *externalServer, std:: } acre::Result CEngine::initialize(IClient *client, IServer *externalServer, std::string fromPipeName, std::string toPipeName, std::string loggingPath) { + ZoneScoped; g_Log = (Log *)new Log(const_cast(loggingPath.c_str())); LOG("* Logging engine initialized."); @@ -100,6 +104,8 @@ acre::Result CEngine::initialize(IClient *client, IServer *externalServer, std:: } acre::Result CEngine::start(const acre::id_t id) { + ZoneScoped; + if (this->getExternalServer()) { this->getExternalServer()->initialize(); } else { @@ -124,6 +130,8 @@ acre::Result CEngine::start(const acre::id_t id) { } acre::Result CEngine::stop() { + ZoneScoped; + LOG("Engine Shutting Down"); this->setState(acre::State::stopping); @@ -152,11 +160,15 @@ acre::Result CEngine::stop() { } acre::Result CEngine::localStartSpeaking(const acre::Speaking speakingType) { + ZoneScoped; + this->localStartSpeaking(speakingType, ""); return acre::Result::ok; } acre::Result CEngine::localStartSpeaking(const acre::Speaking speakingType, const std::string radioId) { + ZoneScoped; + // send a start speaking event to everyone TRACE("Local START speaking: %d, %s", speakingType, radioId.c_str()); this->getSelf()->lock(); @@ -192,6 +204,8 @@ acre::Result CEngine::localStartSpeaking(const acre::Speaking speakingType, cons } acre::Result CEngine::localStopSpeaking( void ) { + ZoneScoped; + this->getSelf()->setSpeaking(false); CEngine::getInstance()->getExternalServer()->sendMessage( CTextMessage::formatNewMessage("ext_remoteStopSpeaking", @@ -213,6 +227,8 @@ acre::Result CEngine::localStopSpeaking( void ) { } acre::Result CEngine::remoteStartSpeaking(const acre::id_t remoteId, const int32_t languageId, const std::string netId, const acre::Speaking speakingType, const std::string radioId, const acre::volume_t curveScale) { + ZoneScoped; + TRACE("Remote Start Speaking Enter: %d, %d", remoteId, speakingType); auto it = this->speakingList.find(remoteId); if (it != this->speakingList.end()) { @@ -241,6 +257,8 @@ acre::Result CEngine::remoteStartSpeaking(const acre::id_t remoteId, const int32 } acre::Result CEngine::remoteStopSpeaking(const acre::id_t remoteId) { + ZoneScoped; + TRACE("Remote STOP Speaking Enter: %d", remoteId); auto it = this->speakingList.find(remoteId); if (it != this->speakingList.end()) { diff --git a/extensions/src/ACRE2Core/NamedPipeServer.cpp b/extensions/src/ACRE2Core/NamedPipeServer.cpp index 2da726fc6..beb634222 100644 --- a/extensions/src/ACRE2Core/NamedPipeServer.cpp +++ b/extensions/src/ACRE2Core/NamedPipeServer.cpp @@ -4,6 +4,7 @@ #include "Log.h" #include "Engine.h" +#include @@ -24,6 +25,8 @@ CNamedPipeServer::~CNamedPipeServer( void ) { } acre::Result CNamedPipeServer::initialize() { + ZoneScoped; + HANDLE writeHandle, readHandle; SECURITY_DESCRIPTOR sd; @@ -105,6 +108,8 @@ acre::Result CNamedPipeServer::initialize() { } acre::Result CNamedPipeServer::shutdown(void) { + ZoneScoped; + HANDLE hPipe; this->setShuttingDown(true); @@ -141,12 +146,15 @@ acre::Result CNamedPipeServer::shutdown(void) { return acre::Result::ok; } +const char *sendFrameName = "NamedPipeServer - sending"; + acre::Result CNamedPipeServer::sendLoop() { + tracy::SetThreadName("NamedPipeServer::sendLoop"); + while (!this->getShuttingDown()) { - do { ConnectNamedPipe(this->m_PipeHandleWrite, NULL); - if (GetLastError() == ERROR_PIPE_CONNECTED) { + if (GetLastError() == ERROR_PIPE_CONNECTED) { LOG("Client write connected"); CEngine::getInstance()->getSoundEngine()->onClientGameConnected(); this->setConnectedWrite(true); @@ -159,6 +167,8 @@ acre::Result CNamedPipeServer::sendLoop() { clock_t lastTick = clock() / CLOCKS_PER_SEC; while (this->getConnectedWrite()) { + FrameMarkStart(sendFrameName); + if (this->getShuttingDown()) break; @@ -172,6 +182,8 @@ acre::Result CNamedPipeServer::sendLoop() { IMessage *msg = nullptr; if (this->m_sendQueue.try_pop(msg)) { if (msg != nullptr) { + ZoneScoped; + lastTick = clock() / CLOCKS_PER_SEC; const DWORD size = (DWORD)strlen((char *)msg->getData()) + 1; if (size > 3) { @@ -196,20 +208,29 @@ acre::Result CNamedPipeServer::sendLoop() { } delete msg; } + + FrameMarkEnd(sendFrameName); } + Sleep(1); } + LOG("Write loop disconnected"); FlushFileBuffers(this->m_PipeHandleWrite); const bool ret = DisconnectNamedPipe(this->m_PipeHandleWrite); Sleep(1); } + TRACE("Sending thread terminating"); return acre::Result::ok; } +const char *receiveFrameName = "NamedPipeServer - receiving"; + acre::Result CNamedPipeServer::readLoop() { + tracy::SetThreadName("NamedPipeServer::readLoop"); + DWORD cbRead; char *mBuffer = (char *)LocalAlloc(LMEM_FIXED, BUFSIZE); @@ -220,22 +241,29 @@ acre::Result CNamedPipeServer::readLoop() { this->validTSServers.insert(std::string("enter a ts3 server id here")); */ while (!this->getShuttingDown()) { - //this->checkServer(); - bool ret = ConnectNamedPipe(this->m_PipeHandleRead, NULL); - if (GetLastError() == ERROR_PIPE_CONNECTED) { - LOG("Client read connected"); - CEngine::getInstance()->getClient()->updateShouldSwitchChannel(false); - CEngine::getInstance()->getClient()->unMuteAll(); - CEngine::getInstance()->getSoundEngine()->onClientGameConnected(); - this->setConnectedRead(true); - } else { - this->setConnectedRead(false); - Sleep(1); + bool ret = false; + { + // ZoneScopedN("CNamedPipeServer::readLoop - connecting read pipe"); + // this->checkServer(); + ret = ConnectNamedPipe(this->m_PipeHandleRead, NULL); + if (GetLastError() == ERROR_PIPE_CONNECTED) { + LOG("Client read connected"); + CEngine::getInstance()->getClient()->updateShouldSwitchChannel(false); + CEngine::getInstance()->getClient()->unMuteAll(); + CEngine::getInstance()->getSoundEngine()->onClientGameConnected(); + this->setConnectedRead(true); + } else { + this->setConnectedRead(false); + Sleep(1); - continue; + continue; + } } + clock_t lastTick = clock() / CLOCKS_PER_SEC; while (this->getConnectedRead()) { + FrameMarkStart(receiveFrameName); + //this->checkServer(); if (this->getShuttingDown()) { break; @@ -264,24 +292,30 @@ acre::Result CNamedPipeServer::readLoop() { this->setConnectedRead(false); break; } + + ZoneScoped; + // handle the packet and run it mBuffer[cbRead] = 0x00; - //LOG("READ: %s", (char *)mBuffer); - IMessage *const msg = new CTextMessage((char *)mBuffer, cbRead); - //TRACE("got and parsed message [%s]", msg->getData()); + // LOG("READ: %s", (char *)mBuffer); + IMessage *const msg = new CTextMessage((char *) mBuffer, cbRead); + // TRACE("got and parsed message [%s]", msg->getData()); if (msg != nullptr && msg->getProcedureName()) { - // Do not free msg, this is deleted inside runProcedure() CEngine::getInstance()->getRpcEngine()->runProcedure(this, msg); lastTick = clock() / CLOCKS_PER_SEC; - //TRACE("tick [%d], [%s]",lastTick, msg->getData()); + // TRACE("tick [%d], [%s]",lastTick, msg->getData()); } // wait 1ms for new msg so we dont hog cpu cycles } while (!ret); - //ret = ConnectNamedPipe(this->getPipeHandle(), NULL); + //ret = ConnectNamedPipe(this->getPipeHandle(), NULL); + + FrameMarkEnd(receiveFrameName); + Sleep(1); } + // Kill the write pipe along with ourselves, because we master shutdown/startup this->setConnectedWrite(false); this->setConnectedRead(false); @@ -305,7 +339,8 @@ acre::Result CNamedPipeServer::readLoop() { CEngine::getInstance()->getSelf()->getId() ) ); - } + } + Sleep(1); } diff --git a/extensions/src/ACRE2Core/RpcEngine.cpp b/extensions/src/ACRE2Core/RpcEngine.cpp index 1c79b9bee..1a0e6e174 100644 --- a/extensions/src/ACRE2Core/RpcEngine.cpp +++ b/extensions/src/ACRE2Core/RpcEngine.cpp @@ -12,16 +12,24 @@ #include "Log.h" #include -// +#include + +const char *frameName = "RPCEngine"; + // // Entrant worker, weee // acre::Result CRpcEngine::exProcessItem(ACRE_RPCDATA *data) { + tracy::SetThreadName("RPCEngine"); + FrameMarkStart(frameName); + if (data->function != nullptr) { data->function->call(data->server, data->message); } delete data->message; free(data); + FrameMarkEnd(frameName); + return acre::Result::ok; } @@ -29,6 +37,8 @@ acre::Result CRpcEngine::exProcessItem(ACRE_RPCDATA *data) { // Proc functions // acre::Result CRpcEngine::addProcedure(IRpcFunction *const cmd) { + ZoneScoped; + LOCK(this); this->m_FunctionList.insert(std::pair(std::string(cmd->getName()), cmd)); UNLOCK(this); @@ -36,6 +46,8 @@ acre::Result CRpcEngine::addProcedure(IRpcFunction *const cmd) { return acre::Result::ok; } acre::Result CRpcEngine::removeProcedure(IRpcFunction *const cmd) { + ZoneScoped; + LOCK(this); this->m_FunctionList.erase(cmd->getName()); UNLOCK(this); @@ -43,6 +55,8 @@ acre::Result CRpcEngine::removeProcedure(IRpcFunction *const cmd) { return acre::Result::ok; } acre::Result CRpcEngine::removeProcedure(char *const cmd) { + ZoneScoped; + LOCK(this); this->m_FunctionList.erase(cmd); UNLOCK(this); @@ -50,6 +64,8 @@ acre::Result CRpcEngine::removeProcedure(char *const cmd) { return acre::Result::ok; } IRpcFunction *CRpcEngine::findProcedure(char *const cmd) { + ZoneScoped; + if (this->getShuttingDown()) { return nullptr; @@ -62,11 +78,15 @@ IRpcFunction *CRpcEngine::findProcedure(char *const cmd) { return nullptr; } + acre::Result CRpcEngine::runProcedure(IServer *const serverInstance, IMessage *msg) { + ZoneScoped; + return this->runProcedure(serverInstance, msg, TRUE); } acre::Result CRpcEngine::runProcedure(IServer *const serverInstance, IMessage *msg, const bool entrant) { + ZoneScoped; if (msg == nullptr) { return acre::Result::error; diff --git a/extensions/src/ACRE2Core/ext_handleGetClientID.h b/extensions/src/ACRE2Core/ext_handleGetClientID.h index 4b4da1ee2..2bb4b7f67 100644 --- a/extensions/src/ACRE2Core/ext_handleGetClientID.h +++ b/extensions/src/ACRE2Core/ext_handleGetClientID.h @@ -11,7 +11,11 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(ext_handleGetClientID) { + ZoneScopedN("RPC - ext_handleGetClientID"); + CEngine::getInstance()->getGameServer()->sendMessage( CTextMessage::formatNewMessage("handleGetClientID", "%d,%s,", diff --git a/extensions/src/ACRE2Core/ext_remoteStartSpeaking.h b/extensions/src/ACRE2Core/ext_remoteStartSpeaking.h index 6fe02c0ae..22d0e0c7b 100644 --- a/extensions/src/ACRE2Core/ext_remoteStartSpeaking.h +++ b/extensions/src/ACRE2Core/ext_remoteStartSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(ext_remoteStartSpeaking) { + ZoneScopedN("RPC - ext_remoteStartSpeaking"); /*CTextMessage::formatNewMessage("ext_remoteStartSpeaking", "%d,%d,%s,%f,", diff --git a/extensions/src/ACRE2Core/ext_remoteStopSpeaking.h b/extensions/src/ACRE2Core/ext_remoteStopSpeaking.h index ccb4f6856..a18e0238a 100644 --- a/extensions/src/ACRE2Core/ext_remoteStopSpeaking.h +++ b/extensions/src/ACRE2Core/ext_remoteStopSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(ext_remoteStopSpeaking) { + ZoneScopedN("RPC - ext_remoteStopSpeaking"); /*CTextMessage::formatNewMessage("ext_remoteStartSpeaking", "%d,%d,%s,%f,", diff --git a/extensions/src/ACRE2Core/ext_reset.h b/extensions/src/ACRE2Core/ext_reset.h index 42781bc98..c51ce5754 100644 --- a/extensions/src/ACRE2Core/ext_reset.h +++ b/extensions/src/ACRE2Core/ext_reset.h @@ -5,7 +5,11 @@ #include "Types.h" #include "Engine.h" +#include + RPC_FUNCTION(ext_reset) { + ZoneScopedN("RPC - ext_reset"); + const acre::id_t id = vMessage->getParameterAsInt(0); // diff --git a/extensions/src/ACRE2Core/getClientID.h b/extensions/src/ACRE2Core/getClientID.h index b1f678c5a..7a1994f0d 100644 --- a/extensions/src/ACRE2Core/getClientID.h +++ b/extensions/src/ACRE2Core/getClientID.h @@ -12,7 +12,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(getClientID) { + ZoneScopedN("RPC - getClientID"); TRACE("enter"); diff --git a/extensions/src/ACRE2Core/getPluginVersion.h b/extensions/src/ACRE2Core/getPluginVersion.h index 9b1e151a4..baf28f541 100644 --- a/extensions/src/ACRE2Core/getPluginVersion.h +++ b/extensions/src/ACRE2Core/getPluginVersion.h @@ -3,7 +3,10 @@ #include "IServer.h" #include "TextMessage.h" +#include + RPC_FUNCTION(getPluginVersion) { + ZoneScopedN("RPC - getPluginVersion"); vServer->sendMessage(CTextMessage::formatNewMessage("handleGetPluginVersion", "%s", ACRE_VERSION)); diff --git a/extensions/src/ACRE2Core/loadSound.h b/extensions/src/ACRE2Core/loadSound.h index 879ca1e0c..ffd21e798 100644 --- a/extensions/src/ACRE2Core/loadSound.h +++ b/extensions/src/ACRE2Core/loadSound.h @@ -11,7 +11,11 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(loadSound) { + ZoneScopedN("RPC - loadSound"); + const std::string id = std::string((char *)vMessage->getParameter(0)); const int32_t currentCount = vMessage->getParameterAsInt(1); const int32_t totalCount = vMessage->getParameterAsInt(2); diff --git a/extensions/src/ACRE2Core/localMute.h b/extensions/src/ACRE2Core/localMute.h index 24d11df4d..d12411ed7 100644 --- a/extensions/src/ACRE2Core/localMute.h +++ b/extensions/src/ACRE2Core/localMute.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(localMute) { + ZoneScopedN("RPC - localMute"); const bool status = vMessage->getParameterAsInt(0) == 1; diff --git a/extensions/src/ACRE2Core/ping.h b/extensions/src/ACRE2Core/ping.h index ab53984a6..061a92f9a 100644 --- a/extensions/src/ACRE2Core/ping.h +++ b/extensions/src/ACRE2Core/ping.h @@ -7,9 +7,13 @@ #include "Engine.h" #include "TextMessage.h" +#include + volatile DWORD g_pingTime; RPC_FUNCTION(ping) { + ZoneScopedN("RPC - ping"); + g_pingTime = clock() / CLOCKS_PER_SEC; vServer->sendMessage(CTextMessage::formatNewMessage("pong", "%f,", g_pingTime)); return acre::Result::ok; diff --git a/extensions/src/ACRE2Core/playSound.h b/extensions/src/ACRE2Core/playSound.h index 98d9d5720..000a6c472 100644 --- a/extensions/src/ACRE2Core/playSound.h +++ b/extensions/src/ACRE2Core/playSound.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(playLoadedSound) { + ZoneScopedN("RPC - playLoadedSound"); const std::string id = std::string((char *)vMessage->getParameter(0)); const acre::vec3_fp32_t position(vMessage->getParameterAsFloat(1), vMessage->getParameterAsFloat(3), vMessage->getParameterAsFloat(2)); diff --git a/extensions/src/ACRE2Core/setChannelDetails.h b/extensions/src/ACRE2Core/setChannelDetails.h index b5532472e..87a8574fa 100644 --- a/extensions/src/ACRE2Core/setChannelDetails.h +++ b/extensions/src/ACRE2Core/setChannelDetails.h @@ -7,7 +7,11 @@ #include +#include + RPC_FUNCTION(setChannelDetails) { + ZoneScopedN("RPC - setChannelDetails"); + const std::vector details = { std::string((char *)vMessage->getParameter(0)), std::string((char *)vMessage->getParameter(1)), diff --git a/extensions/src/ACRE2Core/setMuted.h b/extensions/src/ACRE2Core/setMuted.h index 266a5f0c0..5d62c38cd 100644 --- a/extensions/src/ACRE2Core/setMuted.h +++ b/extensions/src/ACRE2Core/setMuted.h @@ -8,9 +8,12 @@ #include "Engine.h" #include "TextMessage.h" +#include RPC_FUNCTION(setMuted) { + ZoneScopedN("RPC - setMuted"); + for (DWORD index = 0; index < vMessage->getParameterCount(); -1) { if (vMessage->getParameter(index) == nullptr) { break; diff --git a/extensions/src/ACRE2Core/setPTTKeys.h b/extensions/src/ACRE2Core/setPTTKeys.h index db79a1a23..0e7768da4 100644 --- a/extensions/src/ACRE2Core/setPTTKeys.h +++ b/extensions/src/ACRE2Core/setPTTKeys.h @@ -4,7 +4,11 @@ #include "TextMessage.h" #include "Log.h" +#include + RPC_FUNCTION(setPTTKeys) { + ZoneScopedN("RPC - setPTTKeys"); + /* CEngine::getInstance()->getKeyHandlerEngine()->setKeyBind( std::string((char *)vMessage->getParameter(0)), diff --git a/extensions/src/ACRE2Core/setSelectableVoiceCurve.h b/extensions/src/ACRE2Core/setSelectableVoiceCurve.h index cc8bd7dd4..684aa6cf6 100644 --- a/extensions/src/ACRE2Core/setSelectableVoiceCurve.h +++ b/extensions/src/ACRE2Core/setSelectableVoiceCurve.h @@ -4,7 +4,11 @@ #include "TextMessage.h" #include "Log.h" +#include + RPC_FUNCTION(setSelectableVoiceCurve) { + ZoneScopedN("RPC - setSelectableVoiceCurve"); + const float32_t voiceCurveScale = vMessage->getParameterAsFloat(0); //LOG("VOICE MODEL: %d VOICE CURVE: %f", voiceModel, voiceCurveScale); if (!CEngine::getInstance()->getGameServer()->getConnected()) { diff --git a/extensions/src/ACRE2Core/setSetting.h b/extensions/src/ACRE2Core/setSetting.h index 998ae9ad0..74f32bfd3 100644 --- a/extensions/src/ACRE2Core/setSetting.h +++ b/extensions/src/ACRE2Core/setSetting.h @@ -4,7 +4,11 @@ #include "Log.h" #include "AcreSettings.h" +#include + RPC_FUNCTION(setSetting) { + ZoneScopedN("RPC - setSetting"); + const std::string name = std::string((char *)vMessage->getParameter(0)); float32_t value = vMessage->getParameterAsFloat(1); value = round(value * 100.0f) / 100.0f; diff --git a/extensions/src/ACRE2Core/setSoundSystemMasterOverride.h b/extensions/src/ACRE2Core/setSoundSystemMasterOverride.h index f8e94fd18..dc4a7d02e 100644 --- a/extensions/src/ACRE2Core/setSoundSystemMasterOverride.h +++ b/extensions/src/ACRE2Core/setSoundSystemMasterOverride.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(setSoundSystemMasterOverride) { + ZoneScopedN("RPC - setSoundSystemMasterOverride"); const bool status = vMessage->getParameterAsInt(0) == 1; diff --git a/extensions/src/ACRE2Core/setVoiceCurveModel.h b/extensions/src/ACRE2Core/setVoiceCurveModel.h index f3fa7f4e2..0c8d7ee1c 100644 --- a/extensions/src/ACRE2Core/setVoiceCurveModel.h +++ b/extensions/src/ACRE2Core/setVoiceCurveModel.h @@ -4,7 +4,11 @@ #include "TextMessage.h" #include "Log.h" +#include + RPC_FUNCTION(setVoiceCurveModel) { + ZoneScopedN("RPC - setVoiceCurveModel"); + const acre::CurveModel voiceModel = static_cast(vMessage->getParameterAsInt(0)); const float32_t voiceCurveScale = vMessage->getParameterAsFloat(1); diff --git a/extensions/src/ACRE2Core/startGodModeSpeaking.h b/extensions/src/ACRE2Core/startGodModeSpeaking.h index 829412002..5cf281589 100644 --- a/extensions/src/ACRE2Core/startGodModeSpeaking.h +++ b/extensions/src/ACRE2Core/startGodModeSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(startGodModeSpeaking) { + ZoneScopedN("RPC - startGodModeSpeaking"); CEngine::getInstance()->getClient()->localStartSpeaking(acre::Speaking::god); diff --git a/extensions/src/ACRE2Core/startIntercomSpeaking.h b/extensions/src/ACRE2Core/startIntercomSpeaking.h index eefa7780e..c66225733 100644 --- a/extensions/src/ACRE2Core/startIntercomSpeaking.h +++ b/extensions/src/ACRE2Core/startIntercomSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(startIntercomSpeaking) { + ZoneScopedN("RPC - startIntercomSpeaking"); CEngine::getInstance()->getClient()->localStartSpeaking(acre::Speaking::intercom); diff --git a/extensions/src/ACRE2Core/startRadioSpeaking.h b/extensions/src/ACRE2Core/startRadioSpeaking.h index 8875fdfd5..71c4c13ce 100644 --- a/extensions/src/ACRE2Core/startRadioSpeaking.h +++ b/extensions/src/ACRE2Core/startRadioSpeaking.h @@ -13,7 +13,10 @@ #include +#include + RPC_FUNCTION(startRadioSpeaking) { + ZoneScopedN("RPC - startRadioSpeaking"); const std::string radioId = std::string((char *)vMessage->getParameter(0)); diff --git a/extensions/src/ACRE2Core/startZeusSpeaking.h b/extensions/src/ACRE2Core/startZeusSpeaking.h index 4dcac1435..a4576e495 100644 --- a/extensions/src/ACRE2Core/startZeusSpeaking.h +++ b/extensions/src/ACRE2Core/startZeusSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(startZeusSpeaking) { + ZoneScopedN("RPC - startZeusSpeaking"); CEngine::getInstance()->getClient()->localStartSpeaking(acre::Speaking::zeus); diff --git a/extensions/src/ACRE2Core/stopGodModeSpeaking.h b/extensions/src/ACRE2Core/stopGodModeSpeaking.h index 5486c9003..46b3456d4 100644 --- a/extensions/src/ACRE2Core/stopGodModeSpeaking.h +++ b/extensions/src/ACRE2Core/stopGodModeSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(stopGodModeSpeaking) { + ZoneScopedN("RPC - stopGodModeSpeaking"); CEngine::getInstance()->getClient()->localStopSpeaking(acre::Speaking::god); diff --git a/extensions/src/ACRE2Core/stopIntercomSpeaking.h b/extensions/src/ACRE2Core/stopIntercomSpeaking.h index eca43e7e2..6819865e9 100644 --- a/extensions/src/ACRE2Core/stopIntercomSpeaking.h +++ b/extensions/src/ACRE2Core/stopIntercomSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(stopIntercomSpeaking) { + ZoneScopedN("RPC - stopIntercomSpeaking"); CEngine::getInstance()->getClient()->localStopSpeaking(acre::Speaking::intercom); diff --git a/extensions/src/ACRE2Core/stopRadioSpeaking.h b/extensions/src/ACRE2Core/stopRadioSpeaking.h index 0b1ad6540..d1728f703 100644 --- a/extensions/src/ACRE2Core/stopRadioSpeaking.h +++ b/extensions/src/ACRE2Core/stopRadioSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(stopRadioSpeaking) { + ZoneScopedN("RPC - stopRadioSpeaking"); CEngine::getInstance()->getClient()->localStopSpeaking(acre::Speaking::radio); diff --git a/extensions/src/ACRE2Core/stopZeusSpeaking.h b/extensions/src/ACRE2Core/stopZeusSpeaking.h index b99cebe6e..0a50dd677 100644 --- a/extensions/src/ACRE2Core/stopZeusSpeaking.h +++ b/extensions/src/ACRE2Core/stopZeusSpeaking.h @@ -11,7 +11,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(stopZeusSpeaking) { + ZoneScopedN("RPC - stopZeuSpeaking"); CEngine::getInstance()->getClient()->localStopSpeaking(acre::Speaking::zeus); diff --git a/extensions/src/ACRE2Core/updateSelf.h b/extensions/src/ACRE2Core/updateSelf.h index 2977f73ff..b2d3f9148 100644 --- a/extensions/src/ACRE2Core/updateSelf.h +++ b/extensions/src/ACRE2Core/updateSelf.h @@ -12,7 +12,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(updateSelf) { + ZoneScopedN("RPC - updateSelf"); LOCK(CEngine::getInstance()->getSelf()); diff --git a/extensions/src/ACRE2Core/updateSpeakingData.h b/extensions/src/ACRE2Core/updateSpeakingData.h index 6eedd0d16..48d07fe7e 100644 --- a/extensions/src/ACRE2Core/updateSpeakingData.h +++ b/extensions/src/ACRE2Core/updateSpeakingData.h @@ -12,7 +12,10 @@ #include "TextMessage.h" +#include + RPC_FUNCTION(updateSpeakingData) { + ZoneScopedN("RPC - updateSpeakingData"); CPlayer *speaker = nullptr; diff --git a/extensions/src/ACRE2Mumble/CMakeLists.txt b/extensions/src/ACRE2Mumble/CMakeLists.txt index 26a5ab283..0c3a80c1b 100644 --- a/extensions/src/ACRE2Mumble/CMakeLists.txt +++ b/extensions/src/ACRE2Mumble/CMakeLists.txt @@ -11,7 +11,7 @@ file(GLOB_RECURSE SOURCES *.h *.hpp *.c *.cpp *.asm mumble_includes/*) include_directories(mumble_includes) add_library( ${ACRE_NAME} MODULE ${SOURCES} ${GLOBAL_SOURCES}) -target_link_libraries(${ACRE_NAME} ACRE2Core ACRE2Shared x3daudio) +target_link_libraries(${ACRE_NAME} ACRE2Core ACRE2Shared ACRE2Profiling x3daudio) set_target_properties(${ACRE_NAME} PROPERTIES FOLDER ACRE2 LINK_FLAGS -SAFESEH:NO) target_compile_features(${ACRE_NAME} PRIVATE cxx_std_17) diff --git a/extensions/src/ACRE2Mumble/MumbleCallbacks_channelEvents.cpp b/extensions/src/ACRE2Mumble/MumbleCallbacks_channelEvents.cpp index 46e2d2721..64489a93d 100644 --- a/extensions/src/ACRE2Mumble/MumbleCallbacks_channelEvents.cpp +++ b/extensions/src/ACRE2Mumble/MumbleCallbacks_channelEvents.cpp @@ -5,11 +5,15 @@ #include "Types.h" #include "compat.h" +#include + extern MumbleAPI_v_1_0_x mumAPI; extern mumble_connection_t activeConnection; extern mumble_plugin_id_t pluginID; void mumble_onChannelRenamed(mumble_connection_t connection, mumble_channelid_t channelID) { + ZoneScoped; + (void) connection; (void) channelID; CEngine::getInstance()->getClient()->updateShouldSwitchChannel(true); diff --git a/extensions/src/ACRE2Mumble/MumbleCallbacks_init.cpp b/extensions/src/ACRE2Mumble/MumbleCallbacks_init.cpp index 80ea6abf2..56f386f3d 100644 --- a/extensions/src/ACRE2Mumble/MumbleCallbacks_init.cpp +++ b/extensions/src/ACRE2Mumble/MumbleCallbacks_init.cpp @@ -7,9 +7,13 @@ #include "compat.h" #include "helpers.h" +#include + #define FROM_PIPENAME "\\\\.\\pipe\\acre_comm_pipe_fromTS" #define TO_PIPENAME "\\\\.\\pipe\\acre_comm_pipe_toTS" +const char *mumbleThreadName = "Mumble main thread"; + extern MumbleAPI_v_1_0_x mumAPI; mumble_connection_t activeConnection = -1; mumble_plugin_id_t pluginID = -1; @@ -23,11 +27,15 @@ void mumble_registerAPIFunctions(void *apiStruct) { } mumble_error_t mumble_init(mumble_plugin_id_t id) { + ZoneScoped; + + tracy::SetThreadName(mumbleThreadName); + pluginID = id; acre::MumbleEventLoop::getInstance().start(); - if (mumAPI.getActiveServerConnection(pluginID, &activeConnection) != MUMBLE_STATUS_OK) { + if (API_CALL(getActiveServerConnection, pluginID, &activeConnection) != MUMBLE_STATUS_OK) { activeConnection = -1; } @@ -49,12 +57,22 @@ mumble_error_t mumble_init(mumble_plugin_id_t id) { } void mumble_onServerSynchronized(mumble_connection_t connection) { + ZoneScoped; + + tracy::SetThreadName(mumbleThreadName); + acre::MumbleEventLoop::getInstance().queue([connection]() { + ZoneScoped; + activeConnection = connection; // set ID on every new connection - acre::id_t clientId = 0; - mumAPI.getLocalUserID(pluginID, activeConnection, (mumble_userid_t*)&clientId); + acre::id_t clientId = 5; + mumble_error_t retCode = API_CALL(getLocalUserID, pluginID, activeConnection, (mumble_userid_t*)&clientId); + if (retCode != MUMBLE_STATUS_OK) { + LOG("ERROR, FAILED TO FETCH LOCAL USER'S ID: %s (%d)", mumble_errorMessage(retCode), retCode); + } + TRACE("Local user's ID is %d", clientId); CEngine::getInstance()->getSelf()->setId(clientId); CEngine::getInstance()->getExternalServer()->setId(clientId); @@ -66,7 +84,11 @@ void mumble_onServerSynchronized(mumble_connection_t connection) { } void mumble_onServerDisconnected(mumble_connection_t connection) { + ZoneScoped; + acre::MumbleEventLoop::getInstance().queue([connection]() { + ZoneScoped; + activeConnection = -1; if ((CEngine::getInstance()->getClient()->getState() != acre::State::stopped) && @@ -77,7 +99,11 @@ void mumble_onServerDisconnected(mumble_connection_t connection) { } void mumble_shutdown() { + ZoneScoped; + acre::MumbleEventLoop::getInstance().queue([]() { + ZoneScoped; + if ((CEngine::getInstance()->getClient()->getState() != acre::State::stopped) && (CEngine::getInstance()->getClient()->getState() != acre::State::stopping)) { CEngine::getInstance()->getClient()->stop(); diff --git a/extensions/src/ACRE2Mumble/MumbleCallbacks_pluginEvents.cpp b/extensions/src/ACRE2Mumble/MumbleCallbacks_pluginEvents.cpp index 035c16b87..9244c12aa 100644 --- a/extensions/src/ACRE2Mumble/MumbleCallbacks_pluginEvents.cpp +++ b/extensions/src/ACRE2Mumble/MumbleCallbacks_pluginEvents.cpp @@ -4,14 +4,20 @@ #include "MumbleEventLoop.h" #include "compat.h" +#include + // // Handle a command event // bool mumble_onReceiveData(mumble_connection_t connection, mumble_userid_t sender, const uint8_t *data, size_t dataLength, const char *dataID) { + ZoneScoped; + if ((dataLength > 0U) && CEngine::getInstance()->getExternalServer()) { // Copy data to make sure it stays available in the async processing std::string dataString(reinterpret_cast(data), dataLength); acre::MumbleEventLoop::getInstance().queue([dataString]() { + ZoneScoped; + CEngine::getInstance()->getExternalServer()->handleMessage((unsigned char *)dataString.data(), dataString.size()); }); return true; diff --git a/extensions/src/ACRE2Mumble/MumbleCallbacks_sound.cpp b/extensions/src/ACRE2Mumble/MumbleCallbacks_sound.cpp index 6022f882e..625e2f3e3 100644 --- a/extensions/src/ACRE2Mumble/MumbleCallbacks_sound.cpp +++ b/extensions/src/ACRE2Mumble/MumbleCallbacks_sound.cpp @@ -6,6 +6,8 @@ #include "Wave.h" #include "compat.h" +#include + #include #define _USE_MATH_DEFINES @@ -31,6 +33,8 @@ bool mumble_onAudioSourceFetched(float *outputPCM, uint32_t sampleCount, uint16_ return false; } + ZoneScoped; + // Make this faster const std::uint32_t mixdownSampleLength = sampleCount; int16_t *mixdownSamples = new (std::nothrow) int16_t[mixdownSampleLength]; @@ -104,6 +108,8 @@ bool mumble_onAudioSourceFetched(float *outputPCM, uint32_t sampleCount, uint16_ } bool mumble_onAudioOutputAboutToPlay(float *outputPCM, uint32_t sampleCount, uint16_t channelCount, uint32_t sampleRate) { + tracy::SetThreadName("Mumble audio output thread"); + (void) sampleRate; if (CEngine::getInstance()->getSoundSystemOverride()) { @@ -118,6 +124,8 @@ bool mumble_onAudioOutputAboutToPlay(float *outputPCM, uint32_t sampleCount, uin return false; } + ZoneScoped; + uint32_t speakerMask = SPEAKER_STEREO; // Make this faster diff --git a/extensions/src/ACRE2Mumble/MumbleCallbacks_speaking.cpp b/extensions/src/ACRE2Mumble/MumbleCallbacks_speaking.cpp index 2fe03c5b2..22fc57ab4 100644 --- a/extensions/src/ACRE2Mumble/MumbleCallbacks_speaking.cpp +++ b/extensions/src/ACRE2Mumble/MumbleCallbacks_speaking.cpp @@ -6,11 +6,16 @@ #include "Types.h" #include "compat.h" +#include // // Mumble Speaking callbacks // void mumble_onUserTalkingStateChanged(mumble_connection_t connection, mumble_userid_t userID, mumble_talking_state_t status) { + ZoneScoped; + acre::MumbleEventLoop::getInstance().queue([connection, userID, status]() { + ZoneScoped; + TRACE("mumble_onUserTalkingStateChanged ENTER: %d", status); if (static_cast(userID) != CEngine::getInstance()->getSelf()->getId()) { return; diff --git a/extensions/src/ACRE2Mumble/MumbleClient.cpp b/extensions/src/ACRE2Mumble/MumbleClient.cpp index d883b6076..ddea7c6e6 100644 --- a/extensions/src/ACRE2Mumble/MumbleClient.cpp +++ b/extensions/src/ACRE2Mumble/MumbleClient.cpp @@ -8,6 +8,8 @@ #include "compat.h" #include "shlobj.h" +#include + #pragma comment(lib, "Shlwapi.lib") static constexpr std::int32_t invalid_mumble_channel = -1; @@ -18,28 +20,38 @@ extern mumble_connection_t activeConnection; extern mumble_plugin_id_t pluginID; acre::Result CMumbleClient::initialize() { + ZoneScoped; + setPreviousChannel(invalid_mumble_channel); return acre::Result::ok; } acre::Result CMumbleClient::setMuted(const acre::id_t id_, const bool muted_) { + ZoneScoped; + (void) id_; (void) muted_; return acre::Result::ok; } acre::Result CMumbleClient::setMuted(std::list idList_, bool muted_) { + ZoneScoped; + (void) idList_; (void) muted_; return acre::Result::ok; } acre::Result CMumbleClient::getMuted(acre::id_t id_) { + ZoneScoped; + (void) id_; return acre::Result::ok; } acre::Result CMumbleClient::stop() { + ZoneScoped; + if (CEngine::getInstance() != nullptr) { CEngine::getInstance()->stop(); this->setState(acre::State::stopping); @@ -48,13 +60,15 @@ acre::Result CMumbleClient::stop() { } this->setState(acre::State::stopped); - mumAPI.log(pluginID, "stopped"); + API_CALL(log, pluginID, "stopped"); } return acre::Result::ok; } acre::Result CMumbleClient::start(const acre::id_t id_) { + ZoneScoped; + CEngine::getInstance()->start(id_); this->setInputActive(false); this->setDirectFirst(false); @@ -68,15 +82,17 @@ acre::Result CMumbleClient::start(const acre::id_t id_) { this->setState(acre::State::running); this->setIsX3DInitialized(false); - mumAPI.log(pluginID, "Started"); - mumAPI.log(pluginID, ACRE_VERSION_METADATA); + API_CALL(log, pluginID, "Started"); + API_CALL(log, pluginID, ACRE_VERSION_METADATA); return acre::Result::ok; } bool CMumbleClient::getVAD() { + ZoneScoped; + mumble_transmission_mode_t transmitMode; - const mumble_error_t err = mumAPI.getLocalUserTransmissionMode(pluginID, &transmitMode); + const mumble_error_t err = API_CALL(getLocalUserTransmissionMode, pluginID, &transmitMode); if (err != MUMBLE_STATUS_OK) { return false; } @@ -85,11 +101,15 @@ bool CMumbleClient::getVAD() { } acre::Result CMumbleClient::localStartSpeaking(const acre::Speaking speakingType_) { + ZoneScoped; + this->localStartSpeaking(speakingType_, ""); return acre::Result::ok; } acre::Result CMumbleClient::localStartSpeaking(const acre::Speaking speakingType_, std::string radioId_) { + ZoneScoped; + bool stopDirectSpeaking = false; const bool VADactive = this->getVAD(); @@ -133,6 +153,8 @@ acre::Result CMumbleClient::localStartSpeaking(const acre::Speaking speakingType } acre::Result CMumbleClient::localStopSpeaking(const acre::Speaking speakingType_) { + ZoneScoped; + bool resendDirectSpeaking = false; const bool VADactive = this->getVAD(); @@ -205,11 +227,15 @@ acre::Result CMumbleClient::localStopSpeaking(const acre::Speaking speakingType_ } acre::Result CMumbleClient::enableMicrophone(const bool status_) { + ZoneScoped; + (void) status_; return acre::Result::ok; } acre::Result CMumbleClient::playSound(std::string path_, acre::vec3_fp32_t position_, const float32_t volume_, const int32_t looping_) { + ZoneScoped; + return acre::Result::ok; } @@ -218,7 +244,13 @@ std::string CMumbleClient::getUniqueId() { } std::string CMumbleClient::getConfigFilePath(void) { - std::string tempFolder = ".\\acre"; + // For the time being Mumble doesn't expose a config file path via its API, so we just fall back + // to using a sub-directory in Arma 3's AppData directory + std::string tempFolder = "acre"; + std::array appDataPath{""}; + if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, appDataPath.data()))) { + tempFolder = std::string(appDataPath.data()) + "\\Arma 3\\" + tempFolder; + } if (!PathFileExistsA(tempFolder.c_str()) && !CreateDirectoryA(tempFolder.c_str(), nullptr)) { LOG("ERROR: UNABLE TO CREATE TEMP DIR"); } @@ -239,7 +271,9 @@ std::string CMumbleClient::getTempFilePath(void) { } acre::Result CMumbleClient::microphoneOpen(bool status_) { - const mumble_error_t res = mumAPI.requestMicrophoneActivationOvewrite(pluginID, status_); + ZoneScoped; + + const mumble_error_t res = API_CALL(requestMicrophoneActivationOvewrite, pluginID, status_); if (res != MUMBLE_STATUS_OK) { if (status_) { LOG("Error toggling PTT Open: %s (%d)\n", mumble_errorMessage(res), res); @@ -255,20 +289,25 @@ acre::Result CMumbleClient::microphoneOpen(bool status_) { } acre::Result CMumbleClient::unMuteAll(void) { + ZoneScoped; + return acre::Result::ok; } acre::Result CMumbleClient::moveToServerChannel() { + ZoneScoped; + TRACE("moveToServerChannel ENTER"); if (!CAcreSettings::getInstance()->getDisableChannelSwitch()) { mumble_userid_t clientId; std::vector details = getChannelDetails(); - if (mumAPI.getLocalUserID(pluginID, activeConnection, &clientId) == MUMBLE_STATUS_OK) { + if (API_CALL(getLocalUserID, pluginID, activeConnection, &clientId) == MUMBLE_STATUS_OK) { mumble_channelid_t currentChannelId = invalid_mumble_channel; - if ((mumAPI.getChannelOfUser(pluginID, activeConnection, clientId, ¤tChannelId) == MUMBLE_STATUS_OK) && + if ((API_CALL(getChannelOfUser, pluginID, activeConnection, clientId, ¤tChannelId) == MUMBLE_STATUS_OK) && (getPreviousChannel() == invalid_mumble_channel)) { + TRACE("Setting previous channel ID to %d", currentChannelId); setPreviousChannel(currentChannelId); } @@ -279,8 +318,11 @@ acre::Result CMumbleClient::moveToServerChannel() { password = details.at(1); } - mumAPI.requestUserMove(pluginID, activeConnection, clientId, channelId, password.c_str()); + TRACE("Requesting local user to be moved to channel %d", channelId); + API_CALL(requestUserMove, pluginID, activeConnection, clientId, channelId, password.c_str()); } + } else { + LOG("ERROR, FAILED TO OBTAIN LOCAL USER'S ID"); } } setShouldSwitchChannel(false); @@ -289,17 +331,19 @@ acre::Result CMumbleClient::moveToServerChannel() { } acre::Result CMumbleClient::moveToPreviousChannel() { + ZoneScoped; + TRACE("moveToPreviousChannel ENTER"); if (!CAcreSettings::getInstance()->getDisableChannelSwitch()) { mumble_userid_t clientId = -1; - if (mumAPI.getLocalUserID(pluginID, activeConnection, &clientId) == MUMBLE_STATUS_OK) { + if (API_CALL(getLocalUserID, pluginID, activeConnection, &clientId) == MUMBLE_STATUS_OK) { mumble_channelid_t currentChannelId = invalid_mumble_channel; - if (mumAPI.getChannelOfUser(pluginID, activeConnection, clientId, ¤tChannelId) == MUMBLE_STATUS_OK) { + if (API_CALL(getChannelOfUser, pluginID, activeConnection, clientId, ¤tChannelId) == MUMBLE_STATUS_OK) { const mumble_channelid_t channelId = static_cast(getPreviousChannel()); if (channelId != invalid_mumble_channel && channelId != currentChannelId) { - mumAPI.requestUserMove(pluginID, activeConnection, clientId, channelId, ""); + API_CALL(requestUserMove, pluginID, activeConnection, clientId, channelId, ""); } } } @@ -310,11 +354,13 @@ acre::Result CMumbleClient::moveToPreviousChannel() { } uint64_t CMumbleClient::findChannelByNames(std::vector details_) { + ZoneScoped; + TRACE("findChannelByNames ENTER"); mumble_channelid_t *channelList = nullptr; std::size_t channelCount = 0U; - if (mumAPI.getAllChannels(pluginID, activeConnection, &channelList, &channelCount) == MUMBLE_STATUS_OK) { + if (API_CALL(getAllChannels, pluginID, activeConnection, &channelList, &channelCount) == MUMBLE_STATUS_OK) { mumble_channelid_t channelId = invalid_mumble_channel; mumble_channelid_t defaultChannelId = invalid_mumble_channel; std::map channelMap; @@ -323,14 +369,16 @@ uint64_t CMumbleClient::findChannelByNames(std::vector details_) { name = details_.at(0); } + TRACE("Searching for channel \"%s\"", name.c_str()); + for (std::int32_t idx = 0U; idx < channelCount; idx++) { channelId = *channelList + idx; const char *channelName = nullptr; - if (mumAPI.getChannelName(pluginID, activeConnection, channelId, &channelName) == MUMBLE_STATUS_OK) { + if (API_CALL(getChannelName, pluginID, activeConnection, channelId, &channelName) == MUMBLE_STATUS_OK) { // Copy the channel name into a std::string and then get rid of the Mumble resource again std::string channelNameString(channelName); - mumAPI.freeMemory(pluginID, (void *) channelName); + API_CALL(freeMemory, pluginID, (void *) channelName); if (channelNameString.find(default_mumble_channel) != -1 || (!details_.at(0).empty() && channelNameString == name)) { if (channelNameString == default_mumble_channel) { @@ -341,7 +389,7 @@ uint64_t CMumbleClient::findChannelByNames(std::vector details_) { } } - mumAPI.freeMemory(pluginID, channelList); + API_CALL(freeMemory, pluginID, channelList); mumble_channelid_t bestChannelId = invalid_mumble_channel; int32_t bestMatches = 0; @@ -377,6 +425,8 @@ uint64_t CMumbleClient::findChannelByNames(std::vector details_) { } } return bestChannelId; + } else { + LOG("ERROR, FAILED TO GET CHANNEL LIST"); } return 0; diff --git a/extensions/src/ACRE2Mumble/MumbleCommandServer.cpp b/extensions/src/ACRE2Mumble/MumbleCommandServer.cpp index 2729f6d16..1bff925c4 100644 --- a/extensions/src/ACRE2Mumble/MumbleCommandServer.cpp +++ b/extensions/src/ACRE2Mumble/MumbleCommandServer.cpp @@ -4,6 +4,8 @@ #include "MumbleFunctions.h" #include "TextMessage.h" +#include + #include extern MumbleAPI_v_1_0_x mumAPI; @@ -23,30 +25,32 @@ acre::Result CMumbleCommandServer::shutdown() { } acre::Result CMumbleCommandServer::sendMessage(IMessage *msg) { + ZoneScoped; + std::lock_guard guard(*this); mumble_userid_t *channelUsers = nullptr; size_t userCount = 0U; mumble_channelid_t currentChannel = 0; - mumble_error_t err = mumAPI.getChannelOfUser(pluginID, activeConnection, this->getId(), ¤tChannel); + mumble_error_t err = API_CALL(getChannelOfUser, pluginID, activeConnection, this->getId(), ¤tChannel); if (err != MUMBLE_STATUS_OK) { LOG("ERROR, UNABLE TO GET CHANNEL OF USER: %s (%d)", mumble_errorMessage(err), err); return acre::Result::error; } - err = mumAPI.getUsersInChannel(pluginID, activeConnection, currentChannel, &channelUsers, &userCount); + err = API_CALL(getUsersInChannel, pluginID, activeConnection, currentChannel, &channelUsers, &userCount); if (err != MUMBLE_STATUS_OK) { LOG("ERROR, UNABLE TO GET USERS IN CHANNEL: %s (%d)", mumble_errorMessage(err), err); return acre::Result::error; } - err = mumAPI.sendData(pluginID, activeConnection, channelUsers, userCount, (const uint8_t *) msg->getData(), msg->getLength(), "ACRE2"); + err = API_CALL(sendData, pluginID, activeConnection, channelUsers, userCount, (const uint8_t *) msg->getData(), msg->getLength(), "ACRE2"); if (err != MUMBLE_STATUS_OK) { LOG("ERROR, UNABLE TO SEND MESSAGE DATA: %s (%d)", mumble_errorMessage(err), err); return acre::Result::error; } - err = mumAPI.freeMemory(pluginID, (void *) channelUsers); + err = API_CALL(freeMemory, pluginID, (void *) channelUsers); if (err != MUMBLE_STATUS_OK) { LOG("ERROR, UNABLE TO FREE CHANNEL USER LIST: %s (%d)", mumble_errorMessage(err), err); return acre::Result::error; @@ -62,6 +66,8 @@ acre::Result CMumbleCommandServer::handleMessage(unsigned char *data) { } acre::Result CMumbleCommandServer::handleMessage(unsigned char *data, size_t length) { + ZoneScoped; + CTextMessage *msg = nullptr; // TRACE("recv: [%s]", data); msg = new (std::nothrow) CTextMessage((char *) data, length); diff --git a/extensions/src/ACRE2Mumble/MumbleEventLoop.cpp b/extensions/src/ACRE2Mumble/MumbleEventLoop.cpp index ae49effba..7437447ff 100644 --- a/extensions/src/ACRE2Mumble/MumbleEventLoop.cpp +++ b/extensions/src/ACRE2Mumble/MumbleEventLoop.cpp @@ -1,5 +1,7 @@ #include "MumbleEventLoop.h" +#include + namespace acre { MumbleEventLoop& MumbleEventLoop::getInstance() { @@ -17,7 +19,7 @@ namespace acre { } { - std::lock_guard guard(m_lock); + std::lock_guard guard(m_lock); m_keepRunning = true; } @@ -25,9 +27,12 @@ namespace acre { } void MumbleEventLoop::stop() { + ZoneScoped; + { - std::lock_guard guard(m_lock); + std::lock_guard guard(m_lock); m_keepRunning = false; + m_drain = true; m_waiter.notify_all(); } @@ -39,7 +44,9 @@ namespace acre { } void MumbleEventLoop::queue(const std::function& callable) { - std::lock_guard guard(m_lock); + ZoneScoped; + + std::lock_guard guard(m_lock); m_queuedFunctions.push_back(callable); @@ -47,7 +54,9 @@ namespace acre { } void MumbleEventLoop::queue(std::function&& callable) { - std::unique_lock guard(m_lock); + ZoneScoped; + + std::unique_lock guard(m_lock); m_queuedFunctions.push_back(std::move(callable)); @@ -55,9 +64,16 @@ namespace acre { } void MumbleEventLoop::run() { - std::unique_lock guard(m_lock); + tracy::SetThreadName("ACRE2-Mumble-EventLoop"); + + std::unique_lock guard(m_lock); + + const char *frameName = "ACRE2 MumbleEventLoop"; + while (m_keepRunning || m_drain) { + FrameMarkStart(frameName); + + m_drain = false; - while (m_keepRunning) { // Process all pending events while (!m_queuedFunctions.empty()) { std::function currentFunc = std::move(m_queuedFunctions.front()); @@ -73,6 +89,8 @@ namespace acre { guard.lock(); } + FrameMarkEnd(frameName); + if (!m_keepRunning) { break; } diff --git a/extensions/src/ACRE2Mumble/MumbleEventLoop.h b/extensions/src/ACRE2Mumble/MumbleEventLoop.h index f46656bf0..5100440f3 100644 --- a/extensions/src/ACRE2Mumble/MumbleEventLoop.h +++ b/extensions/src/ACRE2Mumble/MumbleEventLoop.h @@ -6,6 +6,8 @@ #include #include +#include + namespace acre { /** @@ -39,9 +41,10 @@ namespace acre { void queue(std::function&& callable); protected: - std::mutex m_lock; - std::condition_variable m_waiter; + TracyLockable(std::mutex, m_lock); + std::condition_variable_any m_waiter; bool m_keepRunning = true; + bool m_drain = false; std::deque> m_queuedFunctions; std::thread m_thread; diff --git a/extensions/src/ACRE2Mumble/MumbleFunctions.h b/extensions/src/ACRE2Mumble/MumbleFunctions.h index c5860ab87..8db8d31ef 100644 --- a/extensions/src/ACRE2Mumble/MumbleFunctions.h +++ b/extensions/src/ACRE2Mumble/MumbleFunctions.h @@ -3,3 +3,16 @@ #include "MumbleAPI_v_1_0_x.h" #define MUMBLE_PLUGIN_NO_DEFAULT_FUNCTION_DEFINITIONS #include "MumblePlugin_v_1_1_x.h" + + +#include + +#ifndef TRACY_ENABLE +#define API_CALL(function, ...) mumAPI.function(__VA_ARGS__) +#else +#define API_CALL(function, ...) \ + [&]() mutable { \ + ZoneScopedN("Mumble API function \"" #function "\""); \ + return mumAPI.function(__VA_ARGS__); \ + }() +#endif diff --git a/extensions/src/ACRE2Profiling/CMakeLists.txt b/extensions/src/ACRE2Profiling/CMakeLists.txt new file mode 100644 index 000000000..320c8822a --- /dev/null +++ b/extensions/src/ACRE2Profiling/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required (VERSION 3.0) + +option(USE_TRACY "USE_TRACY" OFF) + +set(ACRE_NAME "ACRE2Profiling") + +acre_set_linker_options() + +file(GLOB SOURCES *.h *.hpp *.c *.cpp) + +add_library( ${ACRE_NAME} INTERFACE) + +if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tracy/CMakeLists.txt") + message(FATAL_ERROR "Unable to locate tracy submodule - did you forget to run git submodule update --init?") +endif() + +set(TRACY_ENABLE ${USE_TRACY} CACHE BOOL "" FORCE) +set(TRACY_ON_DEMAND OFF CACHE BOOL "" FORCE) +# We require the delayed init mode to prevent freezes on unloading/shutdown of the (Mumble) plugin +set(TRACY_DELAYED_INIT ON CACHE BOOL "" FORCE) +add_subdirectory("tracy") + +target_link_libraries( ${ACRE_NAME} INTERFACE Tracy::TracyClient) diff --git a/extensions/src/ACRE2Profiling/tracy b/extensions/src/ACRE2Profiling/tracy new file mode 160000 index 000000000..f493d4aa8 --- /dev/null +++ b/extensions/src/ACRE2Profiling/tracy @@ -0,0 +1 @@ +Subproject commit f493d4aa8ba8141d9680473fad007d8a6348628e diff --git a/extensions/src/ACRE2Shared/CMakeLists.txt b/extensions/src/ACRE2Shared/CMakeLists.txt index 79007c67d..5291f3ddc 100644 --- a/extensions/src/ACRE2Shared/CMakeLists.txt +++ b/extensions/src/ACRE2Shared/CMakeLists.txt @@ -7,5 +7,5 @@ acre_set_linker_options() file(GLOB SOURCES *.h *.hpp *.c *.cpp) add_library( ${ACRE_NAME} STATIC ${SOURCES} ${GLOBAL_SOURCES}) -target_link_libraries( ${ACRE_NAME}) +target_link_libraries( ${ACRE_NAME} ACRE2Profiling) set_target_properties(${ACRE_NAME} PROPERTIES FOLDER ACRE2) diff --git a/extensions/src/ACRE2Shared/EntrantWorker.h b/extensions/src/ACRE2Shared/EntrantWorker.h index b38432bda..599aef4e7 100644 --- a/extensions/src/ACRE2Shared/EntrantWorker.h +++ b/extensions/src/ACRE2Shared/EntrantWorker.h @@ -7,6 +7,8 @@ #include #include +#include + template class TEntrantWorker : public CLockable { public: TEntrantWorker() { @@ -17,6 +19,8 @@ template class TEntrantWorker : public CLockable { } acre::Result startWorker(void) { + ZoneScoped; + LOCK(this); setShuttingDown(false); std::queue().swap(m_processQueue); // Clear the queue @@ -27,6 +31,8 @@ template class TEntrantWorker : public CLockable { } acre::Result stopWorker(void) { + ZoneScoped; + setShuttingDown(true); setRunning(false); if (m_workerThread.joinable()) { diff --git a/extensions/src/ACRE2Shared/Lockable.h b/extensions/src/ACRE2Shared/Lockable.h index dfe9d205c..2788e90e0 100644 --- a/extensions/src/ACRE2Shared/Lockable.h +++ b/extensions/src/ACRE2Shared/Lockable.h @@ -3,9 +3,11 @@ #include +#include + class CLockable { private: - std::recursive_mutex m_lockable_mutex; + TracyLockable(std::recursive_mutex, m_lockable_mutex); public: void lock() { m_lockable_mutex.lock(); diff --git a/extensions/src/ACRE2TS/CMakeLists.txt b/extensions/src/ACRE2TS/CMakeLists.txt index bfbb0e4c0..bf1ceb84d 100644 --- a/extensions/src/ACRE2TS/CMakeLists.txt +++ b/extensions/src/ACRE2TS/CMakeLists.txt @@ -11,7 +11,7 @@ file(GLOB_RECURSE SOURCES *.h *.hpp *.c *.cpp *.asm inc/*) include_directories(inc) add_library( ${ACRE_NAME} MODULE ${SOURCES} ${GLOBAL_SOURCES}) -target_link_libraries(${ACRE_NAME} ACRE2Core ACRE2Shared x3daudio) +target_link_libraries(${ACRE_NAME} ACRE2Core ACRE2Shared ACRE2Profiling x3daudio) set_target_properties(${ACRE_NAME} PROPERTIES FOLDER ACRE2 LINK_FLAGS -SAFESEH:NO) target_compile_features(${ACRE_NAME} PRIVATE cxx_std_17)