From d2d9981efe4af75bb0b0e4e48e6c5cec384237ef Mon Sep 17 00:00:00 2001 From: Patedam Date: Sun, 25 Oct 2026 15:23:07 -0400 Subject: [PATCH] two windows open + can close the app by pressing X --- Juliet/julietapp/julietapp_core.c | 108 ++++++++++++++++--- Juliet/julietapp/julietapp_core.h | 42 +++++++- Juliet/win32/window_manager/window_manager.c | 2 +- 3 files changed, 132 insertions(+), 20 deletions(-) diff --git a/Juliet/julietapp/julietapp_core.c b/Juliet/julietapp/julietapp_core.c index 1126b6c..ef58625 100644 --- a/Juliet/julietapp/julietapp_core.c +++ b/Juliet/julietapp/julietapp_core.c @@ -6,28 +6,32 @@ internal void ja_init() // Window cache { - ja_state->window_state_gen_id = 1; + ja_state->window_request_gen_id = 1; ja_state->window_state_slots_count = 64; ja_state->window_state_slots = push_array(arena, JA_WindowStateSlot, ja_state->window_state_slots_count); ja_state->first_window_state = ja_state->last_window_state = &ja_nil_window_state; } + + // Create window requests (2 for testing) + { + ja_window_request(); + ja_window_request(); + } } internal void ja_frame() { TempArena scratch = scratch_begin(0, 0); + ja_state->frame_depth += 1; // ========================================================================= // Events from os WM_EventList events = { 0 }; - bool32 wait = 0; - events = wm_get_events(scratch.arena, wait); - - // if (hello.handle[0] == 0) - // { - // hello = wm_window_open(rect2fp(50.f, 50.f, 1280.f, 720.f), WM_WindowFlag_UseDefaultPosition, - // str8_literal("Hello")); wm_window_first_paint(hello); - // } + if (ja_state->frame_depth == 1) + { + bool32 wait = 0; + events = wm_get_events(scratch.arena, wait); + } // ========================================================================= // Consume events @@ -50,10 +54,14 @@ internal void ja_frame() // Window management (open/render) { - for (uint64 id = 1; id < ja_state->window_state_gen_id + 1; ++id) - { - JA_WindowState* ws = ja_window_state_from_id(id); - } + for + EachNode(request, JA_WindowRequest, ja_state->window_request_first) + { + JA_WindowState* ws = ja_window_state_from_id(request->id); + + // Will render here but for now just increase frame num + ws->frames_alive += 1; + } } // Window Garbage collect @@ -63,10 +71,9 @@ internal void ja_frame() { for (JA_WindowState *ws = ja_state->window_state_slots[slot_idx].first, *next; ws != 0; ws = next) { - next = ws->hash_next; - // TODO : need to be able to gc a closed window. Right now we only know number of window using - // the gen id, but we must do better. No need to save opened window in config so leaner version is ok - if (ja_state->quit) + next = ws->hash_next; + JA_WindowRequest* request = ja_window_request_from_id(ws->id); + if (request == 0 || ja_state->quit) { wm_window_close(ws->plat_handle); arena_release(ws->arena); @@ -80,6 +87,26 @@ internal void ja_frame() } } + // show window after first frame + if (ja_state->frame_depth == 1) + { + JA_IDList windows_to_show = { 0 }; + for (JA_WindowState* ws = ja_state->first_window_state; ws != &ja_nil_window_state; ws = ws->order_next) + { + if (ws->frames_alive == 1) + { + ja_id_list_push(scratch.arena, &windows_to_show, ws->id); + } + } + for + EachNode(node, JA_IDNode, windows_to_show.first) + { + JA_WindowState* ws = ja_window_state_from_id(node->val); + wm_window_first_paint(ws->plat_handle); + } + } + + ja_state->frame_depth -= 1; scratch_end(scratch); } @@ -88,6 +115,17 @@ internal void ja_shutdown() arena_release(ja_state->arena); } +// ============================================================================= +// Id Functions + +internal void ja_id_list_push(Arena* arena, JA_IDList* list, JA_ID id) +{ + JA_IDNode* node = push_array(arena, JA_IDNode, 1); + SLL_queue_push(list->first, list->last, node); + list->count += 1; + node->val = id; +} + // ============================================================================= // Window Functions @@ -144,6 +182,8 @@ internal JA_WindowState* ja_window_state_from_id(JA_ID id) { TempArena scratch = scratch_begin(0, 0); + ws->frames_alive = 0; + // TODO: save fav monitor in config WM_Monitor prim_m = wm_primary_monitor(); String8 prim_name = wm_name_from_monitor(scratch.arena, prim_m); @@ -179,3 +219,37 @@ internal JA_WindowState* ja_window_state_from_id(JA_ID id) ja_state->window_state_last_accessed = ws; return ws; } + +internal void ja_window_request() +{ + JA_ID id = ja_state->window_request_gen_id++; + JA_WindowRequest* result = ja_state->free_window_request; + if (result != 0) + { + SLL_stack_pop(ja_state->free_window_request); + } + else + { + result = push_array_no_zero(ja_state->arena, JA_WindowRequest, 1); + } + result->id = id; + DLL_push_back(ja_state->window_request_first, ja_state->window_request_last, result); +} + +internal void ja_window_close_request(JA_WindowRequest* request) +{ + DLL_remove(ja_state->window_request_first, ja_state->window_request_last, request); + SLL_stack_push(ja_state->free_window_request, request); +} + +internal JA_WindowRequest* ja_window_request_from_id(JA_ID id) +{ + JA_WindowRequest* result = 0; + for + EachNode(wr, JA_WindowRequest, ja_state->window_request_first) + { + result = wr; + break; + } + return result; +} diff --git a/Juliet/julietapp/julietapp_core.h b/Juliet/julietapp/julietapp_core.h index 8a881c0..ecaa6f2 100644 --- a/Juliet/julietapp/julietapp_core.h +++ b/Juliet/julietapp/julietapp_core.h @@ -4,9 +4,32 @@ // Core Types typedef uint64 JA_ID; +typedef struct JA_IDNode JA_IDNode; +struct JA_IDNode +{ + JA_IDNode* next; + JA_ID val; +}; + +typedef struct JA_IDList JA_IDList; +struct JA_IDList +{ + JA_IDNode* first; + JA_IDNode* last; + uint64 count; +}; + // ============================================================================= // States Types +typedef struct JA_WindowRequest JA_WindowRequest; +struct JA_WindowRequest +{ + JA_WindowRequest* next; + JA_WindowRequest* previous; + JA_ID id; +}; + typedef struct JA_WindowState JA_WindowState; struct JA_WindowState { @@ -16,6 +39,7 @@ struct JA_WindowState JA_WindowState* hash_next; JA_WindowState* hash_previous; JA_ID id; + uint64 frames_alive; // Info and handle Arena* arena; @@ -35,6 +59,13 @@ struct JA_State // Base Arena* arena; bool32 quit; + int32 frame_depth; + + // Windows requests + JA_ID window_request_gen_id; + JA_WindowRequest* window_request_first; + JA_WindowRequest* window_request_last; + JA_WindowRequest* free_window_request; // Windows JA_WindowState* free_window_state; @@ -43,7 +74,6 @@ struct JA_State JA_WindowState* first_window_state; JA_WindowState* last_window_state; JA_ID window_state_last_accessed_id; - JA_ID window_state_gen_id; JA_WindowState* window_state_last_accessed; }; @@ -61,7 +91,15 @@ internal void ja_init(); internal void ja_frame(); internal void ja_shutdown(); +// ============================================================================= +// Id Functions + +internal void ja_id_list_push(Arena* arena, JA_IDList* list, JA_ID id); + // ============================================================================= // Window Functions -internal JA_WindowState* ja_window_state_from_id(JA_ID id); +internal JA_WindowState* ja_window_state_from_id(JA_ID id); +internal void ja_window_request(); +internal void ja_window_close_request(JA_WindowRequest* request); +internal JA_WindowRequest* ja_window_request_from_id(JA_ID id); diff --git a/Juliet/win32/window_manager/window_manager.c b/Juliet/win32/window_manager/window_manager.c index b214461..3e88911 100644 --- a/Juliet/win32/window_manager/window_manager.c +++ b/Juliet/win32/window_manager/window_manager.c @@ -81,7 +81,7 @@ internal W32_WM_Window* w32_wm_window_alloc(HWND hwnd) internal WM_Event* w32_wm_push_event(WM_EventKind kind, W32_WM_Window* window) { - WM_Event* result = 0; + WM_Event* result = wm_event_list_push_new(w32_wm_event_arena, &w32_wm_event_list, kind); result->window = w32_wm_handle_from_window(window); result->modifiers = wm_get_modifiers(); return result;