Extra2D/tests/test_event_bus.cpp

535 lines
14 KiB
C++

#include <gtest/gtest.h>
#include <event/event_bus.h>
#include <event/events.h>
using namespace extra2d;
using extra2d::event::broadcast;
using extra2d::event::Listener;
// ============================================================================
// 基础事件测试
// ============================================================================
TEST(EventBus, BasicBroadcast) {
int received = 0;
{
Listener<events::OnInit> listener;
listener.bind([&received]() {
received++;
});
// 广播事件
broadcast<events::OnInit>();
EXPECT_EQ(1, received);
// 再次广播
broadcast<events::OnInit>();
EXPECT_EQ(2, received);
}
// 监听器销毁后不应再接收
broadcast<events::OnInit>();
EXPECT_EQ(2, received);
}
TEST(EventBus, MultipleListeners) {
int count1 = 0, count2 = 0, count3 = 0;
Listener<events::OnUpdate> listener1;
listener1.bind([&count1](float dt) {
count1++;
});
Listener<events::OnUpdate> listener2;
listener2.bind([&count2](float dt) {
count2++;
});
Listener<events::OnUpdate> listener3;
listener3.bind([&count3](float dt) {
count3++;
});
broadcast<events::OnUpdate>(0.016f);
EXPECT_EQ(1, count1);
EXPECT_EQ(1, count2);
EXPECT_EQ(1, count3);
}
TEST(EventBus, ListenerEnableDisable) {
int count = 0;
Listener<events::OnInit> listener;
listener.bind([&count]() {
count++;
});
// 默认启用
broadcast<events::OnInit>();
EXPECT_EQ(1, count);
// 禁用
listener.disable();
EXPECT_FALSE(listener.isEnabled());
broadcast<events::OnInit>();
EXPECT_EQ(1, count); // 不应增加
// 重新启用
listener.enable();
EXPECT_TRUE(listener.isEnabled());
broadcast<events::OnInit>();
EXPECT_EQ(2, count);
}
TEST(EventBus, ListenerReset) {
int count = 0;
Listener<events::OnInit> listener;
listener.bind([&count]() {
count++;
});
broadcast<events::OnInit>();
EXPECT_EQ(1, count);
// 重置回调
listener.reset();
broadcast<events::OnInit>();
EXPECT_EQ(1, count); // 不应增加
}
// ============================================================================
// 带参数事件测试
// ============================================================================
TEST(EventBus, EventWithParameters) {
float receivedDt = 0.0f;
Listener<events::OnUpdate> listener;
listener.bind([&receivedDt](float dt) {
receivedDt = dt;
});
broadcast<events::OnUpdate>(0.016f);
EXPECT_NEAR(0.016f, receivedDt, 0.0001f);
broadcast<events::OnUpdate>(0.033f);
EXPECT_NEAR(0.033f, receivedDt, 0.0001f);
}
TEST(EventBus, EventWithMultipleParameters) {
int receivedWidth = 0, receivedHeight = 0;
Listener<events::OnResize> listener;
listener.bind([&receivedWidth, &receivedHeight](int32 width, int32 height) {
receivedWidth = width;
receivedHeight = height;
});
broadcast<events::OnResize>(1920, 1080);
EXPECT_EQ(1920, receivedWidth);
EXPECT_EQ(1080, receivedHeight);
broadcast<events::OnResize>(1280, 720);
EXPECT_EQ(1280, receivedWidth);
EXPECT_EQ(720, receivedHeight);
}
// ============================================================================
// 不同事件类型测试
// ============================================================================
TEST(EventBus, DifferentEventTypes) {
int initCount = 0;
int updateCount = 0;
int shutdownCount = 0;
Listener<events::OnInit> listener1;
listener1.bind([&initCount]() {
initCount++;
});
Listener<events::OnUpdate> listener2;
listener2.bind([&updateCount](float dt) {
updateCount++;
});
Listener<events::OnShutdown> listener3;
listener3.bind([&shutdownCount]() {
shutdownCount++;
});
// 广播不同类型的事件
broadcast<events::OnInit>();
EXPECT_EQ(1, initCount);
EXPECT_EQ(0, updateCount);
EXPECT_EQ(0, shutdownCount);
broadcast<events::OnUpdate>(0.016f);
EXPECT_EQ(1, initCount);
EXPECT_EQ(1, updateCount);
EXPECT_EQ(0, shutdownCount);
broadcast<events::OnShutdown>();
EXPECT_EQ(1, initCount);
EXPECT_EQ(1, updateCount);
EXPECT_EQ(1, shutdownCount);
}
// ============================================================================
// 监听器生命周期测试
// ============================================================================
TEST(EventBus, ListenerAutoUnregister) {
int count = 0;
{
Listener<events::OnInit> listener;
listener.bind([&count]() {
count++;
});
broadcast<events::OnInit>();
EXPECT_EQ(1, count);
} // listener 在这里销毁
// 再次广播,不应触发
broadcast<events::OnInit>();
EXPECT_EQ(1, count);
}
TEST(EventBus, ListenerOrder) {
std::vector<int> order;
Listener<events::OnInit> listener1;
listener1.bind([&order]() {
order.push_back(1);
});
Listener<events::OnInit> listener2;
listener2.bind([&order]() {
order.push_back(2);
});
Listener<events::OnInit> listener3;
listener3.bind([&order]() {
order.push_back(3);
});
broadcast<events::OnInit>();
EXPECT_EQ(3, order.size());
EXPECT_EQ(1, order[0]);
EXPECT_EQ(2, order[1]);
EXPECT_EQ(3, order[2]);
}
// ============================================================================
// 复杂场景测试
// ============================================================================
TEST(EventBus, AddListenerDuringBroadcast) {
// 这个测试验证在广播期间添加监听器的行为
int count1 = 0;
int count2 = 0;
Listener<events::OnInit>* listener2 = nullptr;
Listener<events::OnInit> listener1;
listener1.bind([&]() {
count1++;
// 在回调中创建新监听器
if (!listener2) {
listener2 = new Listener<events::OnInit>();
listener2->bind([&count2]() {
count2++;
});
}
});
broadcast<events::OnInit>();
EXPECT_EQ(1, count1);
// 新监听器在当前广播中不应被触发
EXPECT_EQ(0, count2);
// 下一次广播,新监听器应该被触发
broadcast<events::OnInit>();
EXPECT_EQ(2, count1);
EXPECT_EQ(1, count2);
delete listener2;
}
TEST(EventBus, RemoveListenerDuringBroadcast) {
int count1 = 0, count2 = 0, count3 = 0;
Listener<events::OnInit> listener1;
listener1.bind([&]() {
count1++;
});
{
Listener<events::OnInit> listener2;
listener2.bind([&]() {
count2++;
});
Listener<events::OnInit> listener3;
listener3.bind([&]() {
count3++;
});
broadcast<events::OnInit>();
EXPECT_EQ(1, count1);
EXPECT_EQ(1, count2);
EXPECT_EQ(1, count3);
} // listener2 和 listener3 在这里销毁
// 再次广播
broadcast<events::OnInit>();
EXPECT_EQ(2, count1);
EXPECT_EQ(1, count2); // 不应增加
EXPECT_EQ(1, count3); // 不应增加
}
// ============================================================================
// 输入事件测试
// ============================================================================
TEST(EventBus, InputEvents) {
int keyDownCode = -1;
int keyUpCode = -1;
int mouseButton = -1;
int mouseX = -1, mouseY = -1;
Listener<events::OnKeyDown> keyDownListener;
keyDownListener.bind([&keyDownCode](int32 key) {
keyDownCode = key;
});
Listener<events::OnKeyUp> keyUpListener;
keyUpListener.bind([&keyUpCode](int32 key) {
keyUpCode = key;
});
Listener<events::OnMouseDown> mouseDownListener;
mouseDownListener.bind([&mouseButton, &mouseX, &mouseY](int32 button, int32 x, int32 y) {
mouseButton = button;
mouseX = x;
mouseY = y;
});
// 模拟输入事件
broadcast<events::OnKeyDown>(65); // 'A' key
EXPECT_EQ(65, keyDownCode);
broadcast<events::OnKeyUp>(65);
EXPECT_EQ(65, keyUpCode);
broadcast<events::OnMouseDown>(0, 100, 200); // 左键点击
EXPECT_EQ(0, mouseButton);
EXPECT_EQ(100, mouseX);
EXPECT_EQ(200, mouseY);
}
TEST(EventBus, MouseMoveEvent) {
int receivedX = -1, receivedY = -1;
Listener<events::OnMouseMove> listener;
listener.bind([&receivedX, &receivedY](int32 x, int32 y) {
receivedX = x;
receivedY = y;
});
broadcast<events::OnMouseMove>(500, 300);
EXPECT_EQ(500, receivedX);
EXPECT_EQ(300, receivedY);
}
TEST(EventBus, MouseWheelEvent) {
int receivedDelta = 0;
Listener<events::OnMouseWheel> listener;
listener.bind([&receivedDelta](int32 delta) {
receivedDelta = delta;
});
broadcast<events::OnMouseWheel>(120);
EXPECT_EQ(120, receivedDelta);
broadcast<events::OnMouseWheel>(-120);
EXPECT_EQ(-120, receivedDelta);
}
// ============================================================================
// 窗口事件测试
// ============================================================================
TEST(EventBus, WindowEvents) {
bool focusReceived = false;
bool blurReceived = false;
bool showReceived = false;
bool hideReceived = false;
bool closeReceived = false;
int resizeWidth = 0, resizeHeight = 0;
Listener<events::OnFocus> focusListener;
focusListener.bind([&focusReceived]() {
focusReceived = true;
});
Listener<events::OnBlur> blurListener;
blurListener.bind([&blurReceived]() {
blurReceived = true;
});
Listener<events::OnShow> showListener;
showListener.bind([&showReceived]() {
showReceived = true;
});
Listener<events::OnHide> hideListener;
hideListener.bind([&hideReceived]() {
hideReceived = true;
});
Listener<events::OnClose> closeListener;
closeListener.bind([&closeReceived]() {
closeReceived = true;
});
Listener<events::OnResize> resizeListener;
resizeListener.bind([&resizeWidth, &resizeHeight](int32 width, int32 height) {
resizeWidth = width;
resizeHeight = height;
});
broadcast<events::OnFocus>();
EXPECT_TRUE(focusReceived);
broadcast<events::OnBlur>();
EXPECT_TRUE(blurReceived);
broadcast<events::OnShow>();
EXPECT_TRUE(showReceived);
broadcast<events::OnHide>();
EXPECT_TRUE(hideReceived);
broadcast<events::OnClose>();
EXPECT_TRUE(closeReceived);
broadcast<events::OnResize>(800, 600);
EXPECT_EQ(800, resizeWidth);
EXPECT_EQ(600, resizeHeight);
}
// ============================================================================
// 触摸事件测试
// ============================================================================
TEST(EventBus, TouchEvents) {
int touchId = -1;
int touchX = -1, touchY = -1;
Listener<events::OnTouchBegin> touchBeginListener;
touchBeginListener.bind([&touchId, &touchX, &touchY](int32 id, int32 x, int32 y) {
touchId = id;
touchX = x;
touchY = y;
});
broadcast<events::OnTouchBegin>(0, 100, 200);
EXPECT_EQ(0, touchId);
EXPECT_EQ(100, touchX);
EXPECT_EQ(200, touchY);
Listener<events::OnTouchMove> touchMoveListener;
touchMoveListener.bind([&touchId, &touchX, &touchY](int32 id, int32 x, int32 y) {
touchId = id;
touchX = x;
touchY = y;
});
broadcast<events::OnTouchMove>(0, 150, 250);
EXPECT_EQ(0, touchId);
EXPECT_EQ(150, touchX);
EXPECT_EQ(250, touchY);
Listener<events::OnTouchEnd> touchEndListener;
touchEndListener.bind([&touchId, &touchX, &touchY](int32 id, int32 x, int32 y) {
touchId = id;
touchX = x;
touchY = y;
});
broadcast<events::OnTouchEnd>(0, 150, 250);
EXPECT_EQ(0, touchId);
EXPECT_EQ(150, touchX);
EXPECT_EQ(250, touchY);
}
// ============================================================================
// 游戏手柄事件测试
// ============================================================================
TEST(EventBus, GamepadEvents) {
int connectedDeviceId = -1;
int disconnectedDeviceId = -1;
Listener<events::OnGamepadConnect> connectListener;
connectListener.bind([&connectedDeviceId](int32 deviceId) {
connectedDeviceId = deviceId;
});
Listener<events::OnGamepadDisconnect> disconnectListener;
disconnectListener.bind([&disconnectedDeviceId](int32 deviceId) {
disconnectedDeviceId = deviceId;
});
broadcast<events::OnGamepadConnect>(0);
EXPECT_EQ(0, connectedDeviceId);
broadcast<events::OnGamepadDisconnect>(0);
EXPECT_EQ(0, disconnectedDeviceId);
}
// ============================================================================
// 性能测试
// ============================================================================
TEST(EventBus, HighFrequencyBroadcast) {
const int iterations = 10000;
int count = 0;
Listener<events::OnUpdate> listener;
listener.bind([&count](float dt) {
count++;
});
for (int i = 0; i < iterations; i++) {
broadcast<events::OnUpdate>(0.016f);
}
EXPECT_EQ(iterations, count);
}
TEST(EventBus, ManyListeners) {
const int listenerCount = 100;
int totalCount = 0;
std::vector<std::unique_ptr<Listener<events::OnInit>>> listeners;
for (int i = 0; i < listenerCount; i++) {
auto listener = std::make_unique<Listener<events::OnInit>>();
listener->bind([&totalCount]() {
totalCount++;
});
listeners.push_back(std::move(listener));
}
broadcast<events::OnInit>();
EXPECT_EQ(listenerCount, totalCount);
}