Print loaded files and errors, enable loading and searching
This commit is contained in:
@@ -401,10 +401,10 @@ struct Array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bounded_add(T item) {
|
void bounded_add(T item) {
|
||||||
Assert(len + 1 <= cap);
|
if (len + 1 <= cap) {
|
||||||
try_growing(); // in case of error
|
|
||||||
data[len++] = item;
|
data[len++] = item;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
T *alloc(const T &item) {
|
T *alloc(const T &item) {
|
||||||
try_growing();
|
try_growing();
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ struct ThreadCtx {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct WorkQueue {
|
struct WorkQueue {
|
||||||
|
int32_t thread_count;
|
||||||
WorkQueueEntry entries[256];
|
WorkQueueEntry entries[256];
|
||||||
int64_t volatile index_to_write;
|
int64_t volatile index_to_write;
|
||||||
int64_t volatile index_to_read;
|
int64_t volatile index_to_read;
|
||||||
@@ -28,3 +29,5 @@ struct ThreadStartupInfo {
|
|||||||
void PushWork(WorkQueue *wq, void *data, WorkQueueCallback *callback);
|
void PushWork(WorkQueue *wq, void *data, WorkQueueCallback *callback);
|
||||||
void InitWorkQueue(WorkQueue *queue, uint32_t thread_count, ThreadStartupInfo *info);
|
void InitWorkQueue(WorkQueue *queue, uint32_t thread_count, ThreadStartupInfo *info);
|
||||||
void WaitUntilCompletion(WorkQueue *wq);
|
void WaitUntilCompletion(WorkQueue *wq);
|
||||||
|
|
||||||
|
int64_t AtomicIncrement(volatile int64_t *i);
|
||||||
@@ -51,6 +51,7 @@ DWORD WINAPI WorkQueueThreadEntry(LPVOID param) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InitWorkQueue(WorkQueue *queue, uint32_t thread_count, ThreadStartupInfo *info) {
|
void InitWorkQueue(WorkQueue *queue, uint32_t thread_count, ThreadStartupInfo *info) {
|
||||||
|
queue->thread_count = thread_count;
|
||||||
queue->index_to_read = 0;
|
queue->index_to_read = 0;
|
||||||
queue->index_to_write = 0;
|
queue->index_to_write = 0;
|
||||||
queue->completion_index = 0;
|
queue->completion_index = 0;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ Array<TimeString> ParseSrtFile(Arena *arena, String filename) {
|
|||||||
for (int i = 0; i < lines.len;) {
|
for (int i = 0; i < lines.len;) {
|
||||||
String it0 = lines[i++];
|
String it0 = lines[i++];
|
||||||
long num = strtol(it0.data, NULL, 10);
|
long num = strtol(it0.data, NULL, 10);
|
||||||
Assert(section_number == num);
|
Assert(section_number == num); // @todo: error
|
||||||
section_number += 1;
|
section_number += 1;
|
||||||
|
|
||||||
TimeString item = {};
|
TimeString item = {};
|
||||||
|
|||||||
@@ -65,9 +65,24 @@ struct XToTimeString {
|
|||||||
String filepath;
|
String filepath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FileLoadResult {
|
||||||
|
String filename;
|
||||||
|
String error;
|
||||||
|
};
|
||||||
|
|
||||||
Arena XArena;
|
Arena XArena;
|
||||||
std::mutex XArenaAddMutex;
|
std::mutex XArenaAddMutex;
|
||||||
Array<XToTimeString> XToTime;
|
Array<XToTimeString> XToTime;
|
||||||
|
Array<FileLoadResult> XFileLoadResults;
|
||||||
|
int64_t XLoadThreadComplete;
|
||||||
|
|
||||||
|
void XInitLoading() {
|
||||||
|
InitArena(&XArena);
|
||||||
|
XArena.align = 0;
|
||||||
|
|
||||||
|
XToTime.reserve(1000000);
|
||||||
|
XFileLoadResults.reserve(10000);
|
||||||
|
}
|
||||||
|
|
||||||
WORK_FUNCTION(ParseFilesWork) {
|
WORK_FUNCTION(ParseFilesWork) {
|
||||||
ParseThreadIO *io = (ParseThreadIO *)data;
|
ParseThreadIO *io = (ParseThreadIO *)data;
|
||||||
@@ -82,12 +97,27 @@ WORK_FUNCTION(ParseFilesWork) {
|
|||||||
XToTime.add({s, it.hour, it.minute, it.second, it_time_file});
|
XToTime.add({s, it.hour, it.minute, it.second, it_time_file});
|
||||||
}
|
}
|
||||||
XArenaAddMutex.unlock();
|
XArenaAddMutex.unlock();
|
||||||
|
XFileLoadResults.bounded_add({it_time_file});
|
||||||
}
|
}
|
||||||
|
AtomicIncrement(&XLoadThreadComplete);
|
||||||
|
}
|
||||||
|
|
||||||
|
String XGetArenaString() {
|
||||||
|
XArenaAddMutex.lock();
|
||||||
|
String buffer = {(char *)XArena.data, (int64_t)XArena.len};
|
||||||
|
XArenaAddMutex.unlock();
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<FileLoadResult> XLockFileLoadResults() {
|
||||||
|
return XFileLoadResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XUnlockFileResults() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XAddFolder(String folder, Array<String> *filenames) {
|
void XAddFolder(String folder, Array<String> *filenames) {
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
|
|
||||||
Array<String> srt_files = {scratch};
|
Array<String> srt_files = {scratch};
|
||||||
for (FileIter iter = IterateFiles(scratch, folder); IsValid(iter); Advance(&iter)) {
|
for (FileIter iter = IterateFiles(scratch, folder); IsValid(iter); Advance(&iter)) {
|
||||||
String file = Copy(Perm, iter.absolute_path);
|
String file = Copy(Perm, iter.absolute_path);
|
||||||
@@ -97,15 +127,20 @@ void XAddFolder(String folder, Array<String> *filenames) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t thread_count = 16;
|
if (srt_files.len == 0) {
|
||||||
|
XFileLoadResults.add({Copy(Perm, folder), "no files found"});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t thread_count = MainWorkQueue.thread_count;
|
||||||
int64_t files_per_thread = srt_files.len / thread_count;
|
int64_t files_per_thread = srt_files.len / thread_count;
|
||||||
int64_t remainder = srt_files.len % thread_count;
|
int64_t remainder = srt_files.len % thread_count;
|
||||||
int64_t fi = 0;
|
int64_t fi = 0;
|
||||||
|
|
||||||
Array<ParseThreadIO> io = {scratch};
|
Array<ParseThreadIO> io = {Perm};
|
||||||
io.reserve(thread_count);
|
io.reserve(thread_count);
|
||||||
for (int ti = 0; ti < thread_count; ti += 1) {
|
for (int ti = 0; ti < thread_count; ti += 1) {
|
||||||
Array<String> files = {scratch};
|
Array<String> files = {Perm};
|
||||||
for (int i = 0; fi < srt_files.len && i < files_per_thread + remainder; fi += 1, i += 1) {
|
for (int i = 0; fi < srt_files.len && i < files_per_thread + remainder; fi += 1, i += 1) {
|
||||||
files.add(srt_files[fi]);
|
files.add(srt_files[fi]);
|
||||||
}
|
}
|
||||||
@@ -115,18 +150,27 @@ void XAddFolder(String folder, Array<String> *filenames) {
|
|||||||
i->input_files = files;
|
i->input_files = files;
|
||||||
PushWork(&MainWorkQueue, (void *)i, ParseFilesWork);
|
PushWork(&MainWorkQueue, (void *)i, ParseFilesWork);
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitUntilCompletion(&MainWorkQueue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XToTimeString *XFindItem(String string) {
|
XToTimeString *XFindItem(String string) {
|
||||||
|
XToTimeString *result = NULL;
|
||||||
|
|
||||||
|
XArenaAddMutex.lock();
|
||||||
For(XToTime) {
|
For(XToTime) {
|
||||||
uintptr_t begin = (uintptr_t)(it.string.data);
|
uintptr_t begin = (uintptr_t)(it.string.data);
|
||||||
uintptr_t end = (uintptr_t)(it.string.data + it.string.len);
|
uintptr_t end = (uintptr_t)(it.string.data + it.string.len);
|
||||||
uintptr_t needle = (uintptr_t)string.data;
|
uintptr_t needle = (uintptr_t)string.data;
|
||||||
if (needle >= begin && needle < end) {
|
if (needle >= begin && needle < end) {
|
||||||
return ⁢
|
result = ⁢
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
XArenaAddMutex.unlock();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XLoadingComplete() {
|
||||||
|
bool result = MainWorkQueue.thread_count == XLoadThreadComplete;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
@@ -3,8 +3,6 @@
|
|||||||
#include "../basic/filesystem.h"
|
#include "../basic/filesystem.h"
|
||||||
#include "../basic/thread_queue.h"
|
#include "../basic/thread_queue.h"
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#include <semaphore>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@@ -20,25 +18,98 @@ WorkQueue MainWorkQueue;
|
|||||||
#include "loading_thread.cpp"
|
#include "loading_thread.cpp"
|
||||||
#include "searching_thread.cpp"
|
#include "searching_thread.cpp"
|
||||||
|
|
||||||
/*
|
void UISearchResults(Array<String> filenames) {
|
||||||
|
Scratch scratch;
|
||||||
|
Array<String> matches = LockSearchResults();
|
||||||
|
defer { UnlockSearchResults(); };
|
||||||
|
|
||||||
TODO:
|
float font_size = ImGui::GetFontSize();
|
||||||
- New threading model idea: I could just spin up a bunch of threads and then don't kill them. Just use them for searching! Each one would have it's own xarena and so on.
|
ImFont *font = ImGui::GetFont();
|
||||||
*/
|
const ImGuiViewport *main_viewport = ImGui::GetMainViewport();
|
||||||
|
|
||||||
//
|
int64_t chars_per_line = (int64_t)(main_viewport->WorkSize.x / 2) / (int64_t)font->GetCharAdvance('_') - strlen(Prompt) * 2;
|
||||||
// Searching thread
|
|
||||||
//
|
ImGuiListClipper clipper;
|
||||||
|
clipper.Begin((int)matches.len);
|
||||||
|
while (clipper.Step()) {
|
||||||
|
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||||
|
ImGui::PushID(i);
|
||||||
|
defer { ImGui::PopID(); };
|
||||||
|
auto &it = matches[i];
|
||||||
|
uintptr_t begin_region = (uintptr_t)XArena.data;
|
||||||
|
uintptr_t end_region = (uintptr_t)XArena.data + XArena.len;
|
||||||
|
|
||||||
|
uint64_t begin = (uintptr_t)(it.data - chars_per_line / 2);
|
||||||
|
uint64_t end = (uintptr_t)(it.data + it.len + chars_per_line / 2);
|
||||||
|
|
||||||
|
uint64_t a = Clamp(begin, begin_region, end_region);
|
||||||
|
uint64_t b = Clamp((uintptr_t)it.data, begin_region, end_region);
|
||||||
|
String left = {(char *)a, (int64_t)(b - a)};
|
||||||
|
|
||||||
|
uint64_t c = Clamp((uintptr_t)(it.data + it.len), begin_region, end_region);
|
||||||
|
uint64_t d = Clamp(end, begin_region, end_region);
|
||||||
|
String right = {(char *)c, (int64_t)(d - c)};
|
||||||
|
|
||||||
|
String middle = it;
|
||||||
|
String string = Format(scratch, "%.*s**%.*s**%.*s",
|
||||||
|
FmtString(left), FmtString(middle), FmtString(right));
|
||||||
|
|
||||||
|
XToTimeString *item = XFindItem(middle);
|
||||||
|
if (ImGui::Button(string.data)) {
|
||||||
|
String base = ChopLastPeriod(item->filepath); // .srt
|
||||||
|
base = ChopLastPeriod(base); // .en
|
||||||
|
|
||||||
|
For(filenames) {
|
||||||
|
if (StartsWith(it, base)) {
|
||||||
|
if (EndsWith(it, ".mkv") || EndsWith(it, ".webm") || EndsWith(it, ".mp4")) {
|
||||||
|
int seconds = item->hour * 60 * 60 + item->minute * 60 + item->second;
|
||||||
|
String copy = Copy(scratch, it);
|
||||||
|
for (int i = 0; i < copy.len; i += 1)
|
||||||
|
if (copy.data[i] == '/') copy.data[i] = '\\';
|
||||||
|
String args = Format(scratch, "C:\\Program Files\\VideoLAN\\VLC\\vlc.exe --start-time %d \"%.*s\"", seconds, FmtString(copy));
|
||||||
|
RunEx(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text(SkipToLastSlash(item->filepath).data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UILoadedFiles() {
|
||||||
|
Scratch scratch;
|
||||||
|
Array<FileLoadResult> file_load_results = XLockFileLoadResults();
|
||||||
|
defer { XUnlockFileResults(); };
|
||||||
|
|
||||||
|
ImGuiListClipper clipper;
|
||||||
|
clipper.Begin((int)file_load_results.len);
|
||||||
|
while (clipper.Step()) {
|
||||||
|
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||||
|
FileLoadResult file = file_load_results[file_load_results.len - 1 - i];
|
||||||
|
if (file.error.len) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)ImColor::HSV(7.0f, 0.6f, 0.6f));
|
||||||
|
String string = Format(scratch, "%.*s error: %.*s", FmtString(file.filename), FmtString(file.error));
|
||||||
|
ImGui::Text(string.data);
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
} else {
|
||||||
|
String string = Format(scratch, "%.*s loaded", FmtString(file.filename));
|
||||||
|
ImGui::Text(string.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int, char **) {
|
int main(int, char **) {
|
||||||
InitOS();
|
InitOS();
|
||||||
InitScratch();
|
InitScratch();
|
||||||
InitArena(&Perm);
|
InitArena(&Perm);
|
||||||
InitArena(&XArena);
|
|
||||||
XArena.align = 0;
|
|
||||||
|
|
||||||
|
XInitLoading();
|
||||||
|
InitSearch();
|
||||||
ThreadStartupInfo infos[16] = {};
|
ThreadStartupInfo infos[16] = {};
|
||||||
InitWorkQueue(&MainWorkQueue, 16, infos);
|
InitWorkQueue(&MainWorkQueue, Lengthof(infos), infos);
|
||||||
|
|
||||||
memcpy(Prompt, "read=D:/zizek", sizeof("read=D:/zizek"));
|
memcpy(Prompt, "read=D:/zizek", sizeof("read=D:/zizek"));
|
||||||
|
|
||||||
@@ -93,11 +164,9 @@ int main(int, char **) {
|
|||||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||||
io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
|
||||||
|
|
||||||
// Our state
|
|
||||||
bool show_demo_window = true;
|
|
||||||
bool show_another_window = false;
|
|
||||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||||
|
|
||||||
|
bool show_loaded_files = false;
|
||||||
bool set_focus_to_input = true;
|
bool set_focus_to_input = true;
|
||||||
int64_t frame = -1;
|
int64_t frame = -1;
|
||||||
|
|
||||||
@@ -111,6 +180,7 @@ int main(int, char **) {
|
|||||||
bool set_focus_to_list = false;
|
bool set_focus_to_list = false;
|
||||||
bool tab_press = false;
|
bool tab_press = false;
|
||||||
bool enter_press = false;
|
bool enter_press = false;
|
||||||
|
bool f1_press = false;
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
#if 1
|
#if 1
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
@@ -127,6 +197,8 @@ int main(int, char **) {
|
|||||||
set_focus_to_input = true;
|
set_focus_to_input = true;
|
||||||
} else if (event.key.keysym.sym == SDLK_TAB) {
|
} else if (event.key.keysym.sym == SDLK_TAB) {
|
||||||
tab_press = true;
|
tab_press = true;
|
||||||
|
} else if (event.key.keysym.sym == SDLK_F1) {
|
||||||
|
f1_press = true;
|
||||||
}
|
}
|
||||||
} else if (event.type == SDL_KEYUP) {
|
} else if (event.type == SDL_KEYUP) {
|
||||||
|
|
||||||
@@ -151,11 +223,16 @@ int main(int, char **) {
|
|||||||
ImGui::SetNextWindowSize(ImVec2(main_viewport->Size.x, 20), ImGuiCond_Always);
|
ImGui::SetNextWindowSize(ImVec2(main_viewport->Size.x, 20), ImGuiCond_Always);
|
||||||
|
|
||||||
ImGui::Begin("input", NULL, window_flags);
|
ImGui::Begin("input", NULL, window_flags);
|
||||||
|
if (ImGui::Button("Show loaded files") || f1_press) {
|
||||||
|
show_loaded_files = !show_loaded_files;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
if (set_focus_to_input) ImGui::SetKeyboardFocusHere(0);
|
if (set_focus_to_input) ImGui::SetKeyboardFocusHere(0);
|
||||||
if (tab_press && ImGui::IsWindowFocused()) set_focus_to_list = true;
|
if (tab_press && ImGui::IsWindowFocused()) set_focus_to_list = true;
|
||||||
if (ImGui::InputText("Input your query", Prompt, sizeof(Prompt))) {
|
if (ImGui::InputText("Input your query", Prompt, sizeof(Prompt))) {
|
||||||
StartSearchingForMatches();
|
StartSearchingForMatches();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
if (enter_press) {
|
if (enter_press) {
|
||||||
@@ -175,60 +252,10 @@ int main(int, char **) {
|
|||||||
|
|
||||||
ImGui::Begin("result", NULL, window_flags);
|
ImGui::Begin("result", NULL, window_flags);
|
||||||
if (!ImGui::IsWindowFocused() && set_focus_to_list) ImGui::SetKeyboardFocusHere(0);
|
if (!ImGui::IsWindowFocused() && set_focus_to_list) ImGui::SetKeyboardFocusHere(0);
|
||||||
|
if (show_loaded_files) {
|
||||||
Array<String> matches = LockSearchResults();
|
UILoadedFiles();
|
||||||
defer { UnlockSearchResults(); };
|
} else {
|
||||||
|
UISearchResults(filenames);
|
||||||
float font_size = ImGui::GetFontSize();
|
|
||||||
ImFont *font = ImGui::GetFont();
|
|
||||||
int64_t chars_per_line = (int64_t)(main_viewport->WorkSize.x / 2) / (int64_t)font->GetCharAdvance('_') - strlen(Prompt) * 2;
|
|
||||||
|
|
||||||
ImGuiListClipper clipper;
|
|
||||||
clipper.Begin((int)matches.len);
|
|
||||||
while (clipper.Step()) {
|
|
||||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
|
||||||
ImGui::PushID(i);
|
|
||||||
defer { ImGui::PopID(); };
|
|
||||||
auto &it = matches[i];
|
|
||||||
uintptr_t begin_region = (uintptr_t)XArena.data;
|
|
||||||
uintptr_t end_region = (uintptr_t)XArena.data + XArena.len;
|
|
||||||
|
|
||||||
uint64_t begin = (uintptr_t)(it.data - chars_per_line / 2);
|
|
||||||
uint64_t end = (uintptr_t)(it.data + it.len + chars_per_line / 2);
|
|
||||||
|
|
||||||
uint64_t a = Clamp(begin, begin_region, end_region);
|
|
||||||
uint64_t b = Clamp((uintptr_t)it.data, begin_region, end_region);
|
|
||||||
String left = {(char *)a, (int64_t)(b - a)};
|
|
||||||
|
|
||||||
uint64_t c = Clamp((uintptr_t)(it.data + it.len), begin_region, end_region);
|
|
||||||
uint64_t d = Clamp(end, begin_region, end_region);
|
|
||||||
String right = {(char *)c, (int64_t)(d - c)};
|
|
||||||
|
|
||||||
String middle = it;
|
|
||||||
String string = Format(frame_arena, "%.*s**%.*s**%.*s",
|
|
||||||
FmtString(left), FmtString(middle), FmtString(right));
|
|
||||||
|
|
||||||
XToTimeString *item = XFindItem(middle);
|
|
||||||
if (ImGui::Button(string.data)) {
|
|
||||||
String base = ChopLastPeriod(item->filepath); // .srt
|
|
||||||
base = ChopLastPeriod(base); // .en
|
|
||||||
|
|
||||||
For(filenames) {
|
|
||||||
if (StartsWith(it, base)) {
|
|
||||||
if (EndsWith(it, ".mkv") || EndsWith(it, ".webm") || EndsWith(it, ".mp4")) {
|
|
||||||
int seconds = item->hour * 60 * 60 + item->minute * 60 + item->second;
|
|
||||||
String copy = Copy(*frame_arena, it);
|
|
||||||
for (int i = 0; i < copy.len; i += 1)
|
|
||||||
if (copy.data[i] == '/') copy.data[i] = '\\';
|
|
||||||
String args = Format(*frame_arena, "C:\\Program Files\\VideoLAN\\VLC\\vlc.exe --start-time %d \"%.*s\"", seconds, FmtString(copy));
|
|
||||||
RunEx(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::Text(SkipToLastSlash(item->filepath).data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
Array<String> Matches = {};
|
Array<String> Matches = {};
|
||||||
char Prompt[256];
|
char Prompt[256];
|
||||||
std::mutex SearchThreadArrayMutex;
|
std::mutex SearchThreadArrayMutex;
|
||||||
bool SearchThreadStopSearching;
|
int64_t SearchThreadStopSearching;
|
||||||
|
|
||||||
WORK_FUNCTION(SearchForMatchesWork) {
|
WORK_FUNCTION(SearchForMatchesWork) {
|
||||||
if (Prompt[0] == 0) return;
|
if (Prompt[0] == 0) return;
|
||||||
|
|
||||||
|
int64_t search_thread_stop_searching = SearchThreadStopSearching;
|
||||||
|
|
||||||
SearchThreadArrayMutex.lock();
|
SearchThreadArrayMutex.lock();
|
||||||
Matches.clear();
|
Matches.clear();
|
||||||
SearchThreadArrayMutex.unlock();
|
SearchThreadArrayMutex.unlock();
|
||||||
|
|
||||||
String buffer = {(char *)XArena.data, (int64_t)XArena.len};
|
String buffer = XGetArenaString();
|
||||||
String find = Prompt;
|
String find = Prompt;
|
||||||
int64_t index = 0;
|
int64_t index = 0;
|
||||||
while (Seek(buffer, find, &index, SeekFlag_IgnoreCase)) {
|
while (Seek(buffer, find, &index, SeekFlag_IgnoreCase)) {
|
||||||
String found = {buffer.data + index, find.len};
|
String found = {buffer.data + index, find.len};
|
||||||
Matches.add(found);
|
Matches.bounded_add(found);
|
||||||
buffer = buffer.skip(index + find.len);
|
buffer = buffer.skip(index + find.len);
|
||||||
if (SearchThreadStopSearching) return;
|
if (search_thread_stop_searching != SearchThreadStopSearching) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartSearchingForMatches() {
|
void StartSearchingForMatches() {
|
||||||
SearchThreadStopSearching = true;
|
SearchThreadStopSearching += 1;
|
||||||
WaitUntilCompletion(&MainWorkQueue);
|
|
||||||
SearchThreadStopSearching = false;
|
|
||||||
PushWork(&MainWorkQueue, NULL, SearchForMatchesWork);
|
PushWork(&MainWorkQueue, NULL, SearchForMatchesWork);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,3 +37,7 @@ Array<String> LockSearchResults() {
|
|||||||
void UnlockSearchResults() {
|
void UnlockSearchResults() {
|
||||||
SearchThreadArrayMutex.unlock();
|
SearchThreadArrayMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitSearch() {
|
||||||
|
Matches.reserve(100000);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user