Skip to content

Commit 70c6038

Browse files
committed
Backends: moved global to a data structure to facilitate support for multi-contexts. (ocornut#586, ocornut#1851, ocornut#2004, ocornut#3012, ocornut#3934, ocornut#4141)
This is NOT enable multi-contexts for any backends - in order to make this commit as harmless as possible, while containing all the cruft/renaming -
1 parent 88f4c13 commit 70c6038

12 files changed

+1046
-709
lines changed

backends/imgui_impl_allegro5.cpp

+74-48
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
1010
// [ ] Platform: Missing gamepad support.
1111

12-
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
12+
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
1313
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
1414
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
1515
// Read online: https://github.com/ocornut/imgui/tree/master/docs
1616

1717
// CHANGELOG
1818
// (minor and older changes stripped away, please see git history for details)
19+
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
1920
// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
2021
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
2122
// 2020-08-10: Inputs: Fixed horizontal mouse wheel direction.
@@ -53,13 +54,24 @@
5354
#pragma warning (disable: 4127) // condition expression is constant
5455
#endif
5556

56-
// Data
57-
static ALLEGRO_DISPLAY* g_Display = NULL;
58-
static ALLEGRO_BITMAP* g_Texture = NULL;
59-
static double g_Time = 0.0;
60-
static ALLEGRO_MOUSE_CURSOR* g_MouseCursorInvisible = NULL;
61-
static ALLEGRO_VERTEX_DECL* g_VertexDecl = NULL;
62-
static char* g_ClipboardTextData = NULL;
57+
// Allegro Data
58+
struct ImGui_ImplAllegro5_Data
59+
{
60+
ALLEGRO_DISPLAY* Display;
61+
ALLEGRO_BITMAP* Texture;
62+
double Time;
63+
ALLEGRO_MOUSE_CURSOR* MouseCursorInvisible;
64+
ALLEGRO_VERTEX_DECL* VertexDecl;
65+
char* ClipboardTextData;
66+
67+
ImGui_ImplAllegro5_Data() { memset(this, 0, sizeof(*this)); }
68+
};
69+
70+
// Wrapping access to backend data (to facilitate multiple-contexts stored in io.BackendPlatformUserData)
71+
static ImGui_ImplAllegro5_Data* g_Data;
72+
static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_CreateBackendData() { IM_ASSERT(g_Data == NULL); g_Data = IM_NEW(ImGui_ImplAllegro5_Data); return g_Data; }
73+
static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_GetBackendData() { return ImGui::GetCurrentContext() != NULL ? g_Data : NULL; }
74+
static void ImGui_ImplAllegro5_DestroyBackendData() { IM_DELETE(g_Data); g_Data = NULL; }
6375

6476
struct ImDrawVertAllegro
6577
{
@@ -96,6 +108,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
96108
return;
97109

98110
// Backup Allegro state that will be modified
111+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
99112
ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
100113
ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform();
101114
int last_clip_x, last_clip_y, last_clip_w, last_clip_h;
@@ -161,7 +174,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
161174
// Draw
162175
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID();
163176
al_set_clipping_rectangle(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y);
164-
al_draw_prim(&vertices[0], g_VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
177+
al_draw_prim(&vertices[0], bd->VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
165178
}
166179
idx_offset += pcmd->ElemCount;
167180
}
@@ -177,6 +190,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
177190
bool ImGui_ImplAllegro5_CreateDeviceObjects()
178191
{
179192
// Build texture atlas
193+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
180194
ImGuiIO& io = ImGui::GetIO();
181195
unsigned char* pixels;
182196
int width, height;
@@ -210,54 +224,61 @@ bool ImGui_ImplAllegro5_CreateDeviceObjects()
210224

211225
// Store our identifier
212226
io.Fonts->SetTexID((void*)cloned_img);
213-
g_Texture = cloned_img;
227+
bd->Texture = cloned_img;
214228

215229
// Create an invisible mouse cursor
216230
// Because al_hide_mouse_cursor() seems to mess up with the actual inputs..
217231
ALLEGRO_BITMAP* mouse_cursor = al_create_bitmap(8, 8);
218-
g_MouseCursorInvisible = al_create_mouse_cursor(mouse_cursor, 0, 0);
232+
bd->MouseCursorInvisible = al_create_mouse_cursor(mouse_cursor, 0, 0);
219233
al_destroy_bitmap(mouse_cursor);
220234

221235
return true;
222236
}
223237

224238
void ImGui_ImplAllegro5_InvalidateDeviceObjects()
225239
{
226-
if (g_Texture)
240+
ImGuiIO& io = ImGui::GetIO();
241+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
242+
if (bd->Texture)
227243
{
228-
ImGuiIO& io = ImGui::GetIO();
229244
io.Fonts->SetTexID(NULL);
230-
al_destroy_bitmap(g_Texture);
231-
g_Texture = NULL;
245+
al_destroy_bitmap(bd->Texture);
246+
bd->Texture = NULL;
232247
}
233-
if (g_MouseCursorInvisible)
248+
if (bd->MouseCursorInvisible)
234249
{
235-
al_destroy_mouse_cursor(g_MouseCursorInvisible);
236-
g_MouseCursorInvisible = NULL;
250+
al_destroy_mouse_cursor(bd->MouseCursorInvisible);
251+
bd->MouseCursorInvisible = NULL;
237252
}
238253
}
239254

240255
#if ALLEGRO_HAS_CLIPBOARD
241256
static const char* ImGui_ImplAllegro5_GetClipboardText(void*)
242257
{
243-
if (g_ClipboardTextData)
244-
al_free(g_ClipboardTextData);
245-
g_ClipboardTextData = al_get_clipboard_text(g_Display);
246-
return g_ClipboardTextData;
258+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
259+
if (bd->ClipboardTextData)
260+
al_free(bd->ClipboardTextData);
261+
bd->ClipboardTextData = al_get_clipboard_text(bd->Display);
262+
return bd->ClipboardTextData;
247263
}
248264

249265
static void ImGui_ImplAllegro5_SetClipboardText(void*, const char* text)
250266
{
251-
al_set_clipboard_text(g_Display, text);
267+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
268+
al_set_clipboard_text(bd->Display, text);
252269
}
253270
#endif
254271

255272
bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
256273
{
257-
g_Display = display;
274+
ImGuiIO& io = ImGui::GetIO();
275+
IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!");
276+
277+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_CreateBackendData();
278+
bd->Display = display;
258279

259280
// Setup backend capabilities flags
260-
ImGuiIO& io = ImGui::GetIO();
281+
io.BackendRendererUserData = (void*)bd;
261282
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
262283
io.BackendPlatformName = io.BackendRendererName = "imgui_impl_allegro5";
263284

@@ -271,7 +292,7 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
271292
{ ALLEGRO_PRIM_COLOR_ATTR, 0, IM_OFFSETOF(ImDrawVertAllegro, col) },
272293
{ 0, 0, 0 }
273294
};
274-
g_VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
295+
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
275296

276297
io.KeyMap[ImGuiKey_Tab] = ALLEGRO_KEY_TAB;
277298
io.KeyMap[ImGuiKey_LeftArrow] = ALLEGRO_KEY_LEFT;
@@ -308,18 +329,20 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
308329

309330
void ImGui_ImplAllegro5_Shutdown()
310331
{
332+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
311333
ImGui_ImplAllegro5_InvalidateDeviceObjects();
312334

313-
g_Display = NULL;
314-
g_Time = 0.0;
335+
bd->Display = NULL;
336+
bd->Time = 0.0;
315337

316-
if (g_VertexDecl)
317-
al_destroy_vertex_decl(g_VertexDecl);
318-
g_VertexDecl = NULL;
338+
if (bd->VertexDecl)
339+
al_destroy_vertex_decl(bd->VertexDecl);
340+
bd->VertexDecl = NULL;
319341

320-
if (g_ClipboardTextData)
321-
al_free(g_ClipboardTextData);
322-
g_ClipboardTextData = NULL;
342+
if (bd->ClipboardTextData)
343+
al_free(bd->ClipboardTextData);
344+
bd->ClipboardTextData = NULL;
345+
ImGui_ImplAllegro5_DestroyBackendData();
323346
}
324347

325348
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
@@ -329,11 +352,12 @@ void ImGui_ImplAllegro5_Shutdown()
329352
bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
330353
{
331354
ImGuiIO& io = ImGui::GetIO();
355+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
332356

333357
switch (ev->type)
334358
{
335359
case ALLEGRO_EVENT_MOUSE_AXES:
336-
if (ev->mouse.display == g_Display)
360+
if (ev->mouse.display == bd->Display)
337361
{
338362
io.MouseWheel += ev->mouse.dz;
339363
io.MouseWheelH -= ev->mouse.dw;
@@ -342,31 +366,31 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
342366
return true;
343367
case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
344368
case ALLEGRO_EVENT_MOUSE_BUTTON_UP:
345-
if (ev->mouse.display == g_Display && ev->mouse.button <= 5)
369+
if (ev->mouse.display == bd->Display && ev->mouse.button <= 5)
346370
io.MouseDown[ev->mouse.button - 1] = (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN);
347371
return true;
348372
case ALLEGRO_EVENT_TOUCH_MOVE:
349-
if (ev->touch.display == g_Display)
373+
if (ev->touch.display == bd->Display)
350374
io.MousePos = ImVec2(ev->touch.x, ev->touch.y);
351375
return true;
352376
case ALLEGRO_EVENT_TOUCH_BEGIN:
353377
case ALLEGRO_EVENT_TOUCH_END:
354378
case ALLEGRO_EVENT_TOUCH_CANCEL:
355-
if (ev->touch.display == g_Display && ev->touch.primary)
379+
if (ev->touch.display == bd->Display && ev->touch.primary)
356380
io.MouseDown[0] = (ev->type == ALLEGRO_EVENT_TOUCH_BEGIN);
357381
return true;
358382
case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY:
359-
if (ev->mouse.display == g_Display)
383+
if (ev->mouse.display == bd->Display)
360384
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
361385
return true;
362386
case ALLEGRO_EVENT_KEY_CHAR:
363-
if (ev->keyboard.display == g_Display)
387+
if (ev->keyboard.display == bd->Display)
364388
if (ev->keyboard.unichar != 0)
365389
io.AddInputCharacter((unsigned int)ev->keyboard.unichar);
366390
return true;
367391
case ALLEGRO_EVENT_KEY_DOWN:
368392
case ALLEGRO_EVENT_KEY_UP:
369-
if (ev->keyboard.display == g_Display)
393+
if (ev->keyboard.display == bd->Display)
370394
io.KeysDown[ev->keyboard.keycode] = (ev->type == ALLEGRO_EVENT_KEY_DOWN);
371395
return true;
372396
}
@@ -379,11 +403,12 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
379403
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
380404
return;
381405

406+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
382407
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
383408
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
384409
{
385410
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
386-
al_set_mouse_cursor(g_Display, g_MouseCursorInvisible);
411+
al_set_mouse_cursor(bd->Display, bd->MouseCursorInvisible);
387412
}
388413
else
389414
{
@@ -398,27 +423,28 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
398423
case ImGuiMouseCursor_ResizeNWSE: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NW; break;
399424
case ImGuiMouseCursor_NotAllowed: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_UNAVAILABLE; break;
400425
}
401-
al_set_system_mouse_cursor(g_Display, cursor_id);
426+
al_set_system_mouse_cursor(bd->Display, cursor_id);
402427
}
403428
}
404429

405430
void ImGui_ImplAllegro5_NewFrame()
406431
{
407-
if (!g_Texture)
432+
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
433+
if (!bd->Texture)
408434
ImGui_ImplAllegro5_CreateDeviceObjects();
409435

410436
ImGuiIO& io = ImGui::GetIO();
411437

412438
// Setup display size (every frame to accommodate for window resizing)
413439
int w, h;
414-
w = al_get_display_width(g_Display);
415-
h = al_get_display_height(g_Display);
440+
w = al_get_display_width(bd->Display);
441+
h = al_get_display_height(bd->Display);
416442
io.DisplaySize = ImVec2((float)w, (float)h);
417443

418444
// Setup time step
419445
double current_time = al_get_time();
420-
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
421-
g_Time = current_time;
446+
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
447+
bd->Time = current_time;
422448

423449
// Setup inputs
424450
ALLEGRO_KEYBOARD_STATE keys;

0 commit comments

Comments
 (0)