diff --git a/CYD-Klipper/src/core/files_query.cpp b/CYD-Klipper/src/core/files_query.cpp index fec496c..85acfa1 100644 --- a/CYD-Klipper/src/core/files_query.cpp +++ b/CYD-Klipper/src/core/files_query.cpp @@ -9,7 +9,7 @@ // Always has +1 entry with a null'd name FILESYSTEM_FILE* last_query = NULL; -FILESYSTEM_FILE* get_files(){ +FILESYSTEM_FILE* get_files(int limit){ freeze_request_thread(); if (last_query != NULL){ @@ -22,42 +22,77 @@ FILESYSTEM_FILE* get_files(){ free(last_query); } + Serial.printf("Heap space pre-file-parse: %d bytes\n", esp_get_free_heap_size()); std::list files; + + auto timer_request = millis(); char buff[256] = {}; sprintf(buff, "http://%s:%d/server/files/list", global_config.klipperHost, global_config.klipperPort); HTTPClient client; client.useHTTP10(true); client.begin(buff); int httpCode = client.GET(); - int count = 0; + auto timer_parse = millis(); + if (httpCode == 200){ JsonDocument doc; auto parseResult = deserializeJson(doc, client.getStream()); Serial.printf("Json parse: %s\n", parseResult.c_str()); auto result = doc["result"].as(); + for (auto file : result){ FILESYSTEM_FILE f = {0}; const char* path = file["path"]; + float modified = file["modified"]; + auto file_iter = files.begin(); + + while (file_iter != files.end()){ + if ((*file_iter).modified < modified) + break; + + file_iter++; + } + + // Little inefficient as it always allocates a string, even if it doesn't have to f.name = (char*)malloc(strlen(path) + 1); if (f.name == NULL){ Serial.println("Failed to allocate memory"); continue; } strcpy(f.name, path); - f.modified = file["modified"]; - files.push_back(f); - count++; + f.modified = modified; + + if (file_iter != files.end()) + files.insert(file_iter, f); + else + files.push_back(f); + + if (files.size() > limit){ + auto last_entry = files.back(); + + if (last_entry.name != NULL) + free(last_entry.name); + + files.pop_back(); + } } } - //Serial.printf("Found %d files\n", count); - files.sort([](FILESYSTEM_FILE a, FILESYSTEM_FILE b){return a.modified < b.modified;}); - files.reverse(); // TODO: Reverse is unneeded here, we can iterate backwards - size_t size = sizeof(FILESYSTEM_FILE) * (files.size() + 1); FILESYSTEM_FILE* result = (FILESYSTEM_FILE*)malloc(size); - //Serial.printf("Allocated %d bytes\n", size); + + if (result == NULL){ + Serial.println("Failed to allocate memory"); + + for (auto file : files){ + free(file.name); + } + + unfreeze_request_thread(); + return NULL; + } + last_query = result; result[files.size()].name = NULL; @@ -67,6 +102,7 @@ FILESYSTEM_FILE* get_files(){ } Serial.printf("Heap space post-file-parse: %d bytes\n", esp_get_free_heap_size()); + Serial.printf("Got %d files. Request took %dms, parsing took %dms\n", files.size(), timer_parse - timer_request, millis() - timer_parse); unfreeze_request_thread(); return last_query; } \ No newline at end of file diff --git a/CYD-Klipper/src/core/files_query.h b/CYD-Klipper/src/core/files_query.h index a5c6cbc..efb8b12 100644 --- a/CYD-Klipper/src/core/files_query.h +++ b/CYD-Klipper/src/core/files_query.h @@ -19,4 +19,4 @@ typedef struct _FILESYSTEM_FILE { float modified; } FILESYSTEM_FILE; -FILESYSTEM_FILE* get_files(); \ No newline at end of file +FILESYSTEM_FILE* get_files(int limit); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/print_panel.cpp b/CYD-Klipper/src/ui/panels/print_panel.cpp index a44d9b6..e0a1cd6 100644 --- a/CYD-Klipper/src/ui/panels/print_panel.cpp +++ b/CYD-Klipper/src/ui/panels/print_panel.cpp @@ -95,13 +95,20 @@ void print_panel_init(lv_obj_t* panel){ lv_obj_set_size(list, panel_width_margin, panel_height_margin); lv_obj_align(list, LV_ALIGN_CENTER, 0, 0); - FILESYSTEM_FILE* files = get_files(); + FILESYSTEM_FILE* files = get_files(25); int count = 0; - while (files->name != NULL && count <= 20){ + while (files != NULL && files->name != NULL && count <= 20){ lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, files->name); lv_obj_add_event_cb(btn, btn_print_file_verify, LV_EVENT_CLICKED, (void*)files); files += 1; count++; } + + if (count <= 0){ + lv_obj_del(list); + lv_obj_t * label = lv_label_create(panel); + lv_label_set_text(label, "Failed to read files."); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + } } \ No newline at end of file