ksys: Add MessageBroker and finish MessageDispatcher

This commit is contained in:
Léo Lam 2021-02-02 19:15:11 +01:00
parent 6e2e22cca5
commit df58679dda
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
12 changed files with 240 additions and 64 deletions

View File

@ -88866,12 +88866,12 @@
0x00000071010bff48,StateBase::exec4,8,
0x00000071010bff50,StateBase::return0,8,
0x00000071010bff58,StateBase::null,4,
0x00000071010bff5c,sub_71010BFF5C,20,
0x00000071010bff70,nullsub_4509,4,
0x00000071010bff74,j__ZdlPv_1197,4,
0x00000071010bff78,sub_71010BFF78,52,
0x00000071010bffac,sub_71010BFFAC,52,
0x00000071010bffe0,sub_71010BFFE0,36,
0x00000071010bff5c,sub_71010BFF5C,20,_ZN4ksys14IMessageBrokerC2Ev
0x00000071010bff70,nullsub_4509,4,_ZN4ksys14IMessageBrokerD1Ev
0x00000071010bff74,j__ZdlPv_1197,4,_ZN4ksys14IMessageBrokerD0Ev
0x00000071010bff78,sub_71010BFF78,52,_ZN4ksys14IMessageBroker19registerTransceiverERKNS_22MessageTransceiverBaseE
0x00000071010bffac,sub_71010BFFAC,52,_ZN4ksys14IMessageBroker21deregisterTransceiverERKNS_22MessageTransceiverBaseE
0x00000071010bffe0,sub_71010BFFE0,36,_ZN4ksys14IMessageBroker17countTransceiversEv
0x00000071010c0004,Struct1B::ctor,56,_ZN4ksys17MessageReceiverExC1Ev
0x00000071010c003c,j_Struct1A::dtor,4,_ZN4ksys17MessageReceiverExD1Ev
0x00000071010c0040,sub_71010C0040,36,_ZN4ksys17MessageReceiverExD0Ev
@ -92627,7 +92627,7 @@
0x00000071011f4884,sub_71011F4884,20,_ZN4ksys17MessageDispatcher9MainQueueD1Ev
0x00000071011f4898,sub_71011F4898,440,_ZN4ksys17MessageDispatcher19DoubleBufferedQueueD1Ev
0x00000071011f4a50,nullsub_4667,4,_ZN4ksys17MessageDispatcher6Queues11DummyLoggerD1Ev
0x00000071011f4a54,nullsub_4668,4,
0x00000071011f4a54,nullsub_4668,4,_ZN4ksys22IMessageBrokerRegister15IForEachContextD2Ev
0x00000071011f4a58,sub_71011F4A58,72,_ZN4ksys17MessageDispatcher9MainQueue10addMessageERKNS_7MessageE
0x00000071011f4aa0,sub_71011F4AA0,112,_ZN4ksys17MessageDispatcher9MainQueue12processQueueERNS_16MessageProcessorE
0x00000071011f4b10,nullsub_4669,4,_ZN4ksys17MessageDispatcher6Queues11DummyLogger3logERKNS_7MessageEb
@ -92645,23 +92645,23 @@
0x00000071011f51cc,GlobalMessage::x_0,344,_ZN4ksys17MessageDispatcher21deregisterTransceiverERNS_17MessageReceiverExE
0x00000071011f5324,GlobalMessage::x_1,124,_ZN4ksys17MessageDispatcher11sendMessageERKNS_16MesTransceiverIdES3_RKNS_11MessageTypeEPvb
0x00000071011f53a0,GlobalMessage::x_5,236,_ZN4ksys17MessageDispatcher29sendMessageOnProcessingThreadERKNS_16MesTransceiverIdES3_RKNS_11MessageTypeEPvb?
0x00000071011f548c,GlobalMessage::x_2,208,
0x00000071011f555c,GlobalMessage::x_3,268,
0x00000071011f548c,GlobalMessage::x_2,208,_ZN4ksys17MessageDispatcher11sendMessageERKNS_16MesTransceiverIdERNS_22IMessageBrokerRegisterERKNS_11MessageTypeEPvb
0x00000071011f555c,GlobalMessage::x_3,268,_ZN4ksys17MessageDispatcher29sendMessageOnProcessingThreadERKNS_16MesTransceiverIdERNS_22IMessageBrokerRegisterERKNS_11MessageTypeEPvb
0x00000071011f5668,GlobalMessage::x_4,248,_ZN4ksys17MessageDispatcher6updateEv?
0x00000071011f5760,GlobalMessage::rtti1,204,_ZNK4ksys17MessageDispatcher27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x00000071011f582c,GlobalMessage::rtti2,92,_ZNK4ksys17MessageDispatcher18getRuntimeTypeInfoEv
0x00000071011f5888,j__ZdlPv_1221,4,_ZN4ksys17MessageDispatcher6Queues11DummyLoggerD0Ev
0x00000071011f588c,sub_71011F588C,140,_ZNK4sead15RuntimeTypeInfo6DeriveIN4ksys21MessageDispatcherBaseEE9isDerivedEPKNS0_9InterfaceE
0x00000071011f5918,sub_71011F5918,240,_ZN4ksys17MessageDispatcher5QueueD1Ev
0x00000071011f5a08,sub_71011F5A08,240,_ZN4ksys17MessageDispatcher5QueueD0Ev
0x00000071011f5af8,sub_71011F5AF8,460,_ZN4ksys17MessageDispatcher5Queue10addMessageERKNS_7MessageE
0x00000071011f5cc4,sub_71011F5CC4,228,_ZN4ksys17MessageDispatcher5Queue12processQueueERNS_16MessageProcessorE
0x00000071011f5da8,sub_71011F5DA8,132,_ZN4ksys17MessageDispatcher5Queue5clearEv
0x00000071011f5918,sub_71011F5918,240,_ZN4ksys12MessageQueueD1Ev
0x00000071011f5a08,sub_71011F5A08,240,_ZN4ksys12MessageQueueD0Ev
0x00000071011f5af8,sub_71011F5AF8,460,_ZN4ksys12MessageQueue10addMessageERKNS_7MessageE
0x00000071011f5cc4,sub_71011F5CC4,228,_ZN4ksys12MessageQueue12processQueueERNS_16MessageProcessorE
0x00000071011f5da8,sub_71011F5DA8,132,_ZN4ksys12MessageQueue5clearEv
0x00000071011f5e2c,sub_71011F5E2C,52,_ZN4ksys17MessageDispatcher9MainQueueD0Ev
0x00000071011f5e60,j__ZdlPv_1222,4,
0x00000071011f5e64,sub_71011F5E64,116,
0x00000071011f5ed8,j__ZdlPv_1223,4,
0x00000071011f5edc,sub_71011F5EDC,116,
0x00000071011f5e60,j__ZdlPv_1222,4,_ZN4ksys17AddMessageContextD0Ev
0x00000071011f5e64,sub_71011F5E64,116,_ZN4ksys17AddMessageContext7processERKNS_16MesTransceiverIdE
0x00000071011f5ed8,j__ZdlPv_1223,4,_ZN4ksys21AddMessageMainContextD0Ev
0x00000071011f5edc,sub_71011F5EDC,116,_ZN4ksys21AddMessageMainContext7processERKNS_16MesTransceiverIdE
0x00000071011f5f50,sub_71011F5F50,20,_ZN4ksys21MessageDispatcherBaseC2Ev
0x00000071011f5f64,nullsub_4672,4,_ZN4ksys21MessageDispatcherBaseD1Ev
0x00000071011f5f68,j__ZdlPv_1224,4,_ZN4ksys21MessageDispatcherBaseD0Ev
@ -92684,15 +92684,15 @@
0x00000071011f65a4,getGlobalMessagePtr,36,_ZN4ksys22MessageTransceiverBaseC2Ev
0x00000071011f65c8,nullsub_4673,4,_ZN4ksys22MessageTransceiverBaseD1Ev
0x00000071011f65cc,j__ZdlPv_1225,4,_ZN4ksys22MessageTransceiverBaseD0Ev
0x00000071011f65d0,sub_71011F65D0,28,_ZNK4ksys22MessageTransceiverBase18checkGeneratorFlagEv
0x00000071011f65ec,sub_71011F65EC,28,_ZNK4ksys22MessageTransceiverBase21checkGeneratorCounterEv
0x00000071011f65d0,sub_71011F65D0,28,_ZNK4ksys22MessageTransceiverBase17checkReceiverFlagEv
0x00000071011f65ec,sub_71011F65EC,28,_ZNK4ksys22MessageTransceiverBase20checkReceiverCounterEv
0x00000071011f6608,sub_71011F6608,8,_ZN4ksys22MessageTransceiverBase2m2Ev
0x00000071011f6610,sub_71011F6610,8,_ZN4ksys22MessageTransceiverBase2m3Ev
0x00000071011f6618,sub_71011F6618,8,_ZN4ksys22MessageTransceiverBase2m4Ev
0x00000071011f6620,sub_71011F6620,8,_ZN4ksys22MessageTransceiverBase2m5Ev
0x00000071011f6628,getGlobalMessage,8,_ZN4ksys22MessageTransceiverBase13getDispatcherEv
0x00000071011f6630,GlobalMessage::setGlobalPtr_,16,_ZN4ksys22MessageTransceiverBase19setGlobalDispatcherEPNS_21MessageDispatcherBaseE
0x00000071011f6640,sub_71011F6640,16,
0x00000071011f6640,sub_71011F6640,16,_ZNK4ksys22MessageTransceiverBase11getRegisterERNS_14IMessageBrokerE
0x00000071011f6650,j_j_Struct1A::dtor_1,4,
0x00000071011f6654,sub_71011F6654,36,
0x00000071011f6678,sub_71011F6678,16,

Can't render this file because it is too large.

View File

@ -11,6 +11,8 @@ target_sources(uking PRIVATE
Thread/Message.h
Thread/MessageAck.cpp
Thread/MessageAck.h
Thread/MessageBroker.cpp
Thread/MessageBroker.h
Thread/MessageDispatcher.cpp
Thread/MessageDispatcher.h
Thread/MessageDispatcherBase.cpp

View File

@ -34,7 +34,7 @@ void* Message::getUserData() const {
}
u32 Message::getField48() const {
return _48;
return mBrokerId;
}
bool Message::shouldBeProcessed() const {
@ -56,7 +56,7 @@ void Message::setDestination(const MesTransceiverId& dest) {
}
void Message::setField48(const u32& v) {
_48 = v;
mBrokerId = v;
}
} // namespace ksys

View File

@ -50,7 +50,7 @@ public:
mDestination = other.getDestination();
mType = other.getType();
mUserData = other.getUserData();
_48 = other.getField48();
mBrokerId = other.getField48();
mDelayParams = other.mDelayParams;
mShouldAck = other.shouldAck();
return *this;
@ -76,7 +76,7 @@ public:
void reset() {
mType = {};
mUserData = {};
_48 = 0xffffffff;
mBrokerId = 0xffffffff;
mDelayParams = {};
mShouldAck = {};
mSource.reset();
@ -90,12 +90,14 @@ public:
bool isValid() const { return mDestination.isRegistered(); }
void setBrokerId_(u32 id) { mBrokerId = id; }
private:
MesTransceiverId mSource{};
MesTransceiverId mDestination{};
MessageType mType{};
void* mUserData{};
u32 _48 = 0xffffffff;
u32 mBrokerId = 0xffffffff;
DelayParams mDelayParams{};
bool mShouldAck = true;
};

View File

@ -0,0 +1,22 @@
#include "KingSystem/Utils/Thread/MessageBroker.h"
#include "KingSystem/Utils/Thread/MessageTransceiverBase.h"
namespace ksys {
IMessageBroker::IMessageBroker() = default;
IMessageBroker::~IMessageBroker() = default;
bool IMessageBroker::registerTransceiver(const MessageTransceiverBase& transceiver) {
return getRegister()->registerTransceiver(*transceiver.getId());
}
void IMessageBroker::deregisterTransceiver(const MessageTransceiverBase& transceiver) {
return getRegister()->deregisterTransceiver(*transceiver.getId());
}
int IMessageBroker::countTransceivers() {
return getRegister()->countTransceivers();
}
} // namespace ksys

View File

@ -0,0 +1,53 @@
#pragma once
#include <basis/seadTypes.h>
#include <prim/seadRuntimeTypeInfo.h>
namespace ksys {
class Message;
class MessageTransceiverBase;
class MessageQueue;
struct MesTransceiverId;
class IMessageBrokerRegister {
public:
struct IForEachContext {
virtual ~IForEachContext() = default;
virtual void process(const MesTransceiverId& id) = 0;
};
virtual ~IMessageBrokerRegister() = default;
virtual bool registerTransceiver(const MesTransceiverId& id) = 0;
virtual void deregisterTransceiver(const MesTransceiverId& id) = 0;
virtual void forEachRegistered(IForEachContext& context) = 0;
virtual void setId(const u32& id) = 0;
virtual const u32& getId() const = 0;
virtual int countTransceivers() const = 0;
};
class IMessageBroker {
public:
class SetIdArg {
SEAD_RTTI_BASE(SetIdArg)
public:
SetIdArg() = default;
explicit SetIdArg(u32 id) { setId(id); }
virtual ~SetIdArg() = default;
u32 getId() const { return mId; }
void setId(u32 id) { mId = id; }
private:
u32 mId{};
};
IMessageBroker();
virtual ~IMessageBroker();
virtual void setId(const SetIdArg& arg) = 0;
virtual IMessageBrokerRegister* getRegister() = 0;
bool registerTransceiver(const MessageTransceiverBase& transceiver);
void deregisterTransceiver(const MessageTransceiverBase& transceiver);
int countTransceivers();
};
} // namespace ksys

View File

@ -7,17 +7,18 @@
#include "KingSystem/Utils/HeapUtil.h"
#include "KingSystem/Utils/SafeDelete.h"
#include "KingSystem/Utils/Thread/Message.h"
#include "KingSystem/Utils/Thread/MessageBroker.h"
#include "KingSystem/Utils/Thread/MessageReceiverEx.h"
namespace ksys {
MessageDispatcher::Queue::Queue() = default;
MessageQueue::MessageQueue() = default;
MessageDispatcher::Queue::~Queue() {
Queue::clear();
MessageQueue::~MessageQueue() {
MessageQueue::clear();
}
Message* MessageDispatcher::Queue::findUnusedEntry() const {
Message* MessageQueue::findUnusedEntry() const {
for (Message& entry : mMessages) {
if (!entry.isValid())
return &entry;
@ -25,7 +26,7 @@ Message* MessageDispatcher::Queue::findUnusedEntry() const {
return nullptr;
}
bool MessageDispatcher::Queue::addMessage(const Message& message) {
bool MessageQueue::addMessage(const Message& message) {
if (!message.getSource().isRegistered())
return false;
@ -40,7 +41,7 @@ bool MessageDispatcher::Queue::addMessage(const Message& message) {
return true;
}
void MessageDispatcher::Queue::processQueue(MessageProcessor& processor) {
void MessageQueue::processQueue(MessageProcessor& processor) {
for (auto& message : mMessages) {
if (!message.isValid())
break;
@ -50,7 +51,7 @@ void MessageDispatcher::Queue::processQueue(MessageProcessor& processor) {
}
}
void MessageDispatcher::Queue::clear() {
void MessageQueue::clear() {
for (auto it = mMessages.begin(); it != mMessages.end(); ++it)
it->resetIfValid();
}
@ -228,6 +229,16 @@ bool MessageDispatcher::sendMessage(const MesTransceiverId& src, const MesTransc
return queues->getQueue().addMessage(message);
}
bool MessageDispatcher::Queues::sendMessageOnProcessingThread(const MesTransceiverId& src,
const MesTransceiverId& dest,
const MessageType& type,
void* user_data, bool ack) {
const auto message = Message{src, dest, type, user_data, {}, ack};
if (!isProcessing())
return false;
return mMainQueue.addMessage(message);
}
// NON_MATCHING: branching: deduplicated Message destructor call
bool MessageDispatcher::sendMessageOnProcessingThread(const MesTransceiverId& src,
const MesTransceiverId& dest,
@ -235,12 +246,78 @@ bool MessageDispatcher::sendMessageOnProcessingThread(const MesTransceiverId& sr
bool ack) {
if (!isProcessingOnCurrentThread())
return false;
return mQueues->sendMessageOnProcessingThread(src, dest, type, user_data, ack);
}
auto* queues = mQueues;
const auto message = Message{src, dest, type, user_data, {}, ack};
if (!queues->isProcessing())
struct AddMessageContext : IMessageBrokerRegister::IForEachContext {
AddMessageContext(MessageQueue* queue, Message* message) : queue(queue), message(message) {}
void process(const MesTransceiverId& id) override {
if (!id.isRegistered())
return;
message->setDestination(id);
result = queue->addMessage(*message);
}
MessageQueue* queue;
Message* message;
bool result = false;
};
bool MessageDispatcher::sendMessage(const MesTransceiverId& src, IMessageBrokerRegister& reg,
const MessageType& type, void* user_data, bool ack) {
auto queues = mQueues;
Message::DelayParams delay_params;
// This should probably be a Queues member function, but putting this here removes
// the need to include Message.h in the header.
return [&] {
auto message = Message{src, type, user_data, delay_params, ack};
message.setBrokerId_(reg.getId());
queues->getCritSection().lock();
AddMessageContext ctx{queues->getQueue().getQueue(), &message};
reg.forEachRegistered(ctx);
queues->getCritSection().unlock();
return ctx.result;
}();
}
struct AddMessageMainContext : IMessageBrokerRegister::IForEachContext {
AddMessageMainContext(MessageDispatcher::MainQueue* queue, Message* message)
: queue(queue), message(message) {}
void process(const MesTransceiverId& id) override {
if (!id.isRegistered())
return;
message->setDestination(id);
result = queue->addMessage(*message);
}
MessageDispatcher::MainQueue* queue;
Message* message;
bool result = false;
};
bool MessageDispatcher::sendMessageOnProcessingThread(const MesTransceiverId& src,
IMessageBrokerRegister& reg,
const MessageType& type, void* user_data,
bool ack) {
if (!isProcessingOnCurrentThread())
return false;
return queues->getMainQueue().addMessage(message);
auto queues = mQueues;
Message::DelayParams delay_params;
return [&] {
if (!queues->isProcessing())
return false;
auto message = Message{src, type, user_data, delay_params, ack};
message.setBrokerId_(reg.getId());
AddMessageMainContext ctx{&queues->getMainQueue(), &message};
reg.forEachRegistered(ctx);
return ctx.result;
}();
}
void MessageDispatcher::Queues::process() {

View File

@ -22,6 +22,20 @@ class Message;
class MessageProcessor;
struct MesTransceiverId;
class MessageQueue {
public:
MessageQueue();
virtual ~MessageQueue();
virtual bool addMessage(const Message& message);
virtual void processQueue(MessageProcessor& processor);
virtual void clear();
private:
Message* findUnusedEntry() const;
util::UniqueArrayPtr<Message, 3000> mMessages;
};
class MessageDispatcher : public MessageDispatcherBase {
SEAD_SINGLETON_DISPOSER(MessageDispatcher)
SEAD_RTTI_OVERRIDE(MessageDispatcher, MessageDispatcherBase)
@ -47,24 +61,14 @@ public:
const MessageType& type, void* user_data, bool ack) override;
bool sendMessageOnProcessingThread(const MesTransceiverId& src, const MesTransceiverId& dest,
const MessageType& type, void* user_data, bool ack) override;
void m_8() override;
void m_9() override;
bool sendMessage(const MesTransceiverId& src, IMessageBrokerRegister& reg,
const MessageType& type, void* user_data, bool ack) override;
bool sendMessageOnProcessingThread(const MesTransceiverId& src, IMessageBrokerRegister& reg,
const MessageType& type, void* user_data, bool ack) override;
void update() override;
private:
class Queue {
public:
Queue();
virtual ~Queue();
virtual bool addMessage(const Message& message);
virtual void processQueue(MessageProcessor& processor);
virtual void clear();
private:
Message* findUnusedEntry() const;
util::UniqueArrayPtr<Message, 3000> mMessages;
};
friend struct AddMessageMainContext;
class DoubleBufferedQueue {
public:
@ -74,13 +78,14 @@ private:
void clear();
void processQueue(MessageProcessor& processor);
void swapBuffer() { mActiveIdx ^= 1; }
MessageQueue* getQueue() { return &mBuffer[mActiveIdx ^ 1]; }
private:
u32 mActiveIdx = 1;
Queue mBuffer[2];
MessageQueue mBuffer[2];
};
class MainQueue final {
class MainQueue {
public:
MainQueue();
virtual ~MainQueue();
@ -104,6 +109,9 @@ private:
MainQueue& getMainQueue() { return mMainQueue; }
bool isProcessing() const { return mIsProcessing; }
void process();
bool sendMessageOnProcessingThread(const MesTransceiverId& src,
const MesTransceiverId& dest, const MessageType& type,
void* user_data, bool ack);
private:
struct DummyLogger : public MessageProcessor::Logger {

View File

@ -4,6 +4,7 @@
namespace ksys {
class IMessageBrokerRegister;
class MessageReceiverEx;
struct MesTransceiverId;
struct MessageType;
@ -22,9 +23,11 @@ public:
const MesTransceiverId& dest,
const MessageType& type, void* user_data,
bool ack) = 0;
// TODO
virtual void m_8() = 0;
virtual void m_9() = 0;
virtual bool sendMessage(const MesTransceiverId& src, IMessageBrokerRegister& reg,
const MessageType& type, void* user_data, bool ack) = 0;
virtual bool sendMessageOnProcessingThread(const MesTransceiverId& src,
IMessageBrokerRegister& reg, const MessageType& type,
void* user_data, bool ack) = 0;
virtual void update() = 0;
protected:

View File

@ -1,4 +1,5 @@
#include "KingSystem/Utils/Thread/MessageTransceiverBase.h"
#include "KingSystem/Utils/Thread/MessageBroker.h"
#include "KingSystem/Utils/Thread/MessageReceiverEx.h"
namespace ksys {
@ -9,12 +10,12 @@ MessageTransceiverBase::MessageTransceiverBase() = default;
MessageTransceiverBase::~MessageTransceiverBase() = default;
bool MessageTransceiverBase::checkGeneratorFlag() const {
return getGenerator()->checkFlag();
bool MessageTransceiverBase::checkReceiverFlag() const {
return getReceiver()->checkFlag();
}
bool MessageTransceiverBase::checkGeneratorCounter() const {
return getGenerator()->checkCounter();
bool MessageTransceiverBase::checkReceiverCounter() const {
return getReceiver()->checkCounter();
}
bool MessageTransceiverBase::m2() {
@ -41,4 +42,8 @@ void MessageTransceiverBase::setGlobalDispatcher(MessageDispatcherBase* dispatch
sDispatcher = dispatcher;
}
IMessageBrokerRegister* MessageTransceiverBase::getRegister(IMessageBroker& broker) const {
return broker.getRegister();
}
} // namespace ksys

View File

@ -4,6 +4,8 @@
namespace ksys {
class IMessageBroker;
class IMessageBrokerRegister;
class MessageDispatcherBase;
struct MesTransceiverId;
class MessageReceiverEx;
@ -12,14 +14,16 @@ class MessageTransceiverBase {
public:
MessageTransceiverBase();
virtual ~MessageTransceiverBase();
bool checkGeneratorFlag() const;
bool checkGeneratorCounter() const;
bool checkReceiverFlag() const;
bool checkReceiverCounter() const;
virtual bool m2();
virtual bool m3();
virtual bool m4();
virtual bool m5();
virtual MessageReceiverEx* getGenerator() const = 0;
virtual MessageReceiverEx* getReceiver() const = 0;
MessageDispatcherBase* getDispatcher();
MesTransceiverId* getId() const { return mId; }
IMessageBrokerRegister* getRegister(IMessageBroker& broker) const;
static void setGlobalDispatcher(MessageDispatcherBase* dispatcher);