xref: /aosp_15_r20/external/openscreen/cast/standalone_receiver/sdl_glue.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CAST_STANDALONE_RECEIVER_SDL_GLUE_H_
6 #define CAST_STANDALONE_RECEIVER_SDL_GLUE_H_
7 
8 #include <stdint.h>
9 
10 #pragma GCC diagnostic push
11 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
12 #include <SDL2/SDL.h>
13 #pragma GCC diagnostic pop
14 
15 #include <functional>
16 #include <memory>
17 #include <utility>
18 #include <vector>
19 
20 #include "util/alarm.h"
21 
22 namespace openscreen {
23 
24 class TaskRunner;
25 
26 namespace cast {
27 
28 template <uint32_t subsystem>
29 class ScopedSDLSubSystem {
30  public:
ScopedSDLSubSystem()31   ScopedSDLSubSystem() { SDL_InitSubSystem(subsystem); }
~ScopedSDLSubSystem()32   ~ScopedSDLSubSystem() { SDL_QuitSubSystem(subsystem); }
33 };
34 
35 // Macro that, for an SDL_Foo, generates code for:
36 //
37 //  using SDLFooUniquePtr = std::unique_ptr<SDL_Foo, SDLFooDestroyer>;
38 //  SDLFooUniquePtr MakeUniqueSDLFoo(...args...);
39 #define DEFINE_SDL_UNIQUE_PTR(name)                          \
40   struct SDL##name##Destroyer {                              \
41     void operator()(SDL_##name* obj) const {                 \
42       if (obj) {                                             \
43         SDL_Destroy##name(obj);                              \
44       }                                                      \
45     }                                                        \
46   };                                                         \
47   using SDL##name##UniquePtr =                               \
48       std::unique_ptr<SDL_##name, SDL##name##Destroyer>;     \
49   template <typename... Args>                                \
50   SDL##name##UniquePtr MakeUniqueSDL##name(Args&&... args) { \
51     return SDL##name##UniquePtr(                             \
52         SDL_Create##name(std::forward<Args>(args)...));      \
53   }
54 
55 DEFINE_SDL_UNIQUE_PTR(Window);
56 DEFINE_SDL_UNIQUE_PTR(Renderer);
57 DEFINE_SDL_UNIQUE_PTR(Texture);
58 
59 #undef DEFINE_SDL_UNIQUE_PTR
60 
61 // A looping mechanism that runs the SDL event loop by scheduling periodic tasks
62 // to the given TaskRunner. Looping continues indefinitely, until the instance
63 // is destroyed. A client-provided quit callback is invoked whenever a SDL_QUIT
64 // event is received.
65 class SDLEventLoopProcessor {
66  public:
67   SDLEventLoopProcessor(TaskRunner* task_runner,
68                         std::function<void()> quit_callback);
69   ~SDLEventLoopProcessor();
70 
71   using KeyboardEventCallback = std::function<void(const SDL_KeyboardEvent&)>;
72   void RegisterForKeyboardEvent(KeyboardEventCallback cb);
73 
74  private:
75   void ProcessPendingEvents();
76 
77   Alarm alarm_;
78   std::function<void()> quit_callback_;
79   std::vector<KeyboardEventCallback> keyboard_callbacks_;
80 };
81 
82 }  // namespace cast
83 }  // namespace openscreen
84 
85 #endif  // CAST_STANDALONE_RECEIVER_SDL_GLUE_H_
86