diff --git a/src/backup/todo.txt b/src/backup/todo.txt index cc37ad6..f411efd 100644 --- a/src/backup/todo.txt +++ b/src/backup/todo.txt @@ -3,6 +3,7 @@ Debug session: - Report errorf - use coroutine dialogs + - Replace in render layer also Use session 1: - OpenCommand in command window freezes the app diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index 2dcedca..ff6ec94 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -654,12 +654,11 @@ String CodeSkipPatterns[] = {".git/", ".obj", ".o", ".pdb", ".exe"}; String Coro_OpenCodeDir; void Coro_OpenCode(mco_coro *co) { - BlockArena arena = {}; - Array dirs = {arena}; + Array dirs = {CoCurr->arena}; Add(&dirs, Coro_OpenCodeDir); int i = 0; for (int diri = 0; diri < dirs.len; diri += 1) { - for (FileIter it = IterateFiles(arena, dirs[diri]); IsValid(it); Advance(&it)) { + for (FileIter it = IterateFiles(CoCurr->arena, dirs[diri]); IsValid(it); Advance(&it)) { bool match = false; for (int endings_i = 0; endings_i < Lengthof(CodeSkipPatterns); endings_i += 1) { String ending = CodeSkipPatterns[endings_i]; @@ -680,7 +679,6 @@ void Coro_OpenCode(mco_coro *co) { CoYield(co); } } - Release(&arena); } void OpenCode(String dir) { @@ -707,6 +705,7 @@ void AddHook(Array *arr, String name, String binding, Function *fun Add(arr, n); } +// @todo: rename to temp buffer? but there is already a thing like that... String Coro_YesNoCancel(mco_coro *co, BSet main, String question) { JumpGarbageBuffer(&main); NextActiveWindowID = main.window->id; @@ -766,8 +765,7 @@ void Coro_Close(mco_coro *co) { return; } - Scratch scratch; - String question = Format(scratch, "Do you want to save [%S] before closing?", main.buffer->name); + String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", main.buffer->name); String result = Coro_YesNoCancel(co, main, question); if (result == "Yes") { SaveBuffer(main.buffer); @@ -786,10 +784,10 @@ void Command_Close() { // Considerations with coroutines: // 1. Does scratch memory leak across Yield boundary? Or interacts badly with Yield stuff in any way? // 2. Are pointers and globals correct over time? Or might they get deleted etc. +// 3. Imagine a scenario where the coroutine gets deleted before completion, will the memory leak? String Coro_CloseAllEx(mco_coro *co) { - Scratch scratch; BSet main = GetBSet(LastActiveLayoutWindowID); - Array buffers = {scratch}; + Array buffers = {CoCurr->arena}; For (Buffers) Add(&buffers, it->id); ForItem (id, buffers) { Buffer *it = GetBuffer(id); @@ -800,7 +798,7 @@ String Coro_CloseAllEx(mco_coro *co) { continue; } - String question = Format(scratch, "Do you want to save [%S] before closing?", it->name); + String question = Format(CoCurr->arena, "Do you want to save [%S] before closing?", it->name); String result = Coro_YesNoCancel(co, main, question); it = GetBuffer(id, NULL); if (it && result == "Yes") { diff --git a/src/text_editor/coroutines.cpp b/src/text_editor/coroutines.cpp index 34067e7..bff67d4 100644 --- a/src/text_editor/coroutines.cpp +++ b/src/text_editor/coroutines.cpp @@ -1,10 +1,17 @@ typedef void CoroutineProc(mco_coro *co); +CoData *CoCurr = NULL; + +void CoDestroy(CoData *n) { + mco_destroy(n->co); + Release(&n->arena); +} void CoRemove(String name) { IterRemove(ActiveCoroutines) { IterRemovePrepare(ActiveCoroutines); if (it.name == name) { mco_destroy(it.co); + Release(&it.arena); remove_item = true; } } @@ -15,15 +22,19 @@ CoData *CoAddEx(CoroutineProc *proc, String name) { CoRemove(name); mco_desc desc = mco_desc_init(proc, 0); - mco_coro *coro = NULL; - mco_result ok = mco_create(&coro, &desc); + mco_coro *coro = NULL; + mco_result ok = mco_create(&coro, &desc); if (ok != MCO_SUCCESS) { ReportWarningf("failed to create coroutine %d", ok); return NULL; } - mco_resume(coro); Add(&ActiveCoroutines, {coro, name}); + CoData *prev_curr = CoCurr; + CoCurr = GetLast(ActiveCoroutines); + ok = mco_resume(coro); + Assert(ok == MCO_SUCCESS); + CoCurr = prev_curr; return GetLast(ActiveCoroutines); } @@ -37,14 +48,15 @@ void CoUpdate(Event *event) { mco_state status = mco_status(it.co); if (status == MCO_DEAD) { - mco_destroy(it.co); + CoDestroy(&it); remove_item = true; } else { mco_push(it.co, &event, sizeof(Event *)); + CoCurr = ⁢ mco_result ok = mco_resume(it.co); if (ok != MCO_SUCCESS) { ReportWarningf("failed to resume coroutine %d", ok); - mco_destroy(it.co); + CoDestroy(&it); remove_item = true; } } diff --git a/src/text_editor/globals.cpp b/src/text_editor/globals.cpp index feb14ee..b2ba2d7 100644 --- a/src/text_editor/globals.cpp +++ b/src/text_editor/globals.cpp @@ -87,7 +87,7 @@ Array Variables; Array ActiveProcesses = {}; Array ProcessEnviroment = {}; -struct CoData { mco_coro *co; String name; bool dont_wait_until_resolved; }; +struct CoData { mco_coro *co; String name; BlockArena arena; bool dont_wait_until_resolved; void *user_ctx; }; Array ActiveCoroutines;