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