./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 / 181
0.0%
Branches:
0 / 291
0.0%
Functions:
0 / 13
0.0%

apps/editor/src/eu/editor/main.cc
Line Branch Exec Source
1 // todo(Gustav): look into glad support
2 #define SDL_FUNCTION_POINTER_IS_VOID_POINTER
3
4 #include "SDL.h"
5
6 #include <cassert>
7 #include <string>
8
9 #include "OpenSans-Regular.ttf.h"
10
11 #include "eu/render/canvas.h"
12 #include "eu/render/state.h"
13 #include "eu/render/font.h"
14 #include "eu/render/opengl_utils.h"
15 #include "eu/render/texture.io.h"
16
17 #include "eu/render/enable_high_performance_graphics.h"
18
19 #include "dear_imgui/imgui.h"
20 #include "dear_imgui/imgui_internal.h"
21
22 #include "dear_imgui/backends/imgui_impl_sdl3.h"
23 #include "dear_imgui/backends/imgui_impl_opengl3.h"
24
25 #include "eu/imgui/ui.h"
26 #include "eu/imgui/init.h"
27
28 #define SDL_MAIN_USE_CALLBACKS
29 #include <SDL3/SDL_main.h>
30
31 #include "eu/core/scurve.h"
32 #include "eu/imgui/scurve.h"
33
34 ENABLE_HIGH_PERFORMANCE_GRAPHICS
35
36 ✗ eu::MemoryChunk chunk_from_embed(const embedded_binary& binary)
37 {
38 ✗ return { .bytes = reinterpret_cast<const char*>(binary.data), .size = binary.size };
39 }
40
41 enum class AppState
42 {
43 continue_running, exit_failure, exit_ok
44 };
45
46 struct App
47 {
48 ✗ App() = default;
49 ~App();
50
51 App(const App&) = delete;
52 App(App&&) = delete;
53 void operator=(const App&) = delete;
54 void operator=(App&&) = delete;
55
56 AppState create();
57 AppState iterate();
58 AppState on_event(const SDL_Event& ev);
59 void destroy();
60
61 int window_width = 0;
62 int window_height = 0;
63 SDL_Window* window = nullptr;
64 SDL_GLContextState* glContext = nullptr;
65 bool show_demo_window = true;
66
67 std::unique_ptr<eu::render::State> states;
68 std::unique_ptr<eu::render::Render2> render;
69 };
70
71 ✗ App::~App()
72 {
73 ✗ destroy();
74 ✗ }
75
76 ✗ AppState App::create()
77 {
78 ✗ const char* glsl_version = "#version 130";
79
80
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 193 not taken.
✗ SDL_SetAppMetadata("Euphoria editor", "v0.1", "com.madeso.euphoria");
81
82
0/4
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 193 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 11 not taken.
✗ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) == false)
83 {
84
0/8
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 193 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 128 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 127 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 125 not taken.
✗ LOG_ERR("Error initializing SDL: {}", SDL_GetError());
85 ✗ return AppState::exit_failure;
86 }
87
88
0/2
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 193 not taken.
✗ const auto app_scale = eu::imgui::calculate_app_scale();
89
0/2
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 130 not taken.
✗ std::tie(window_width, window_height) = eu::imgui::rescale_window(1280, 720, app_scale);
90
91 #if defined(__APPLE__)
92 // GL 3.2 Core + GLSL 150
93 const char* glsl_version = "#version 150";
94 SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
95 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
96 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
97 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
98 #else
99 // GL 3.0 + GLSL 130
100 // const char* glsl_version = "#version 130";
101
0/2
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
102
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
103
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
104
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); // was 0 in dear imgui example??
105 #endif
106
107
0/2
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
108
0/2
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
109
110
0/2
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
111
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
112
113
0/2
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
114
0/2
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
115
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
116
0/2
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 193 not taken.
✗ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
117
118
0/2
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 193 not taken.
✗ window = SDL_CreateWindow("Editor sample",
119 window_width, window_height, SDL_WINDOW_OPENGL | SDL_WINDOW_HIGH_PIXEL_DENSITY | SDL_WINDOW_RESIZABLE);
120
0/2
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 35 not taken.
✗ if (!window)
121 {
122
0/8
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 193 not taken.
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 134 not taken.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 133 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 131 not taken.
✗ LOG_ERR("Error creating window: {}", SDL_GetError());
123 ✗ return AppState::exit_failure;
124 }
125
126
0/2
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 193 not taken.
✗ glContext = SDL_GL_CreateContext(window);
127
0/2
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 193 not taken.
✗ SDL_GetWindowSize(window, &window_width, &window_height);
128
0/2
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 44 not taken.
✗ if (!glContext) {
129
0/8
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 193 not taken.
✗ Branch 39 → 40 not taken.
✗ Branch 39 → 139 not taken.
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 138 not taken.
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 136 not taken.
✗ LOG_ERR("Error creating gl context: {}", SDL_GetError());
130 ✗ return AppState::exit_failure;
131 }
132
133 /* OpenGL setup */
134
0/2
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 193 not taken.
✗ const int glad_result = gladLoadGLLoader(SDL_GL_GetProcAddress);
135
0/2
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 51 not taken.
✗ if (glad_result == 0)
136 {
137
0/6
✗ Branch 46 → 47 not taken.
✗ Branch 46 → 193 not taken.
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 143 not taken.
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 141 not taken.
✗ LOG_ERR("Failed to init glad, error: {0}", glad_result);
138 ✗ return AppState::exit_failure;
139 }
140
141
0/2
✗ Branch 51 → 52 not taken.
✗ Branch 51 → 193 not taken.
✗ IMGUI_CHECKVERSION();
142
0/2
✗ Branch 52 → 53 not taken.
✗ Branch 52 → 193 not taken.
✗ ImGui::CreateContext();
143
0/2
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 193 not taken.
✗ ImGuiIO& io = ImGui::GetIO();
144
0/2
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 193 not taken.
✗ eu::imgui::setup_colors(); // ImGui::StyleColorsDark();
145
0/2
✗ Branch 55 → 56 not taken.
✗ Branch 55 → 193 not taken.
✗ ImGui_ImplSDL3_InitForOpenGL(window, glContext);
146
0/2
✗ Branch 56 → 57 not taken.
✗ Branch 56 → 193 not taken.
✗ ImGui_ImplOpenGL3_Init(glsl_version);
147
148 {
149
0/4
✗ Branch 59 → 60 not taken.
✗ Branch 59 → 145 not taken.
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 145 not taken.
✗ const std::string gl_vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
150
0/4
✗ Branch 64 → 65 not taken.
✗ Branch 64 → 148 not taken.
✗ Branch 65 → 66 not taken.
✗ Branch 65 → 148 not taken.
✗ const std::string gl_renderer = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
151
0/4
✗ Branch 69 → 70 not taken.
✗ Branch 69 → 151 not taken.
✗ Branch 70 → 71 not taken.
✗ Branch 70 → 151 not taken.
✗ const std::string gl_version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
152
0/4
✗ Branch 74 → 75 not taken.
✗ Branch 74 → 154 not taken.
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 154 not taken.
✗ const std::string gl_shading_language_version = reinterpret_cast<const char*>(glGetString(GL_SHADING_LANGUAGE_VERSION));
153
154
0/6
✗ Branch 77 → 78 not taken.
✗ Branch 77 → 173 not taken.
✗ Branch 78 → 79 not taken.
✗ Branch 78 → 159 not taken.
✗ Branch 79 → 80 not taken.
✗ Branch 79 → 157 not taken.
✗ LOG_INFO("Vendor: {0}", gl_vendor);
155
0/6
✗ Branch 81 → 82 not taken.
✗ Branch 81 → 173 not taken.
✗ Branch 82 → 83 not taken.
✗ Branch 82 → 163 not taken.
✗ Branch 83 → 84 not taken.
✗ Branch 83 → 161 not taken.
✗ LOG_INFO("Renderer: {0}", gl_renderer);
156
0/6
✗ Branch 85 → 86 not taken.
✗ Branch 85 → 173 not taken.
✗ Branch 86 → 87 not taken.
✗ Branch 86 → 167 not taken.
✗ Branch 87 → 88 not taken.
✗ Branch 87 → 165 not taken.
✗ LOG_INFO("Version OpenGL: {0}", gl_version);
157
0/6
✗ Branch 89 → 90 not taken.
✗ Branch 89 → 173 not taken.
✗ Branch 90 → 91 not taken.
✗ Branch 90 → 171 not taken.
✗ Branch 91 → 92 not taken.
✗ Branch 91 → 169 not taken.
✗ LOG_INFO("Version GLSL: {0}", gl_shading_language_version);
158 ✗ }
159
160 {
161
0/2
✗ Branch 97 → 98 not taken.
✗ Branch 97 → 185 not taken.
✗ ImFontConfig config;
162 ✗ config.FontDataOwnedByAtlas = false;
163
0/2
✗ Branch 98 → 99 not taken.
✗ Branch 98 → 185 not taken.
✗ ImFont* font = io.Fonts->AddFontFromMemoryTTF(
164 const_cast<void*>(static_cast<const void*>(OPENSANS_REGULAR_TTF_data)),
165 OPENSANS_REGULAR_TTF_size,
166 18.0f,
167 &config
168 );
169
0/8
✗ Branch 99 → 100 not taken.
✗ Branch 99 → 106 not taken.
✗ Branch 100 → 101 not taken.
✗ Branch 100 → 185 not taken.
✗ Branch 101 → 102 not taken.
✗ Branch 101 → 106 not taken.
✗ Branch 103 → 104 not taken.
✗ Branch 103 → 182 not taken.
✗ IM_ASSERT(font != nullptr);
170
171
0/2
✗ Branch 106 → 107 not taken.
✗ Branch 106 → 185 not taken.
✗ eu::imgui::setup_scale(app_scale);
172 }
173
174
0/4
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 193 not taken.
✗ Branch 110 → 111 not taken.
✗ Branch 110 → 112 not taken.
✗ states.reset(new eu::render::State());
175
0/8
✗ Branch 112 → 113 not taken.
✗ Branch 112 → 193 not taken.
✗ Branch 114 → 115 not taken.
✗ Branch 114 → 186 not taken.
✗ Branch 116 → 117 not taken.
✗ Branch 116 → 118 not taken.
✗ Branch 186 → 187 not taken.
✗ Branch 186 → 188 not taken.
✗ render.reset(new eu::render::Render2(states.get()));
176
177
0/6
✗ Branch 118 → 119 not taken.
✗ Branch 118 → 193 not taken.
✗ Branch 119 → 120 not taken.
✗ Branch 119 → 191 not taken.
✗ Branch 120 → 121 not taken.
✗ Branch 120 → 189 not taken.
✗ LOG_INFO("Editor started");
178 ✗ return AppState::continue_running;
179 }
180
181 ✗ AppState App::on_event(const SDL_Event& ev)
182 {
183 ✗ ImGui_ImplSDL3_ProcessEvent(&ev);
184
0/3
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 10 not taken.
✗ Branch 3 → 11 not taken.
✗ switch (ev.type)
185 {
186 ✗ case SDL_EVENT_WINDOW_RESIZED:
187
0/4
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 16 not taken.
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 14 not taken.
✗ LOG_INFO("Resized");
188 ✗ SDL_GetWindowSize(window, &window_width, &window_height);
189 ✗ break;
190 ✗ case SDL_EVENT_QUIT:
191 ✗ return AppState::exit_ok;
192 ✗ default:
193 // ignore other events
194 ✗ break;
195 }
196
197 ✗ return AppState::continue_running;
198 }
199
200 ✗ void custom_widgets_demo()
201 {
202
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 49 not taken.
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 33 not taken.
✗ if (auto prop = eu::imgui::PropTable::begin())
203 {
204
0/4
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 10 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 10 not taken.
✗ static std::string text;
205 static auto rot = eu::Ypr{ .yaw = eu::no_rotation, .pitch = eu::no_rotation, .roll = eu::no_rotation };
206 static auto vec = eu::v3{ 0.1f, 5.0f, 24.0f };
207 static float gamma = 2.0f;
208 static eu::Rui rui = { .right = 0.0f, .up = 0.0f, .in = 0.0f };
209 static eu::m4 mat = eu::m4_identity;
210
211
0/4
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 37 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 35 not taken.
✗ prop.text("Text", "This is a text");
212
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 47 not taken.
✗ prop.edit("Editable", &text);
213
214
0/4
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 43 not taken.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 41 not taken.
✗ prop.readonly("Readonly text", "Some text");
215
0/2
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 47 not taken.
✗ prop.readonly("Readonly Vec", vec);
216
0/2
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 47 not taken.
✗ prop.readonly("Readonly Rot", rot);
217
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 47 not taken.
✗ prop.simple_gamma_slider("Gamma", &gamma);
218
219
0/2
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 47 not taken.
✗ prop.drag("Drag vec", &vec);
220
0/2
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 47 not taken.
✗ prop.drag("Drag Rotation", &rot);
221
222
0/2
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 47 not taken.
✗ prop.gear("Gear vec", &vec);
223
0/2
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 47 not taken.
✗ prop.gear("Gear rui", &rui);
224
0/2
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 47 not taken.
✗ prop.gear("Gear Rot", &rot);
225
226
0/2
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 47 not taken.
✗ prop.transform(mat);
227
0/2
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 47 not taken.
✗ prop.transform(&mat);
228 ✗ }
229 ✗ }
230
231 ✗ AppState App::iterate()
232 {
233 ✗ eu::imgui::setup_colors();
234
235 ✗ ImGui_ImplOpenGL3_NewFrame();
236 ✗ ImGui_ImplSDL3_NewFrame();
237 ✗ ImGui::NewFrame();
238
239
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 8 not taken.
✗ if (show_demo_window)
240 {
241 ✗ ImGui::ShowDemoWindow(&show_demo_window);
242 }
243
244
0/2
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 57 not taken.
✗ if (ImGui::Begin("Demo"))
245 {
246 static eu::v3 pos = { 0,0,0 };
247 static eu::v3 rot = { 0, 0, 0 };
248 static eu::v3 scale = { 1, 1, 1 };
249
250 static float roughness = 0.35f;
251 static float metallic = 0.85f;
252 static float normal_intensity = 1.20f;
253
254 static bool is_trigger = false;
255 static eu::v3 center = {0, 0, 0};
256 static eu::v3 size = { 0, 0, 0 };
257
258
0/2
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 20 not taken.
✗ if (eu::imgui::header("TRANSFORM"))
259 {
260
0/4
✗ Branch 12 → 13 not taken.
✗ Branch 12 → 76 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 18 not taken.
✗ if (const auto prop = eu::imgui::PropTable::begin())
261 {
262
0/2
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 74 not taken.
✗ prop.drag("Position", &pos);
263
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 74 not taken.
✗ prop.drag("Rotation", &rot);
264
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 74 not taken.
✗ prop.drag("Scale", &scale);
265 ✗ }
266 }
267
268
0/2
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 30 not taken.
✗ if (eu::imgui::header("MATERIAL"))
269 {
270
0/4
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 79 not taken.
✗ Branch 24 → 25 not taken.
✗ Branch 24 → 28 not taken.
✗ if (const auto prop = eu::imgui::PropTable::begin())
271 {
272
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 77 not taken.
✗ prop.slider("Roughness", &roughness);
273
0/2
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 77 not taken.
✗ prop.slider("Metallic", &metallic);
274
0/2
✗ Branch 27 → 28 not taken.
✗ Branch 27 → 77 not taken.
✗ prop.slider("Normal intensity", &normal_intensity, 0.0f, 2.0f);
275 ✗ }
276 }
277
278
0/2
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 40 not taken.
✗ if (eu::imgui::header("BOX COLLIDER 3D"))
279 {
280
0/4
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 82 not taken.
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 38 not taken.
✗ if (auto prop = eu::imgui::PropTable::begin())
281 {
282
0/2
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 80 not taken.
✗ prop.check("Is Trigger", &is_trigger);
283
0/2
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 80 not taken.
✗ prop.drag("Center", &center);
284
0/2
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 80 not taken.
✗ prop.drag("Size", &size);
285 ✗ }
286 }
287
288
0/2
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 43 not taken.
✗ if (eu::imgui::header("CUSTOM WIDGETS"))
289 {
290 ✗ custom_widgets_demo();
291 }
292
293
0/2
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 56 not taken.
✗ if (eu::imgui::header("SCURVE"))
294 {
295
0/4
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 85 not taken.
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 54 not taken.
✗ if (auto prop = eu::imgui::PropTable::begin())
296 {
297 static eu::core::SCurve scurve;
298
0/4
✗ Branch 48 → 49 not taken.
✗ Branch 48 → 53 not taken.
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 53 not taken.
✗ static eu::imgui::SCurveGuiState gui;
299 static eu::imgui::SCurveImguiSettings settings;
300
301
0/2
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 83 not taken.
✗ prop.scurve("Default curve", &scurve, &gui, eu::imgui::FlipX::yes, settings, true);
302 ✗ }
303 }
304
305 ✗ eu::imgui::centered_button("Add component");
306 }
307 ✗ ImGui::End();
308
309 {
310 ✗ eu::render::RenderCommand cmd {.states = states.get(), .render = render.get(), .size = {.width = window_width, .height = window_height} };
311
312 // todo(Gustav): provide a pixel layout
313 ✗ const auto screen = eu::render::LayoutData{ .style = eu::render::ViewportStyle::extended,
314 ✗ .requested_width = static_cast<float>(window_width), .requested_height = static_cast<float>(window_height) };
315
316
0/2
✗ Branch 60 → 61 not taken.
✗ Branch 60 → 90 not taken.
✗ cmd.clear(eu::colors::blue_sky, screen);
317
318
0/2
✗ Branch 61 → 62 not taken.
✗ Branch 61 → 90 not taken.
✗ auto layer = eu::render::with_layer2(cmd, screen);
319
0/4
✗ Branch 65 → 66 not taken.
✗ Branch 65 → 86 not taken.
✗ Branch 66 → 67 not taken.
✗ Branch 66 → 86 not taken.
✗ eu::render::Quad{ .tint = eu::colors::green_bluish }.draw(layer.batch, layer.viewport_aabb_in_worldspace.get_bottom(50));
320 ✗ }
321
322 ✗ ImGui::Render();
323 ✗ ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
324 ✗ SDL_GL_SwapWindow(window);
325
326 ✗ return AppState::continue_running;
327 }
328
329 ✗ void App::destroy()
330 {
331 ✗ render.reset();
332 ✗ states.reset();
333
334 ✗ ImGui_ImplOpenGL3_Shutdown();
335 ✗ ImGui_ImplSDL3_Shutdown();
336 ✗ ImGui::DestroyContext();
337
338
0/4
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 17 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 15 not taken.
✗ LOG_INFO("Shutting down");
339 ✗ SDL_GL_DestroyContext(glContext);
340 ✗ glContext = nullptr;
341
342 ✗ SDL_DestroyWindow(window);
343 ✗ window = nullptr;
344 ✗ SDL_Quit();
345 ✗ }
346
347 // binding
348 ✗ SDL_AppResult to_sdl_result(AppState state)
349 {
350
0/4
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ Branch 2 → 5 not taken.
✗ Branch 2 → 6 not taken.
✗ switch (state)
351 {
352 ✗ case AppState::continue_running: return SDL_APP_CONTINUE;
353 ✗ case AppState::exit_failure: return SDL_APP_FAILURE;
354 ✗ case AppState::exit_ok: return SDL_APP_SUCCESS;
355 }
356
357 ✗ return SDL_APP_FAILURE;
358 }
359
360 ✗ SDL_AppResult SDL_AppInit(void** out_app, int, char**)
361 {
362
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
✗ auto app = new App();
363 ✗ const auto create_result = app->create();
364
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ if (create_result == AppState::continue_running)
365 {
366 ✗ *out_app = app;
367 ✗ return SDL_APP_CONTINUE;
368 }
369
370
0/2
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 12 not taken.
✗ delete app;
371 ✗ return to_sdl_result(create_result);
372 }
373
374 ✗ SDL_AppResult SDL_AppIterate(void* app_arg)
375 {
376 ✗ auto app = static_cast<App*>(app_arg);
377 ✗ const auto result = app->iterate();
378 ✗ return to_sdl_result(result);
379 }
380
381 ✗ SDL_AppResult SDL_AppEvent(void* app_arg, SDL_Event* ev)
382 {
383 ✗ auto app = static_cast<App*>(app_arg);
384 ✗ const auto result = app->on_event(*ev);
385 ✗ return to_sdl_result(result);
386 }
387
388 ✗ void SDL_AppQuit(void* app_arg, SDL_AppResult result)
389 {
390
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 8 not taken.
✗ if (result == SDL_APP_FAILURE)
391 {
392
0/4
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 14 not taken.
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 12 not taken.
✗ LOG_ERR("App crashed :(");
393 }
394
395 ✗ auto app = static_cast<App*>(app_arg);
396
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 11 not taken.
✗ delete app;
397 ✗ app = nullptr;
398 ✗ }
399