Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/GameLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ void GameLoop::UpdateAllButDraw(bool bRunningFromVBLANK)

// Update the lights
LIGHTSMAN->Update(fDeltaTime);

// Process broadcast queue from other threads
MESSAGEMAN->HandleQueuedBroadcasts();
}

void GameLoop::RunGameLoop()
Expand Down
36 changes: 33 additions & 3 deletions src/MessageManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "EnumHelper.h"
#include "LuaManager.h"
#include "RageLog.h"
#include "arch/Threads/Threads.h"
#include "RageThreads.h"

#include <set>
#include <map>
Expand Down Expand Up @@ -154,7 +156,7 @@ void Message::SetParamFromStack( lua_State *L, const RString &sName )
m_pParams->Set( L, sName );
}

MessageManager::MessageManager()
MessageManager::MessageManager() : m_messagemanBroadcastQueue_mutex("m_messagemanBroadcastQueue")
{
m_Logging= false;
// Register with Lua.
Expand Down Expand Up @@ -205,6 +207,26 @@ void MessageManager::Unsubscribe( IMessageSubscriber* pSubscriber, MessageID m )
Unsubscribe( pSubscriber, MessageIDToString(m) );
}

/** @brief Queue Message to be ran on the main thread. */
void MessageManager::QueueBroadcast(std::unique_ptr<Message> msg) {
m_messagemanBroadcastQueue_mutex.Lock();
m_messagemanBroadcastQueue.push(std::move(msg));
m_messagemanBroadcastQueue_mutex.Unlock();
}

/** @brief Check message queue for broadcasts. ONLY CALL FROM MAIN THREAD. */
void MessageManager::HandleQueuedBroadcasts() {
if (!m_messagemanBroadcastQueue.empty()) {
m_messagemanBroadcastQueue_mutex.Lock();
if (!m_messagemanBroadcastQueue.empty()) {
std::unique_ptr<Message> message = std::move(m_messagemanBroadcastQueue.front());
m_messagemanBroadcastQueue.pop();
MESSAGEMAN->Broadcast(*message.get());
}
m_messagemanBroadcastQueue_mutex.Unlock();
}
}

void MessageManager::Broadcast( Message &msg ) const
{
if(m_Logging)
Expand Down Expand Up @@ -289,6 +311,7 @@ void MessageSubscriber::UnsubscribeAll()

// lua start
#include "LuaBinding.h"
#include "RageThreads.h"

/** @brief Allow Lua to have access to the MessageManager. */
class LunaMessageManager: public Luna<MessageManager>
Expand All @@ -303,8 +326,15 @@ class LunaMessageManager: public Luna<MessageManager>
lua_pushvalue( L, 2 );
ParamTable.SetFromStack( L );

Message msg( SArg(1), ParamTable );
p->Broadcast( msg );
if (p->m_mainThreadID != RageThread::GetCurrentThreadID()) {
// Message constructor copies the string and LuaReference ParamTable, they're not left dangling
std::unique_ptr<Message> msg(new Message(SArg(1), ParamTable));
p->QueueBroadcast(std::move(msg));
} else {
Message msg( SArg(1), ParamTable );
p->Broadcast( msg );
}

COMMON_RETURN_SELF;
}
static int SetLogging(T* p, lua_State *L)
Expand Down
12 changes: 11 additions & 1 deletion src/MessageManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include "LuaManager.h"

#include <vector>

#include <queue>
#include <memory>
#include "RageThreads.h"

struct lua_State;
class LuaTable;
Expand Down Expand Up @@ -207,8 +209,16 @@ class MessageManager
void SetLogging(bool set) { m_Logging= set; }
bool m_Logging;

uint64_t m_mainThreadID = 0;
void QueueBroadcast(std::unique_ptr<Message> message);
void HandleQueuedBroadcasts();

// Lua
void PushSelf( lua_State *L );

private:
std::queue<std::unique_ptr<Message>> m_messagemanBroadcastQueue;
RageMutex m_messagemanBroadcastQueue_mutex;
};

extern MessageManager* MESSAGEMAN; // global and accessible from anywhere in our program
Expand Down
1 change: 1 addition & 0 deletions src/StepMania.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ int sm_main(int argc, char* argv[])

// Set up the messaging system early to have well defined code.
MESSAGEMAN = new MessageManager;
MESSAGEMAN->m_mainThreadID = RageThread::GetCurrentThreadID();

// Create game objects
GAMESTATE = new GameState;
Expand Down
Loading