diff --git a/src/helper_funcs.cpp b/src/helper_funcs.cpp index bc68699..3da0f21 100644 --- a/src/helper_funcs.cpp +++ b/src/helper_funcs.cpp @@ -1,5 +1,7 @@ #include "helper_funcs.h" #include "color.h" +#include "main.h" +#include "memory.h" #include "net.h" #include #include @@ -13,7 +15,9 @@ #include #include #include -#include "main.h" +#include + +std::vector *current_allocated; void safe_exit(int code) { switch (code) { @@ -38,6 +42,7 @@ void safe_exit(int code) { default: break; } + delete_all(current_allocated); curl_easy_cleanup(curl); endwin(); @@ -152,9 +157,11 @@ void wprint_in_middle(WINDOW *win, int starty, int startx, int width, x = startx + (int)temp; wattron(win, color); if (mvwaddwstr(win, y, x, string) == ERR) { - if(config.verbose){ - std::wcerr << RED"[ERROR]"<< RESET" wprint_in_middle failed to print " << string << "\n"; - }} + if (config.verbose) { + std::wcerr << RED "[ERROR]" << RESET " wprint_in_middle failed to print " + << string << "\n"; + } + } wattroff(win, color); refresh(); } diff --git a/src/helper_funcs.h b/src/helper_funcs.h index 6f58408..830297d 100644 --- a/src/helper_funcs.h +++ b/src/helper_funcs.h @@ -1,10 +1,14 @@ +#include "memory.h" #include #include +#include // header guard #ifndef _ba_hf_hg_ #define _ba_hf_hg_ +extern std::vector *current_allocated; + #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) void safe_exit(int code); diff --git a/src/marks.cpp b/src/marks.cpp index 2847465..bee4128 100644 --- a/src/marks.cpp +++ b/src/marks.cpp @@ -1,5 +1,6 @@ #include "marks.h" #include "helper_funcs.h" +#include "memory.h" #include "net.h" #include #include @@ -12,6 +13,7 @@ #include #include #include +#include using nlohmann::json; @@ -27,23 +29,26 @@ using nlohmann::json; #define DEFAULT_PADDING 4 +std::vector marks_allocated; + void init_wins(WINDOW **wins, int n, json marks_json); void win_show(WINDOW *win, wchar_t *label, int label_color, int width, int height, json marks_json, int SubjectIndex); void marks_page() { + current_allocated = &marks_allocated; json resp_from_api; { - std::string endpoint = "api/3/marks"; - resp_from_api = bakaapi::get_data_from_endpoint(endpoint); + std::string endpoint = "api/3/marks"; + resp_from_api = bakaapi::get_data_from_endpoint(endpoint); } - WINDOW **my_wins; size_t size_my_wins = resp_from_api["Subjects"].size(); - my_wins = new (std::nothrow) WINDOW *[size_my_wins]; + WINDOW **my_wins = new (std::nothrow) WINDOW *[size_my_wins]; + marks_allocated.push_back({WINDOW_ARRAY, my_wins, size_my_wins}); - PANEL **my_panels; size_t size_my_panels = resp_from_api["Subjects"].size(); - my_panels = new (std::nothrow) PANEL *[size_my_panels]; + PANEL **my_panels = new (std::nothrow) PANEL *[size_my_panels]; + marks_allocated.push_back({PANEL_ARRAY, my_panels, size_my_panels}); // trows compiler warning for some reason but cannot be removed PANEL *top; @@ -66,7 +71,9 @@ void marks_page() { // store all original window position int *original_y = new int[size_my_wins]; + marks_allocated.push_back({GENERIC_ARRAY, original_y, size_my_wins}); int *original_x = new int[size_my_wins]; + marks_allocated.push_back({GENERIC_ARRAY, original_x, size_my_wins}); for (size_t i = 0; i < size_my_wins; ++i) { getbegyx(my_wins[i], original_y[i], original_x[i]); } @@ -121,10 +128,7 @@ void marks_page() { // Cleanup endwin(); clear(); - delete[] my_wins; - delete[] my_panels; - delete[] original_y; - delete[] original_x; + delete_all(&marks_allocated); } /* Put all the windows */ @@ -153,7 +157,9 @@ void init_wins(WINDOW **wins, int n, json marks_json) { wsub_name.c_str(), wsub_avg_s.c_str()); size_t max_text_length = wcslen(label); - for (unsigned int j = 0; j < static_cast(marks_json["Subjects"][i]["Marks"].size()); j++) { + for (unsigned int j = 0; j < static_cast( + marks_json["Subjects"][i]["Marks"].size()); + j++) { std::string caption = rm_tr_le_whitespace(marks_json["Subjects"][i]["Marks"][j]["Caption"]); std::string theme = @@ -178,7 +184,10 @@ void init_wins(WINDOW **wins, int n, json marks_json) { MaxHight = 0; } - if (static_cast(marks_json["Subjects"][i]["Marks"].size()) * 2 + DEFAULT_PADDING > MaxHight) { + if (static_cast(marks_json["Subjects"][i]["Marks"].size()) * + 2 + + DEFAULT_PADDING > + MaxHight) { MaxHight = marks_json["Subjects"][i]["Marks"].size() * 2 + DEFAULT_PADDING; } @@ -196,8 +205,9 @@ void init_wins(WINDOW **wins, int n, json marks_json) { /* Show the window with a border and a label */ void win_show(WINDOW *win, wchar_t *label, int label_color, int width, int height, json marks_json, int SubjectIndex) { - - // is the compiler smoking weed or something, why is it thinking starty is not used ?? + + // is the compiler smoking weed or something, why is it thinking starty is not + // used ?? int startx, starty; wresize(win, height, width); diff --git a/src/memory.cpp b/src/memory.cpp new file mode 100644 index 0000000..f3312a1 --- /dev/null +++ b/src/memory.cpp @@ -0,0 +1,45 @@ +#include "memory.h" +#include "color.h" +#include +#include +#include + +void delete_all(std::vector *allocated) { + for (long long i = allocated->size() - 1; i >= 0; i--) { + switch (allocated->at(i).type) { + case WINDOW_ARRAY: { + WINDOW **windows = static_cast(allocated->at(i).ptr); + for (std::size_t j = 0; j < allocated->at(i).size; j++) { + delwin(windows[j]); + } + delete[] windows; + break; + } + case PANEL_ARRAY: { + PANEL **panels = static_cast(allocated->at(i).ptr); + for (std::size_t j = 0; j < allocated->at(i).size; j++) { + del_panel(panels[j]); + } + delete[] panels; + break; + } + case GENERIC_ARRAY: + delete[] static_cast(allocated->at(i).ptr); + break; + case WINDOW_TYPE: + delwin(static_cast(allocated->at(i).ptr)); + break; + case PANEL_TYPE: + del_panel(static_cast(allocated->at(i).ptr)); + break; + case GENERIC_TYPE: + delete static_cast(allocated->at(i).ptr); + break; + default: + std::cerr << RED "[!!CRITICAL!!]" << RESET " Unknown allocation type" + << "\n"; + break; + } + allocated->pop_back(); + } +} diff --git a/src/memory.h b/src/memory.h new file mode 100644 index 0000000..3838a6f --- /dev/null +++ b/src/memory.h @@ -0,0 +1,23 @@ +// header guard +#ifndef _ba_me_hg_ +#define _ba_me_hg_ + +#include +#include +enum AllocationType { + WINDOW_ARRAY, + PANEL_ARRAY, + GENERIC_ARRAY, + WINDOW_TYPE, + PANEL_TYPE, + GENERIC_TYPE +}; + +struct allocation { + AllocationType type; + void *ptr; + std::size_t size; +}; + +void delete_all(std::vector *allocated); +#endif diff --git a/src/timetable.cpp b/src/timetable.cpp index 21600aa..8df7088 100644 --- a/src/timetable.cpp +++ b/src/timetable.cpp @@ -2,6 +2,7 @@ #include "color.h" #include "const.h" #include "helper_funcs.h" +#include "memory.h" #include "net.h" #include "types.h" #include @@ -20,13 +21,13 @@ #include #include - - using nlohmann::json; #define BOTTOM_PADDING 5 #define DEFAULT_OFFSET 3 +std::vector timetable_allocated; + const wchar_t *day_abriviations[] = {nullptr, L"Mo", L"Tu", L"We", L"Th", L"Fr", L"Sa", L"Su"}; @@ -87,20 +88,19 @@ json *find_atom_by_indexes(json &resp_from_api, uint8_t day_index, } void timetable_page() { - auto dateSelected = std::chrono::system_clock::now(); - reload_for_new_week: - std::time_t date_time_t = std::chrono::system_clock::to_time_t(dateSelected); - std::tm local_time = *std::localtime(&date_time_t); - + current_allocated = &timetable_allocated; + auto dateSelected = std::chrono::system_clock::now(); +reload_for_new_week: + std::time_t date_time_t = std::chrono::system_clock::to_time_t(dateSelected); + std::tm local_time = *std::localtime(&date_time_t); - std::stringstream date_stringstream; - date_stringstream << std::put_time(&local_time, "%Y-%m-%d"); + std::stringstream date_stringstream; + date_stringstream << std::put_time(&local_time, "%Y-%m-%d"); - std::string date_string = "date=" + date_stringstream.str(); + std::string date_string = "date=" + date_stringstream.str(); std::string endpoint = "api/3/timetable/actual"; - json resp_from_api = - bakaapi::get_data_from_endpoint(endpoint, date_string); + json resp_from_api = bakaapi::get_data_from_endpoint(endpoint, date_string); // this may be unnecessary but i dont have enaugh data to test it // it sorts the hours by start time @@ -111,6 +111,8 @@ void timetable_page() { Id_and_Start_time *temp_hour_sorting_array = new Id_and_Start_time[resp_from_api["Hours"].size()]; + timetable_allocated.push_back({GENERIC_ARRAY, temp_hour_sorting_array, + resp_from_api["Hours"].size()}); for (uint8_t i = 0; i < resp_from_api["Hours"].size(); i++) { temp_hour_sorting_array[i] = std::make_tuple( @@ -155,6 +157,7 @@ void timetable_page() { } delete[] temp_hour_sorting_array; + timetable_allocated.pop_back(); } // some lambda dark magic @@ -194,7 +197,11 @@ void timetable_page() { const uint16_t cell_height = (LINES - BOTTOM_PADDING) / num_of_days; WINDOW **day_windows = new WINDOW *[num_of_days]; + timetable_allocated.push_back({WINDOW_ARRAY, day_windows, num_of_days}); + WINDOW **lesson_windows = new WINDOW *[num_of_columns]; + timetable_allocated.push_back({WINDOW_ARRAY, lesson_windows, num_of_columns}); + std::vector> cells( num_of_days, std::vector(num_of_columns)); @@ -256,7 +263,11 @@ void timetable_page() { selector_windows[i] = newwin(1, 1, DEFAULT_OFFSET + y_offset, DEFAULT_OFFSET + x_offset); + timetable_allocated.push_back({WINDOW_TYPE, selector_windows[i], 1}); + selector_panels[i] = new_panel(selector_windows[i]); + timetable_allocated.push_back({PANEL_TYPE, selector_panels[i], 1}); + wattron(selector_windows[i], COLOR_PAIR(COLOR_RED)); mvwaddch(selector_windows[i], 0, 0, corners[i]); wattroff(selector_windows[i], COLOR_PAIR(COLOR_RED)); @@ -264,45 +275,50 @@ void timetable_page() { } attron(COLOR_PAIR(COLOR_BLUE)); mvprintw(LINES - 2, 0, - "Arrows/hjkl to select | ENTER to show info | p/n to select weeks |F1 to exit"); + "Arrows/hjkl to select | ENTER to show info | p/n to select weeks " + "|F1 to exit"); { std::tm end_week = local_time; -std::tm start_week = local_time; + std::tm start_week = local_time; -// Convert tm_wday (0-6) to API day format (1-7) -int current_wday = (local_time.tm_wday == 0) ? 7 : local_time.tm_wday; + // Convert tm_wday (0-6) to API day format (1-7) + int current_wday = (local_time.tm_wday == 0) ? 7 : local_time.tm_wday; -// Get days of week from API (1-7 format where Monday is 1) -uint8_t start_day = resp_from_api["Days"][0]["DayOfWeek"].get(); -uint8_t end_day = resp_from_api["Days"][resp_from_api["Days"].size() - 1]["DayOfWeek"].get(); + // Get days of week from API (1-7 format where Monday is 1) + uint8_t start_day = resp_from_api["Days"][0]["DayOfWeek"].get(); + uint8_t end_day = + resp_from_api["Days"][resp_from_api["Days"].size() - 1]["DayOfWeek"] + .get(); -// Calculate days back to start day (handles week wraparound) -int days_back = (current_wday >= start_day) - ? (current_wday - start_day) - : (current_wday + 7 - start_day); + // Calculate days back to start day (handles week wraparound) + int days_back = (current_wday >= start_day) + ? (current_wday - start_day) + : (current_wday + 7 - start_day); -// Calculate days forward to end day (handles week wraparound) -int days_forward = (current_wday <= end_day) - ? (end_day - current_wday) - : (end_day + 7 - current_wday); + // Calculate days forward to end day (handles week wraparound) + int days_forward = (current_wday <= end_day) ? (end_day - current_wday) + : (end_day + 7 - current_wday); -// Adjust dates -start_week.tm_mday -= days_back; -end_week.tm_mday += days_forward; + // Adjust dates + start_week.tm_mday -= days_back; + end_week.tm_mday += days_forward; -// Normalize the dates -std::mktime(&start_week); -std::mktime(&end_week); + // Normalize the dates + std::mktime(&start_week); + std::mktime(&end_week); -// Format the dates as strings -std::stringstream start_week_strstream, end_week_strstream; -start_week_strstream << std::put_time(&start_week, "%d.%m.%Y"); -end_week_strstream << std::put_time(&end_week, "%d.%m.%Y"); - -// kern. developer approved ↓↓ -mvprintw(LINES - 2, COLS - (start_week_strstream.str().length() + 3 + end_week_strstream.str().length()), - "%s", (start_week_strstream.str() + " - " + end_week_strstream.str()).c_str()); + // Format the dates as strings + std::stringstream start_week_strstream, end_week_strstream; + start_week_strstream << std::put_time(&start_week, "%d.%m.%Y"); + end_week_strstream << std::put_time(&end_week, "%d.%m.%Y"); + // kern. developer approved ↓↓ + mvprintw(LINES - 2, + COLS - (start_week_strstream.str().length() + 3 + + end_week_strstream.str().length()), + "%s", + (start_week_strstream.str() + " - " + end_week_strstream.str()) + .c_str()); } attroff(COLOR_PAIR(COLOR_BLUE)); @@ -360,13 +376,12 @@ mvprintw(LINES - 2, COLS - (start_week_strstream.str().length() + 3 + end_week_s selected_cell.x++; break; case 'p': - dateSelected = dateSelected - std::chrono::days(7); - goto reload_for_new_week; - break; case 'n': - dateSelected = dateSelected + std::chrono::days(7); + (ch == 'p') ? dateSelected = dateSelected - std::chrono::days(7) + : dateSelected = dateSelected + std::chrono::days(7); + delete_all(&timetable_allocated); goto reload_for_new_week; - break; + break; case 10: // ENTER json *atom = find_atom_by_indexes(resp_from_api, selected_cell.y, selected_cell.x, HourIdLookupTable); @@ -513,8 +528,8 @@ mvprintw(LINES - 2, COLS - (start_week_strstream.str().length() + 3 + end_week_s } } } - delete[] day_windows; - delete[] lesson_windows; + delete_all(&timetable_allocated); + clear(); endwin(); } @@ -661,4 +676,4 @@ void draw_cells(uint8_t num_of_columns, uint8_t num_of_days, } } } -} +} \ No newline at end of file