From 0b72fabadec642dcecfe861c56dfeddb0c82a898 Mon Sep 17 00:00:00 2001 From: scratko Date: Thu, 21 Nov 2024 00:42:10 +0300 Subject: Fixed memory leak The image widget is responsible for deleting the loaded part of the image Check for correct type of selected file Error checking after image upload --- Makefile | 4 ++-- menu_callbacks.cpp | 4 +++- puzzle.cpp | 32 ++++++++++++++++++++++++++++---- puzzle.hpp | 13 ++++++++++--- solution_algorithm.cpp | 1 - 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 4732fd6..742e5f6 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ SRCMODULES = puzzle.cpp gameplay.cpp menu_callbacks.cpp solution_algorithm.cpp img_handler.cpp main.cpp OBJMODULES = $(SRCMODULES:.cpp=.o) CXX = g++ -CXXFLAGS = -Wall -g -D DEBUG +CXXFLAGS = -Wall -g LIBS = -lfltk -lfltk_images all: main %.o: %.сpp - $(CXX) $(CXXFLAGS) -c $< -I /usr/include/libpng16 -o $@ + $(CXX) $(CXXFLAGS) -c $< -o $@ main: $(OBJMODULES) $(CXX) $^ $(LIBS) -o $@ diff --git a/menu_callbacks.cpp b/menu_callbacks.cpp index ffc1aae..5668c67 100644 --- a/menu_callbacks.cpp +++ b/menu_callbacks.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -11,6 +12,7 @@ void new_game_callback(Fl_Widget*, void *gp) { + Fl::check(); PuzzleGame::StartGame(reinterpret_cast(gp)); } @@ -30,7 +32,7 @@ void load_file_callback(Fl_Widget *sender, void*) dialog.type(Fl_Native_File_Chooser::BROWSE_FILE); dialog.filter("JPEG Files\t*.jpg\nPNG Files\t*.png"); #if defined(_WIN32) - dialog.directory((string {getenv("HOMEPATH")} + "\\Desktop").c_str()); + dialog.directory((std::string {getenv("HOMEPATH")} + "\\Desktop").c_str()); #else dialog.directory((std::string {getenv("HOME")} + "/Desktop").c_str()); #endif diff --git a/puzzle.cpp b/puzzle.cpp index 3fbd026..8cca327 100644 --- a/puzzle.cpp +++ b/puzzle.cpp @@ -4,13 +4,15 @@ #include #include #include +#include +#include #include +#include #include #include #include #include - GameParams* GameParams::instance = nullptr; void GameParams::CalculateStandardPuzzlePos() @@ -47,8 +49,10 @@ void GameParams::NextUntestedPuzzles() /* * check if puzzles already were created */ - if(puzzles.size() != 0) + if(puzzles.size() != 0) { puzzles.clear(); + Fl::do_widget_deletion(); + } /* * ======== creating puzzles =========== */ @@ -74,13 +78,33 @@ void GameParams::NextUntestedPuzzles() find_path_to_picture(tmp_puzzle->path, cur_directory, tmp_puzzle->sequence_number); Fl_PNG_Image *img = new Fl_PNG_Image(tmp_puzzle->path.c_str()); - // TODO check fails img->fail(); + switch (img->fail()) { + case Fl_Image::ERR_NO_IMAGE: + case Fl_Image::ERR_FILE_ACCESS: + fl_alert("%s: %s", tmp_puzzle->path.c_str(), strerror(errno)); + exit(1); + case Fl_Image::ERR_FORMAT: + fl_alert("couldn't decode image"); + exit(1); + } tmp_puzzle->image(img); + tmp_puzzle->stored_img_pointer = img; tmp_puzzle->callback(press_button_callback, this); puzzles.push_back(std::move(tmp_puzzle)); } - win->end(); ResetFreePuzzles(); + /* + * Checking image shuffling + */ + bool shuffled_img = false; + for(int i = 0; i < puzzle_pieces-1; ++i) + if(puzzles[i]->sequence_number != i) { + shuffled_img = true; + break; + } + if(!shuffled_img) + NextUntestedPuzzles(); + win->end(); } bool GameParams::IsSolvability() diff --git a/puzzle.hpp b/puzzle.hpp index e44efd4..9b01cc6 100644 --- a/puzzle.hpp +++ b/puzzle.hpp @@ -4,12 +4,13 @@ #include #include #include +#include #include #include #include enum { - puzzle_pieces = 9, + puzzle_pieces = 9, // including empty puzzle puzzles_per_side = 3, puzzle_size = 100, spacing = 5 @@ -19,8 +20,12 @@ class Puzzle : public Fl_Button{ public: unsigned char sequence_number; std::string path; + Fl_PNG_Image *stored_img_pointer; Puzzle(int x, int y) - : Fl_Button(x, y, puzzle_size, puzzle_size) {} + : Fl_Button(x, y, puzzle_size, puzzle_size), + stored_img_pointer(nullptr) { + } + ~Puzzle() { delete stored_img_pointer; } }; class GameParams { @@ -40,7 +45,9 @@ private: Fl_Window *win; std::string cur_directory; - GameParams(Fl_Window *a_win = nullptr) : win(a_win) {} + GameParams(Fl_Window *a_win = nullptr) + : win(a_win) + {} void CalculateStandardPuzzlePos(); void ResetFreePuzzles(); void NextUntestedPuzzles(); diff --git a/solution_algorithm.cpp b/solution_algorithm.cpp index 70a9ace..f0b7861 100644 --- a/solution_algorithm.cpp +++ b/solution_algorithm.cpp @@ -108,7 +108,6 @@ void ASearch::ApplyFairEvaluator(Node& n) const n.evaluation = n.depth + sum_md; } - class MovesCreator { vect_node& free_moves; GameParams::coordinates empty_box_coord; -- cgit v1.2.3