mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
The new system allows to register all function objects as Input::Handler not only function pointers. To not get dangling references a handler is unsubscribed on it's destruction. The order in with the handlers are executed has to be specified by the slot-argument, instead of the reverse order of registration.
168 lines
4.3 KiB
C++
168 lines
4.3 KiB
C++
/* Copyright (C) 2026 Wildfire Games.
|
|
* This file is part of 0 A.D.
|
|
*
|
|
* 0 A.D. is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 0 A.D. is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "lib/self_test.h"
|
|
|
|
#include "lib/external_libraries/libsdl.h"
|
|
#include "ps/Input.h"
|
|
|
|
#include <iterator>
|
|
|
|
class TestInput : public CxxTest::TestSuite
|
|
{
|
|
static std::uint32_t GetEventType(const int numevents)
|
|
{
|
|
std::uint32_t eventType{SDL_RegisterEvents(numevents)};
|
|
TS_ASSERT_DIFFERS(eventType, std::numeric_limits<std::uint32_t>::max());
|
|
TS_ASSERT_STR_EQUALS(SDL_GetError(), "");
|
|
return eventType;
|
|
}
|
|
|
|
static SDL_Event MakeEvent(const std::uint32_t eventType)
|
|
{
|
|
SDL_Event ev{};
|
|
ev.type = eventType;
|
|
return ev;
|
|
}
|
|
|
|
static void PushEvent(const std::uint32_t eventType)
|
|
{
|
|
SDL_Event ev{MakeEvent(eventType)};
|
|
TS_ASSERT_EQUALS(SDL_PushEvent(&ev), 1);
|
|
TS_ASSERT_STR_EQUALS(SDL_GetError(), "");
|
|
}
|
|
|
|
static void PushPriorityEvent(Input::Manager& manager, const std::uint32_t eventType)
|
|
{
|
|
const SDL_Event ev{MakeEvent(eventType)};
|
|
manager.PushPriorityEvent(ev);
|
|
}
|
|
|
|
public:
|
|
void setUp()
|
|
{
|
|
SDL_Init(SDL_INIT_EVENTS);
|
|
}
|
|
|
|
void tearDown()
|
|
{
|
|
SDL_Quit();
|
|
}
|
|
|
|
void test_NoEvent()
|
|
{
|
|
Input::Manager manager;
|
|
auto range = manager.PollEvents();
|
|
TS_ASSERT_EQUALS(std::distance(range.begin(), range.end()), 0);
|
|
}
|
|
|
|
void test_Event()
|
|
{
|
|
Input::Manager manager;
|
|
PushEvent(GetEventType(1));
|
|
auto range = manager.PollEvents();
|
|
TS_ASSERT_EQUALS(std::distance(range.begin(), range.end()), 1);
|
|
}
|
|
|
|
void test_PriorityEvent()
|
|
{
|
|
Input::Manager manager;
|
|
PushPriorityEvent(manager, GetEventType(1));
|
|
auto range = manager.PollEvents();
|
|
TS_ASSERT_EQUALS(std::distance(range.begin(), range.end()), 1);
|
|
}
|
|
|
|
void test_PriorityOrder()
|
|
{
|
|
Input::Manager manager;
|
|
const std::uint32_t eventTypeStart{SDL_RegisterEvents(2)};
|
|
const std::uint32_t priorityEventType{eventTypeStart + 1};
|
|
|
|
PushEvent(eventTypeStart);
|
|
PushPriorityEvent(manager, priorityEventType);
|
|
PushEvent(eventTypeStart);
|
|
|
|
auto range = manager.PollEvents();
|
|
auto iter = range.begin();
|
|
TS_ASSERT_DIFFERS(iter, range.end());
|
|
TS_ASSERT_EQUALS(iter->type, priorityEventType);
|
|
++iter;
|
|
TS_ASSERT_DIFFERS(iter, range.end());
|
|
TS_ASSERT_EQUALS(iter->type, eventTypeStart);
|
|
++iter;
|
|
TS_ASSERT_DIFFERS(iter, range.end());
|
|
TS_ASSERT_EQUALS(iter->type, eventTypeStart);
|
|
++iter;
|
|
TS_ASSERT_EQUALS(iter, range.end());
|
|
}
|
|
|
|
void test_Dispatch()
|
|
{
|
|
Input::Manager manager;
|
|
bool triggered{false};
|
|
Input::Handler _{manager, std::integral_constant<size_t, 0>{}, [&](const SDL_Event&){
|
|
triggered = true;
|
|
return IN_HANDLED;
|
|
}};
|
|
|
|
TS_ASSERT(!triggered);
|
|
SDL_Event ev{MakeEvent(GetEventType(1))};
|
|
manager.DispatchEvent(ev);
|
|
TS_ASSERT(triggered);
|
|
}
|
|
|
|
void test_DispatchFilter()
|
|
{
|
|
Input::Manager manager;
|
|
const std::uint32_t eventTypeStart{SDL_RegisterEvents(2)};
|
|
const std::uint32_t filteredEventType{eventTypeStart + 1};
|
|
[[maybe_unused]] Input::Handler filter{manager, std::integral_constant<size_t, 0>{},
|
|
[&](const SDL_Event& ev){
|
|
return ev.type == filteredEventType ? IN_HANDLED : IN_PASS;
|
|
}};
|
|
|
|
bool triggered{false};
|
|
[[maybe_unused]] Input::Handler test{manager, std::integral_constant<size_t, 1>{},
|
|
[&](const SDL_Event&){
|
|
triggered = true;
|
|
return IN_HANDLED;
|
|
}};
|
|
|
|
SDL_Event ev0{MakeEvent(filteredEventType)};
|
|
manager.DispatchEvent(ev0);
|
|
TS_ASSERT(!triggered);
|
|
SDL_Event ev1{MakeEvent(eventTypeStart)};
|
|
manager.DispatchEvent(ev1);
|
|
TS_ASSERT(triggered);
|
|
}
|
|
|
|
void test_Unsubscribe()
|
|
{
|
|
Input::Manager manager;
|
|
bool triggered{false};
|
|
{
|
|
Input::Handler _{manager, std::integral_constant<size_t, 0>{}, [&](const SDL_Event&){
|
|
triggered = true;
|
|
return IN_HANDLED;
|
|
}};
|
|
}
|
|
|
|
SDL_Event ev{MakeEvent(GetEventType(1))};
|
|
manager.DispatchEvent(ev);
|
|
TS_ASSERT(!triggered);
|
|
}
|
|
};
|