Refactor message handling: remove MessageDispatcher, MessageFilter, and related classes to streamline codebase
This commit is contained in:
@@ -1,131 +0,0 @@
|
||||
#include "message.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace app {
|
||||
namespace core {
|
||||
|
||||
#pragma mark - MessageDispatcher
|
||||
|
||||
void MessageDispatcher::RegisterListener(const std::string& message_type,
|
||||
IMessageListener* listener) {
|
||||
listeners_[message_type].push_back(listener);
|
||||
}
|
||||
|
||||
void MessageDispatcher::UnregisterListener(const std::string& message_type,
|
||||
IMessageListener* listener) {
|
||||
auto& listener_list = listeners_[message_type];
|
||||
listener_list.erase(
|
||||
std::remove(listener_list.begin(), listener_list.end(), listener),
|
||||
listener_list.end());
|
||||
}
|
||||
|
||||
void MessageDispatcher::RegisterProtocol(IMessageProtocol* protocol) {
|
||||
protocols_.push_back(protocol);
|
||||
}
|
||||
|
||||
void MessageDispatcher::RegisterFilteredListener(
|
||||
const std::string& message_type, IMessageListener* listener,
|
||||
std::unique_ptr<MessageFilter> filter) {
|
||||
filtered_listeners_[message_type].push_back({listener, std::move(filter)});
|
||||
}
|
||||
|
||||
void MessageDispatcher::BindHandler(const std::string& message_type,
|
||||
MessageHandler handler) {
|
||||
handlers_[message_type].push_back(handler);
|
||||
}
|
||||
|
||||
void MessageDispatcher::SendMessage(const Message& message) {
|
||||
const auto& listener_list = listeners_[message.type];
|
||||
for (auto listener : listener_list) {
|
||||
listener->OnMessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageDispatcher::DispatchMessage(const Message& message) {
|
||||
for (auto protocol : protocols_) {
|
||||
if (protocol->CanHandleMessage(message)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto& listener_list = listeners_[message.type];
|
||||
for (auto listener : listener_list) {
|
||||
listener->OnMessageReceived(message);
|
||||
}
|
||||
|
||||
const auto& filtered_listener_list = filtered_listeners_[message.type];
|
||||
for (auto& listener : filtered_listener_list) {
|
||||
if (listener.filter->ShouldReceiveMessage(message)) {
|
||||
listener.listener->OnMessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
const auto& handler_list = handlers_[message.type];
|
||||
for (auto& handler : handler_list) {
|
||||
handler(message);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - AsyncMessageDispatcher
|
||||
|
||||
void AsyncMessageDispatcher::Start() {
|
||||
// Start a new thread and run the message loop.
|
||||
|
||||
}
|
||||
|
||||
void AsyncMessageDispatcher::Stop() {
|
||||
// Stop the message loop and join the thread.
|
||||
}
|
||||
|
||||
void AsyncMessageDispatcher::EnqueueMessage(const Message& message) {
|
||||
// Enqueue a message to the message loop.
|
||||
}
|
||||
|
||||
void AsyncMessageDispatcher::DispatchLoop() {
|
||||
// Dispatch messages in a loop.
|
||||
}
|
||||
|
||||
#pragma mark - MessageFilter
|
||||
|
||||
template <typename T>
|
||||
void Swizzler::Swizzle(T* instance, void (T::*original_method)(),
|
||||
std::function<void()> new_method) {
|
||||
original_methods_[instance] = original_method;
|
||||
swizzled_methods_[instance] = new_method;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Swizzler::CallOriginal(T* instance) {
|
||||
auto it = original_methods_.find(instance);
|
||||
if (it != original_methods_.end()) {
|
||||
(instance->*(it->second))();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Swizzler::CallSwizzled(T* instance) {
|
||||
auto it = swizzled_methods_.find(instance);
|
||||
if (it != swizzled_methods_.end()) {
|
||||
it->second();
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - ObjectFactory
|
||||
|
||||
template <typename T>
|
||||
void ObjectFactory::RegisterType(const std::string& type_name) {
|
||||
creators_[type_name] = []() { return std::make_unique<T>(); };
|
||||
}
|
||||
|
||||
std::unique_ptr<Reflectable> ObjectFactory::CreateObject(
|
||||
const std::string& object_name) const {
|
||||
auto it = creators_.find(object_name);
|
||||
if (it != creators_.end()) {
|
||||
return it->second();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace app
|
||||
} // namespace yaze
|
||||
@@ -1,134 +0,0 @@
|
||||
#ifndef YAZE_APP_CORE_MESSAGE_H
|
||||
#define YAZE_APP_CORE_MESSAGE_H
|
||||
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace app {
|
||||
namespace core {
|
||||
|
||||
struct Message {
|
||||
std::string type;
|
||||
void* sender;
|
||||
std::any payload;
|
||||
|
||||
Message() = default;
|
||||
Message(const std::string& type, void* sender, const std::any& payload)
|
||||
: type(type), sender(sender), payload(payload) {}
|
||||
};
|
||||
|
||||
class IMessageListener {
|
||||
public:
|
||||
virtual ~IMessageListener() = default;
|
||||
virtual absl::Status OnMessageReceived(const Message& message) = 0;
|
||||
};
|
||||
|
||||
class IMessageProtocol {
|
||||
public:
|
||||
virtual ~IMessageProtocol() = default;
|
||||
virtual bool CanHandleMessage(const Message& message) const = 0;
|
||||
};
|
||||
|
||||
class MessageFilter {
|
||||
public:
|
||||
virtual ~MessageFilter() = default;
|
||||
virtual bool ShouldReceiveMessage(const Message& message) const = 0;
|
||||
};
|
||||
|
||||
using MessageHandler = std::function<void(const Message&)>;
|
||||
|
||||
class MessageDispatcher {
|
||||
public:
|
||||
void RegisterListener(const std::string& message_type,
|
||||
IMessageListener* listener);
|
||||
void UnregisterListener(const std::string& message_type,
|
||||
IMessageListener* listener);
|
||||
void RegisterProtocol(IMessageProtocol* protocol);
|
||||
void RegisterFilteredListener(const std::string& message_type,
|
||||
IMessageListener* listener,
|
||||
std::unique_ptr<MessageFilter> filter);
|
||||
void BindHandler(const std::string& message_type, MessageHandler handler);
|
||||
void SendMessage(const Message& message);
|
||||
void DispatchMessage(const Message& message);
|
||||
|
||||
private:
|
||||
struct ListenerWithFilter {
|
||||
IMessageListener* listener;
|
||||
std::unique_ptr<MessageFilter> filter;
|
||||
};
|
||||
std::unordered_map<std::string, std::vector<IMessageListener*>> listeners_;
|
||||
std::unordered_map<std::string, std::vector<ListenerWithFilter>>
|
||||
filtered_listeners_;
|
||||
std::unordered_map<std::string, std::vector<MessageHandler>> handlers_;
|
||||
std::vector<IMessageProtocol*> protocols_;
|
||||
};
|
||||
|
||||
class AsyncMessageDispatcher : public MessageDispatcher {
|
||||
public:
|
||||
void Start();
|
||||
void Stop();
|
||||
void EnqueueMessage(const Message& message);
|
||||
|
||||
private:
|
||||
void DispatchLoop();
|
||||
std::queue<Message> messageQueue_;
|
||||
std::mutex queueMutex_;
|
||||
std::thread dispatchThread_;
|
||||
bool running_ = false;
|
||||
};
|
||||
|
||||
class Swizzler {
|
||||
public:
|
||||
template <typename T>
|
||||
void Swizzle(T* instance, void (T::*original_method)(),
|
||||
std::function<void()> new_method);
|
||||
|
||||
template <typename T>
|
||||
void CallOriginal(T* instance);
|
||||
|
||||
template <typename T>
|
||||
void CallSwizzled(T* instance);
|
||||
|
||||
private:
|
||||
std::unordered_map<void*, std::function<void()>> swizzled_methods_;
|
||||
std::unordered_map<void*, void*> original_methods_;
|
||||
};
|
||||
|
||||
class Reflectable {
|
||||
public:
|
||||
virtual ~Reflectable() = default;
|
||||
virtual std::string GetTypeName() const = 0;
|
||||
virtual std::vector<std::string> GetPropertyNames() const = 0;
|
||||
virtual std::any GetPropertyValue(const std::string& property_name) const = 0;
|
||||
virtual void SetPropertyValue(const std::string& property_name,
|
||||
const std::any& value) = 0;
|
||||
virtual std::any InvokeMethod(const std::string& method_name,
|
||||
const std::vector<std::any>& args) = 0;
|
||||
};
|
||||
|
||||
class ObjectFactory {
|
||||
public:
|
||||
template <typename T>
|
||||
void RegisterType(const std::string& type_name);
|
||||
|
||||
std::unique_ptr<Reflectable> CreateObject(const std::string& type_name) const;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::function<std::unique_ptr<Reflectable>()>>
|
||||
creators_;
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
} // namespace app
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APP_CORE_MESSAGE_H
|
||||
@@ -1,124 +0,0 @@
|
||||
#include "core/message.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace yaze {
|
||||
namespace test {
|
||||
namespace message {
|
||||
|
||||
using app::core::IMessageListener;
|
||||
using app::core::IMessageProtocol;
|
||||
using app::core::Message;
|
||||
using app::core::MessageDispatcher;
|
||||
using app::core::MessageFilter;
|
||||
|
||||
class TestListener : public IMessageListener {
|
||||
public:
|
||||
~TestListener() = default;
|
||||
|
||||
absl::Status OnMessageReceived(const Message& message) override {
|
||||
last_message_ = message;
|
||||
message_count_++;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
const Message& last_message() const { return last_message_; }
|
||||
int message_count() const { return message_count_; }
|
||||
|
||||
private:
|
||||
Message last_message_;
|
||||
int message_count_ = 0;
|
||||
};
|
||||
|
||||
class TestProtocol : public IMessageProtocol {
|
||||
public:
|
||||
bool CanHandleMessage(const Message& message) const override {
|
||||
return message.type == "TestMessage";
|
||||
}
|
||||
};
|
||||
|
||||
class TestFilter : public MessageFilter {
|
||||
public:
|
||||
bool ShouldReceiveMessage(const Message& message) const override {
|
||||
return std::any_cast<int>(message.payload) > 10;
|
||||
}
|
||||
};
|
||||
|
||||
class MessageDispatcherTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
message_count_ = 0;
|
||||
protocol_ = std::make_unique<TestProtocol>();
|
||||
filter_ = std::make_unique<TestFilter>();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
protocol_.reset();
|
||||
filter_.reset();
|
||||
}
|
||||
|
||||
int message_count_ = 0;
|
||||
int message_count1_ = 0;
|
||||
int message_count2_ = 0;
|
||||
TestListener listener1_;
|
||||
TestListener listener2_;
|
||||
std::unique_ptr<TestProtocol> protocol_;
|
||||
std::unique_ptr<TestFilter> filter_;
|
||||
};
|
||||
TEST_F(MessageDispatcherTest, RegisterAndSendMessage) {
|
||||
MessageDispatcher dispatcher;
|
||||
|
||||
dispatcher.RegisterListener("TestMessage", &listener1_);
|
||||
|
||||
Message message("TestMessage", nullptr, 42);
|
||||
dispatcher.SendMessage(message);
|
||||
|
||||
EXPECT_EQ(listener1_.message_count(), 1);
|
||||
EXPECT_EQ(std::any_cast<int>(listener1_.last_message().payload), 42);
|
||||
}
|
||||
|
||||
TEST_F(MessageDispatcherTest, UnregisterListener) {
|
||||
MessageDispatcher dispatcher;
|
||||
|
||||
dispatcher.RegisterListener("TestMessage", &listener1_);
|
||||
dispatcher.UnregisterListener("TestMessage", &listener1_);
|
||||
|
||||
Message message("TestMessage", nullptr, 42);
|
||||
dispatcher.SendMessage(message);
|
||||
|
||||
EXPECT_EQ(listener1_.message_count(), 0);
|
||||
}
|
||||
|
||||
TEST_F(MessageDispatcherTest, MultipleListeners) {
|
||||
MessageDispatcher dispatcher;
|
||||
|
||||
dispatcher.RegisterListener("TestMessage", &listener1_);
|
||||
dispatcher.RegisterListener("TestMessage", &listener2_);
|
||||
|
||||
Message message("TestMessage", nullptr, 42);
|
||||
dispatcher.SendMessage(message);
|
||||
|
||||
EXPECT_EQ(listener1_.message_count(), 1);
|
||||
EXPECT_EQ(listener2_.message_count(), 1);
|
||||
EXPECT_EQ(std::any_cast<int>(listener1_.last_message().payload), 42);
|
||||
EXPECT_EQ(std::any_cast<int>(listener2_.last_message().payload), 42);
|
||||
}
|
||||
|
||||
TEST_F(MessageDispatcherTest, FilteredMessageHandling) {
|
||||
MessageDispatcher dispatcher;
|
||||
|
||||
dispatcher.RegisterFilteredListener("TestMessage", &listener1_,
|
||||
std::move(filter_));
|
||||
|
||||
Message valid_message("TestMessage", nullptr, 15);
|
||||
dispatcher.DispatchMessage(valid_message);
|
||||
EXPECT_EQ(listener1_.message_count(), 1);
|
||||
|
||||
Message invalid_message("TestMessage", nullptr, 5);
|
||||
dispatcher.DispatchMessage(invalid_message);
|
||||
EXPECT_EQ(listener1_.message_count(), 1);
|
||||
}
|
||||
|
||||
} // namespace message
|
||||
} // namespace test
|
||||
} // namespace yaze
|
||||
Reference in New Issue
Block a user