载入中...
搜索中...
未找到
EventSink.cpp
浏览该文件的文档.
1// Translates SDL joystick and game-controller events into engine messages, and
2// keeps the module's device table in sync on hotplug.
3//
4// This lived in the SDL event pump, which therefore had to know about the
5// Joystick module and its Pad type. Owning it here removes that edge.
6// The Joystick module binds itself as owner at construction so the hot path
7// never looks up ModuleManager.
8
9#include "common/Capability.h"
10#include "joystick/Joystick.h"
11#include "joystick/Pad.h"
15
16#include <SDL2/SDL_events.h>
17#include <SDL2/SDL_gamecontroller.h>
18
19#include <cmath>
20
22namespace {
23
26
27eve::joystick::Joystick *g_owner = nullptr;
28
30int64_t axisMilli(int16_t raw) {
31 return static_cast<int64_t>(std::lround(clampAxis(raw / 32768.0f) * 1000.0f));
32}
33
34class JoystickEventSink : public eve::platform_event::IPlatformEventSink {
35public:
36 Message *translatePlatformEvent(const void *nativeEvent) override {
37 const auto &e = *static_cast<const SDL_Event *>(nativeEvent);
38 auto *joy = g_owner;
39 if (!joy) return nullptr;
40
41 switch (e.type) {
42 case SDL_JOYDEVICEADDED: {
43 auto *pad = joy->addJoystick(e.jdevice.which);
44 if (!pad) return nullptr;
45 return new Message("joystickadded",
46 {Variant::makeInt(pad->getID()),
47 Variant::makeString(pad->getName()),
48 Variant::makeInt(pad->isGamepad() ? 1 : 0)});
49 }
50 case SDL_JOYDEVICEREMOVED: {
51 auto *pad = joy->getJoystickFromID(e.jdevice.which);
52 if (!pad) return nullptr;
53 const int id = pad->getID();
54 const std::string name = pad->getName();
55 joy->removeJoystick(pad);
56 return new Message("joystickremoved",
57 {Variant::makeInt(id), Variant::makeString(name)});
58 }
59 case SDL_JOYBUTTONDOWN:
60 case SDL_JOYBUTTONUP: {
61 auto *pad = joy->getJoystickFromID(e.jbutton.which);
62 if (!pad) return nullptr;
63 return new Message(
64 e.type == SDL_JOYBUTTONDOWN ? "joystickpressed" : "joystickreleased",
65 {Variant::makeInt(pad->getID()), Variant::makeInt(e.jbutton.button)});
66 }
67 case SDL_JOYAXISMOTION: {
68 auto *pad = joy->getJoystickFromID(e.jaxis.which);
69 if (!pad) return nullptr;
70 return new Message("joystickaxis",
71 {Variant::makeInt(pad->getID()), Variant::makeInt(e.jaxis.axis),
72 Variant::makeInt(axisMilli(e.jaxis.value))});
73 }
74 case SDL_JOYHATMOTION: {
75 auto *pad = joy->getJoystickFromID(e.jhat.which);
76 if (!pad) return nullptr;
77 return new Message("joystickhat",
78 {Variant::makeInt(pad->getID()), Variant::makeInt(e.jhat.hat),
79 Variant::makeString(pad->getHat(e.jhat.hat))});
80 }
81 case SDL_CONTROLLERBUTTONDOWN:
82 case SDL_CONTROLLERBUTTONUP: {
83 auto *pad = joy->getJoystickFromID(e.cbutton.which);
84 if (!pad) return nullptr;
85 const char *btn = SDL_GameControllerGetStringForButton(
86 static_cast<SDL_GameControllerButton>(e.cbutton.button));
87 return new Message(
88 e.type == SDL_CONTROLLERBUTTONDOWN ? "gamepadpressed" : "gamepadreleased",
89 {Variant::makeInt(pad->getID()), Variant::makeString(btn ? btn : "")});
90 }
91 case SDL_CONTROLLERAXISMOTION: {
92 auto *pad = joy->getJoystickFromID(e.caxis.which);
93 if (!pad) return nullptr;
94 const char *axis = SDL_GameControllerGetStringForAxis(
95 static_cast<SDL_GameControllerAxis>(e.caxis.axis));
96 return new Message("gamepadaxis", {Variant::makeInt(pad->getID()),
97 Variant::makeString(axis ? axis : ""),
98 Variant::makeInt(axisMilli(e.caxis.value))});
99 }
100 default:
101 return nullptr;
102 }
103 }
104};
105
106struct Register {
107 Register() {
108 static JoystickEventSink sink;
109 eve::cap::addListener<eve::platform_event::IPlatformEventSink>(&sink,
111 }
112} g_register;
113
114} // namespace
115
116void bindJoystickEventSinkOwner(eve::joystick::Joystick *owner) noexcept { g_owner = owner; }
117
118} // namespace eve::joystick::sdl
std::string name
Joystick / gamepad manager. Tracks connected pads and gamecontroller mappings.
Definition Joystick.h:14
virtual Pad * addJoystick(int deviceindex)=0
Open a device by SDL device index; returns null on failure.
EVENGINE_API_FOUNDATION public API.
A named event carrying an ordered list of Variant payloads. Pushed messages are heap-allocated; the q...
void bindJoystickEventSinkOwner(eve::joystick::Joystick *owner) noexcept
Bind the live Joystick module into the SDL event sink. @ownership Borrowed; the Joystick module owns ...
float clampAxis(float x)
Clamps a raw axis sample into [-1, 1].
Definition Joystick.cpp:14
uint32_t pad[2]