juk3n/fluffypublic Fork
⑂ main
Commits
⬇ Clone ▾
git clone https://git.rickub.com/juk3n/fluffy.git
git clone ssh://git@rickub.com/juk3n/fluffy.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

11 removing the game from a console menu #12

Merged@github-juk3n wants to merge 11-removing-the-game-from-a-console-menu into main
Merged as 1b488bfd95eb.
3 files changed
modified CMakeLists.txt +5 -1
@@ -8,7 +8,7 @@ include(FetchContent)
88 set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
99 FetchContent_Declare(ftxui
1010 GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
11- GIT_TAG v4.0.0
11+ GIT_TAG v5.0.0
1212 )
1313 FetchContent_MakeAvailable(ftxui)
1414 if(NOT ftxui_POPULATED)
@@ -18,6 +18,8 @@ endif()
1818
1919
2020
21+find_program(CLANG_TIDY NAMES "clang-tidy" REQUIRED)
22+set(CLANG_TIDY_COMMAND "${CLANG_TIDY}" "-checks=-*,modernize-*")
2123
2224
2325 find_package(SQLite3 REQUIRED)
@@ -26,12 +28,14 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
2628
2729 add_executable(fluffy src/main.cpp)
2830
31+
2932 target_link_libraries(fluffy
3033 PRIVATE ftxui::screen
3134 PRIVATE ftxui::dom
3235 PRIVATE ftxui::component
3336 PRIVATE SQLite::SQLite3
3437 )
38+set_target_properties(fluffy PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}")
3539
3640 if (EMSCRIPTEN)
3741 string(APPEND CMAKE_CXX_FLAGS " -s USE_PTHREADS")
@@ -8,7 +8,7 @@ include(FetchContent)
8 set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)8 set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE)
9 FetchContent_Declare(ftxui9 FetchContent_Declare(ftxui
10 GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui10 GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
11- GIT_TAG v4.0.011+ GIT_TAG v5.0.0
12 )12 )
13 FetchContent_MakeAvailable(ftxui)13 FetchContent_MakeAvailable(ftxui)
14 if(NOT ftxui_POPULATED)14 if(NOT ftxui_POPULATED)
@@ -18,6 +18,8 @@ endif()
18 18
19 19
20 20
21+find_program(CLANG_TIDY NAMES "clang-tidy" REQUIRED)
22+set(CLANG_TIDY_COMMAND "${CLANG_TIDY}" "-checks=-*,modernize-*")
21 23
22 24
23 find_package(SQLite3 REQUIRED)25 find_package(SQLite3 REQUIRED)
@@ -26,12 +28,14 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
26 28
27 add_executable(fluffy src/main.cpp)29 add_executable(fluffy src/main.cpp)
28 30
31+
29 target_link_libraries(fluffy32 target_link_libraries(fluffy
30 PRIVATE ftxui::screen33 PRIVATE ftxui::screen
31 PRIVATE ftxui::dom34 PRIVATE ftxui::dom
32 PRIVATE ftxui::component35 PRIVATE ftxui::component
33 PRIVATE SQLite::SQLite336 PRIVATE SQLite::SQLite3
34 )37 )
38+set_target_properties(fluffy PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}")
35 39
36 if (EMSCRIPTEN) 40 if (EMSCRIPTEN)
37 string(APPEND CMAKE_CXX_FLAGS " -s USE_PTHREADS") 41 string(APPEND CMAKE_CXX_FLAGS " -s USE_PTHREADS")
added include/game.hpp +19 -0
new file mode 100644
@@ -0,0 +1,19 @@
1+#pragma once
2+
3+#include <string>
4+
5+class Game {
6+private:
7+ int id;
8+ std::string name;
9+ std::string path;
10+
11+public:
12+ Game(int id, std::string name, std::string path)
13+ : id{id}, name{name}, path{path} {}
14+ ~Game() {}
15+
16+ int getId() { return id; }
17+ std::string getName() { return name; }
18+ std::string getPath() { return path; }
19+};
new file mode 100644
@@ -0,0 +1,19 @@
1+#pragma once
2+
3+#include <string>
4+
5+class Game {
6+private:
7+ int id;
8+ std::string name;
9+ std::string path;
10+
11+public:
12+ Game(int id, std::string name, std::string path)
13+ : id{id}, name{name}, path{path} {}
14+ ~Game() {}
15+
16+ int getId() { return id; }
17+ std::string getName() { return name; }
18+ std::string getPath() { return path; }
19+};
modified src/main.cpp +176 -165
@@ -1,208 +1,219 @@
1-#include "ftxui/dom/elements.hpp"
2-#include "ftxui/screen/screen.hpp"
3-#include "ftxui/screen/string.hpp"
41 #include "ftxui/component/component.hpp"
2+#include "ftxui/component/component_base.hpp"
53 #include "ftxui/component/component_options.hpp"
64 #include "ftxui/component/screen_interactive.hpp"
5+#include "ftxui/dom/elements.hpp"
6+#include "ftxui/screen/screen.hpp"
7+#include "ftxui/screen/string.hpp"
78
8-#include <iostream>
9-#include <string>
109 #include <cstdlib>
1110 #include <filesystem>
12-#include <sqlite3.h>
11+#include <iostream>
1312 #include <map>
13+#include <sqlite3.h>
14+#include <string>
15+#include <vector>
1416
17+#include <game.hpp>
1518
1619 using namespace ftxui;
1720
18-std::map<std::string, std::string> games;
21+std::vector<Game> games;
1922
20-std::string database_initialization_command = "CREATE TABLE GAME("
21- "GAME_ID INT PRIMARY KEY NOT NULL, "
22- "GAME_NAME TEXT NOT NULL, "
23- "GAME_PATH TEXT NOT NULL);";
23+std::string database_initialization_command =
24+ "CREATE TABLE games("
25+ "GAME_ID INTEGER PRIMARY KEY AUTOINCREMENT, "
26+ "GAME_NAME TEXT NOT NULL, "
27+ "GAME_PATH TEXT NOT NULL);";
2428
25-const char* select_all_games_command = "SELECT * FROM GAME;";
29+std::string select_all_games_command = "SELECT * FROM games;";
2630
2731 bool debugRun = true;
2832
2933 void printMessage(std::string message) {
30- if (debugRun) {
31- std::cout << message << std::endl;
32- }
34+ if (debugRun) {
35+ std::cout << message << std::endl;
36+ }
3337 }
3438
35-void execute_sql_command(sqlite3* database, std::string command) {
36- int exit = 0;
37- char* messageError;
38- exit = sqlite3_exec(database, command.c_str(), NULL, 0, &messageError);
39-
40- if (exit != SQLITE_OK) {
41- printMessage("Error with command: " + command + " " + messageError);
42- sqlite3_free(messageError);
43- }
39+void execute_sql_command(sqlite3 *database, std::string command) {
40+ int exit = 0;
41+ char *messageError;
42+ exit = sqlite3_exec(database, command.c_str(), nullptr, nullptr, &messageError);
43+
44+ if (exit != SQLITE_OK) {
45+ printMessage("Error with command: " + command + " " + messageError);
46+ sqlite3_free(messageError);
47+ }
4448 }
4549
46-void addGame(sqlite3* database, int id, std::string name, std::string path) {
47- std::string command = "INSERT INTO GAME (GAME_ID, GAME_NAME, GAME_PATH) VALUES (";
48- command += std::to_string(id) + ", '" + name + "', \"" + path + "\");";
49- execute_sql_command(database, command);
50+void addGame(sqlite3 *database, std::string name, std::string path) {
51+ std::string command =
52+ "INSERT INTO games (GAME_NAME, GAME_PATH) VALUES (";
53+ command += "'" + name + "', \"" + path + "\");";
54+ execute_sql_command(database, command);
5055 }
5156
52-void removeGame(sqlite3* database, std::string name) {
53- std::string command = "DELETE FROM GAME WHERE GAME_NAME=";
54- command += "'" + name + "';";
55- execute_sql_command(database, command);
57+void removeGame(sqlite3 *database, std::string name) {
58+ std::string command = "DELETE FROM games WHERE GAME_NAME=";
59+ command += "'" + name + "';";
60+ execute_sql_command(database, command);
5661 }
5762
58-void initialize_database(sqlite3* database) {
59- execute_sql_command(database, database_initialization_command);
60- addGame(database, 1, "Devastating Fog", "");
61- addGame(database, 2, "No Pirates Here!", "");
62- printMessage("Database Initialized");
63+void initialize_database(sqlite3 *database) {
64+ execute_sql_command(database, database_initialization_command);
65+ printMessage("Database Initialized");
6366 }
6467
65-void runGame(sqlite3* database, std::string gameName) {
66- std::string pathToRun = "";
67- for (const auto& [name, path] : games) {
68- if (name == gameName) {
69- pathToRun = path;
70- }
68+void runGame(sqlite3 *database, std::string gameName) {
69+ std::string pathToRun = "";
70+ for (auto &game : games) {
71+ if (gameName == game.getName()) {
72+ pathToRun = game.getPath();
7173 }
72- system(pathToRun.c_str());
74+ }
75+ system(pathToRun.c_str());
7376 }
7477
75-void handleCommand(int argc, char const *argv[], sqlite3* database) {
76- std::string command{};
77- switch (argc) {
78- case 2:
79- command = argv[1];
80- if (command == "show") {
81- for (const auto& [game, path] : games) {
82- std::cout << game << ": " << path << std::endl;
83- }
84- }
85- break;
86- case 3:
87- command = argv[1];
88- if (command == "rm") {
89- std::string gameName{ argv[2] };
90- removeGame(database, gameName);
91- }
92- else if(command == "play") {
93- std::string gameName{ argv[2] };
94- runGame(database, gameName);
95- }
96- case 4:
97- command = argv[1];
98- if (command == "add") {
99- std::string gameName{ argv[2] };
100- auto localPath = std::filesystem::path(argv[3]);
101- std::string globalPath = std::filesystem::absolute(localPath).lexically_normal().string();
102-
103- std::string temp{};
104- for (const auto a : globalPath) {
105- if (a != ' ') {
106- temp += a;
107- }
108- else {
109- temp += "\' \'";
110- }
111- }
112-
113- addGame(database, games.size() + 1, gameName, temp);
114- }
115- break;
78+void handleCommand(int argc, char const *argv[], sqlite3 *database) {
79+ std::string command{};
80+ switch (argc) {
81+ case 2:
82+ command = argv[1];
83+ if (command == "show") {
84+ for (auto &game : games) {
85+ std::cout << game.getName() << ": " << game.getPath() << std::endl;
86+ }
11687 }
117-}
88+ break;
89+ case 3:
90+ command = argv[1];
91+ if (command == "rm") {
92+ std::string gameName{argv[2]};
93+ removeGame(database, gameName);
94+ } else if (command == "play") {
95+ std::string gameName{argv[2]};
96+ runGame(database, gameName);
97+ }
98+ case 4:
99+ command = argv[1];
100+ if (command == "add") {
101+ std::string gameName{argv[2]};
102+ auto localPath = std::filesystem::path(argv[3]);
103+ std::string globalPath =
104+ std::filesystem::absolute(localPath).lexically_normal().string();
105+
106+ std::string temp{};
107+ for (const auto a : globalPath) {
108+ if (a != ' ') {
109+ temp += a;
110+ } else {
111+ temp += "\' \'";
112+ }
113+ }
118114
119-int main(int argc, char const *argv[]) {
120- bool newCreation = not std::filesystem::exists("data.db");
115+ addGame(database, gameName, temp);
116+ }
117+ break;
118+ }
119+}
121120
122- char* messageError;
123- sqlite3* database;
124- sqlite3_stmt* stmt;
125- int exit = 0;
126- exit = sqlite3_open("data.db", &database);
121+auto Style() -> ButtonOption {
122+ auto option = ButtonOption::Border();
123+ option.transform = [](const EntryState &s) {
124+ auto element = text(s.label);
125+ if (s.focused) {
126+ element |= bold;
127+ }
128+ return element | size(HEIGHT, LESS_THAN, 10);
129+ };
130+ return option;
131+}
127132
128- if (exit) {
129- std::cerr << "Error opening database" << sqlite3_errmsg(database) << std::endl;
130- return -1;
131- }
132-
133- std::cout << "Opened database successfully!" << std::endl;
133+auto runConsoleApp(sqlite3* database) -> void {
134+ system("clear");
135+
136+ std::vector<std::string> localGames = {};
137+ for (auto &game : games) {
138+ localGames.emplace_back(game.getName());
139+ }
140+ localGames.emplace_back("Exit");
141+
142+ auto gamesContainer{Container::Vertical({})};
143+ for (auto &game : games) {
144+ gamesContainer->Add(Button(
145+ game.getName(), [&] { runGame(database, game.getName()); }, Style()));
146+ }
147+
148+ auto menu_screen = ScreenInteractive::TerminalOutput();
149+
150+ auto quitButton = Button("Exit", menu_screen.ExitLoopClosure(), Style());
151+ gamesContainer->Add(quitButton);
152+
153+ int menuOptionSelected{0};
154+ auto appContainer =
155+ Container::Tab({gamesContainer}, &menuOptionSelected);
156+
157+ auto container = Container::Horizontal({
158+ appContainer,
159+ });
160+ auto renderer = Renderer(container, [&] {
161+ return vbox({
162+ center(text(L" Fluffy v0.1 ")),
163+ appContainer->Render(),
164+ }) |
165+ border | size(WIDTH, LESS_THAN, 120);
166+ });
167+ menu_screen.Loop(renderer);
134168
135- if (newCreation) {
136- initialize_database(database);
137- }
169+}
138170
139- exit = sqlite3_prepare_v2(database, select_all_games_command, -1, &stmt, 0);
171+auto main(int argc, char const *argv[]) -> int {
172+ bool newCreation = not std::filesystem::exists("data.db");
173+ char *messageError;
174+ sqlite3 *database;
175+ sqlite3_stmt *stmt;
176+ int exit = 0;
177+ exit = sqlite3_open("data.db", &database);
140178
141- if (exit) {
142- std::cerr << "Error retrieving data" << sqlite3_errmsg(database) << std::endl;
143- sqlite3_close(database);
144- return -1;
145- }
179+ if (exit) {
180+ std::cerr << "Error opening database" << sqlite3_errmsg(database)
181+ << std::endl;
182+ return -1;
183+ }
146184
147- while (sqlite3_step(stmt) == SQLITE_ROW) {
148- int id = sqlite3_column_int(stmt, 0);
149- const unsigned char* gameName = sqlite3_column_text(stmt, 1);
150- const unsigned char* gamePath = sqlite3_column_text(stmt, 2);
185+ printMessage("Opened database successfully!");
151186
152- std::string name{reinterpret_cast<const char*>(gameName)};
153- std::string path{reinterpret_cast<const char*>(gamePath)};
154- games[name] = path;
155- }
156- sqlite3_finalize(stmt);
187+ if (newCreation) {
188+ initialize_database(database);
189+ }
157190
158- if (argc > 1) {
159- handleCommand(argc, argv, database);
160- return 0;
161- }
191+ exit = sqlite3_prepare_v2(database, select_all_games_command.c_str(), -1, &stmt, nullptr);
162192
163- int exit_id = games.size();
164- int choice = 0;
165- do {
166- system("clear");
167- auto document = vbox({
168- center(text(L" Fluffy v0.1 ")),
169- });
170-
171- document = document | size(WIDTH, LESS_THAN, 120);
172-
173- auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
174- Render(screen, document);
175-
176- std::cout << screen.ToString() << '\0' << std::endl;
177-
178-
179- auto menu_screen = ScreenInteractive::TerminalOutput();
180-
181- std::vector<std::string> localGames = {};
182- for (const auto& [name, path] : games) {
183- localGames.push_back(name);
184- }
185- localGames.push_back("Exit");
186-
187- MenuOption option;
188- option.on_enter = menu_screen.ExitLoopClosure();
189- auto menu = Menu(&localGames, &choice, option);
190- menu_screen.Loop(menu);
191-
192- if (choice != exit_id) {
193- int i{ 0 };
194- std::string gameToRun = "";
195- for (const auto& [name, path] : games) {
196-
197- if (i == choice) {
198- gameToRun = name;
199-
200- }
201- i++;
202- }
203- runGame(database, gameToRun);
204- }
205- } while (choice != exit_id);
193+ if (exit) {
194+ std::cerr << "Error retrieving data" << sqlite3_errmsg(database)
195+ << std::endl;
206196 sqlite3_close(database);
207- return EXIT_SUCCESS;
197+ return -1;
198+ }
199+
200+ while (sqlite3_step(stmt) == SQLITE_ROW) {
201+ int id = sqlite3_column_int(stmt, 0);
202+ const unsigned char *gameName = sqlite3_column_text(stmt, 1);
203+ const unsigned char *gamePath = sqlite3_column_text(stmt, 2);
204+
205+ games.emplace_back(Game{id, reinterpret_cast<const char *>(gameName),
206+ reinterpret_cast<const char *>(gamePath)});
207+ }
208+ sqlite3_finalize(stmt);
209+
210+ if (argc > 1) {
211+ handleCommand(argc, argv, database);
212+ }
213+ else {
214+ runConsoleApp(database);
215+ }
216+
217+ sqlite3_close(database);
218+ return EXIT_SUCCESS;
208219 }
\ No newline at end of file
@@ -1,208 +1,219 @@
1-#include "ftxui/dom/elements.hpp"
2-#include "ftxui/screen/screen.hpp"
3-#include "ftxui/screen/string.hpp"
4 #include "ftxui/component/component.hpp"1 #include "ftxui/component/component.hpp"
2+#include "ftxui/component/component_base.hpp"
5 #include "ftxui/component/component_options.hpp"3 #include "ftxui/component/component_options.hpp"
6 #include "ftxui/component/screen_interactive.hpp"4 #include "ftxui/component/screen_interactive.hpp"
5+#include "ftxui/dom/elements.hpp"
6+#include "ftxui/screen/screen.hpp"
7+#include "ftxui/screen/string.hpp"
7 8
8-#include <iostream>
9-#include <string>
10 #include <cstdlib>9 #include <cstdlib>
11 #include <filesystem>10 #include <filesystem>
12-#include <sqlite3.h>11+#include <iostream>
13 #include <map>12 #include <map>
13+#include <sqlite3.h>
14+#include <string>
15+#include <vector>
14 16
17+#include <game.hpp>
15 18
16 using namespace ftxui;19 using namespace ftxui;
17 20
18-std::map<std::string, std::string> games;21+std::vector<Game> games;
19 22
20-std::string database_initialization_command = "CREATE TABLE GAME("23+std::string database_initialization_command =
21- "GAME_ID INT PRIMARY KEY NOT NULL, "24+ "CREATE TABLE games("
22- "GAME_NAME TEXT NOT NULL, "25+ "GAME_ID INTEGER PRIMARY KEY AUTOINCREMENT, "
23- "GAME_PATH TEXT NOT NULL);";26+ "GAME_NAME TEXT NOT NULL, "
27+ "GAME_PATH TEXT NOT NULL);";
24 28
25-const char* select_all_games_command = "SELECT * FROM GAME;";29+std::string select_all_games_command = "SELECT * FROM games;";
26 30
27 bool debugRun = true;31 bool debugRun = true;
28 32
29 void printMessage(std::string message) {33 void printMessage(std::string message) {
30- if (debugRun) {34+ if (debugRun) {
31- std::cout << message << std::endl;35+ std::cout << message << std::endl;
32- }36+ }
33 }37 }
34 38
35-void execute_sql_command(sqlite3* database, std::string command) {39+void execute_sql_command(sqlite3 *database, std::string command) {
36- int exit = 0;40+ int exit = 0;
37- char* messageError;41+ char *messageError;
38- exit = sqlite3_exec(database, command.c_str(), NULL, 0, &messageError); 42+ exit = sqlite3_exec(database, command.c_str(), nullptr, nullptr, &messageError);
39- 43+
40- if (exit != SQLITE_OK) {44+ if (exit != SQLITE_OK) {
41- printMessage("Error with command: " + command + " " + messageError);45+ printMessage("Error with command: " + command + " " + messageError);
42- sqlite3_free(messageError);46+ sqlite3_free(messageError);
43- }47+ }
44 }48 }
45 49
46-void addGame(sqlite3* database, int id, std::string name, std::string path) {50+void addGame(sqlite3 *database, std::string name, std::string path) {
47- std::string command = "INSERT INTO GAME (GAME_ID, GAME_NAME, GAME_PATH) VALUES (";51+ std::string command =
48- command += std::to_string(id) + ", '" + name + "', \"" + path + "\");";52+ "INSERT INTO games (GAME_NAME, GAME_PATH) VALUES (";
49- execute_sql_command(database, command);53+ command += "'" + name + "', \"" + path + "\");";
54+ execute_sql_command(database, command);
50 }55 }
51 56
52-void removeGame(sqlite3* database, std::string name) {57+void removeGame(sqlite3 *database, std::string name) {
53- std::string command = "DELETE FROM GAME WHERE GAME_NAME=";58+ std::string command = "DELETE FROM games WHERE GAME_NAME=";
54- command += "'" + name + "';";59+ command += "'" + name + "';";
55- execute_sql_command(database, command);60+ execute_sql_command(database, command);
56 }61 }
57 62
58-void initialize_database(sqlite3* database) {63+void initialize_database(sqlite3 *database) {
59- execute_sql_command(database, database_initialization_command);64+ execute_sql_command(database, database_initialization_command);
60- addGame(database, 1, "Devastating Fog", "");65+ printMessage("Database Initialized");
61- addGame(database, 2, "No Pirates Here!", "");
62- printMessage("Database Initialized");
63 }66 }
64 67
65-void runGame(sqlite3* database, std::string gameName) {68+void runGame(sqlite3 *database, std::string gameName) {
66- std::string pathToRun = "";69+ std::string pathToRun = "";
67- for (const auto& [name, path] : games) {70+ for (auto &game : games) {
68- if (name == gameName) {71+ if (gameName == game.getName()) {
69- pathToRun = path;72+ pathToRun = game.getPath();
70- }
71 }73 }
72- system(pathToRun.c_str());74+ }
75+ system(pathToRun.c_str());
73 }76 }
74 77
75-void handleCommand(int argc, char const *argv[], sqlite3* database) {78+void handleCommand(int argc, char const *argv[], sqlite3 *database) {
76- std::string command{};79+ std::string command{};
77- switch (argc) {80+ switch (argc) {
78- case 2:81+ case 2:
79- command = argv[1];82+ command = argv[1];
80- if (command == "show") {83+ if (command == "show") {
81- for (const auto& [game, path] : games) {84+ for (auto &game : games) {
82- std::cout << game << ": " << path << std::endl;85+ std::cout << game.getName() << ": " << game.getPath() << std::endl;
83- }86+ }
84- }
85- break;
86- case 3:
87- command = argv[1];
88- if (command == "rm") {
89- std::string gameName{ argv[2] };
90- removeGame(database, gameName);
91- }
92- else if(command == "play") {
93- std::string gameName{ argv[2] };
94- runGame(database, gameName);
95- }
96- case 4:
97- command = argv[1];
98- if (command == "add") {
99- std::string gameName{ argv[2] };
100- auto localPath = std::filesystem::path(argv[3]);
101- std::string globalPath = std::filesystem::absolute(localPath).lexically_normal().string();
102-
103- std::string temp{};
104- for (const auto a : globalPath) {
105- if (a != ' ') {
106- temp += a;
107- }
108- else {
109- temp += "\' \'";
110- }
111- }
112-
113- addGame(database, games.size() + 1, gameName, temp);
114- }
115- break;
116 }87 }
117-}88+ break;
89+ case 3:
90+ command = argv[1];
91+ if (command == "rm") {
92+ std::string gameName{argv[2]};
93+ removeGame(database, gameName);
94+ } else if (command == "play") {
95+ std::string gameName{argv[2]};
96+ runGame(database, gameName);
97+ }
98+ case 4:
99+ command = argv[1];
100+ if (command == "add") {
101+ std::string gameName{argv[2]};
102+ auto localPath = std::filesystem::path(argv[3]);
103+ std::string globalPath =
104+ std::filesystem::absolute(localPath).lexically_normal().string();
105+
106+ std::string temp{};
107+ for (const auto a : globalPath) {
108+ if (a != ' ') {
109+ temp += a;
110+ } else {
111+ temp += "\' \'";
112+ }
113+ }
118 114
119-int main(int argc, char const *argv[]) {115+ addGame(database, gameName, temp);
120- bool newCreation = not std::filesystem::exists("data.db");116+ }
117+ break;
118+ }
119+}
121 120
122- char* messageError;121+auto Style() -> ButtonOption {
123- sqlite3* database;122+ auto option = ButtonOption::Border();
124- sqlite3_stmt* stmt;123+ option.transform = [](const EntryState &s) {
125- int exit = 0;124+ auto element = text(s.label);
126- exit = sqlite3_open("data.db", &database);125+ if (s.focused) {
126+ element |= bold;
127+ }
128+ return element | size(HEIGHT, LESS_THAN, 10);
129+ };
130+ return option;
131+}
127 132
128- if (exit) {133+auto runConsoleApp(sqlite3* database) -> void {
129- std::cerr << "Error opening database" << sqlite3_errmsg(database) << std::endl;134+ system("clear");
130- return -1;135+
131- } 136+ std::vector<std::string> localGames = {};
132- 137+ for (auto &game : games) {
133- std::cout << "Opened database successfully!" << std::endl;138+ localGames.emplace_back(game.getName());
139+ }
140+ localGames.emplace_back("Exit");
141+
142+ auto gamesContainer{Container::Vertical({})};
143+ for (auto &game : games) {
144+ gamesContainer->Add(Button(
145+ game.getName(), [&] { runGame(database, game.getName()); }, Style()));
146+ }
147+
148+ auto menu_screen = ScreenInteractive::TerminalOutput();
149+
150+ auto quitButton = Button("Exit", menu_screen.ExitLoopClosure(), Style());
151+ gamesContainer->Add(quitButton);
152+
153+ int menuOptionSelected{0};
154+ auto appContainer =
155+ Container::Tab({gamesContainer}, &menuOptionSelected);
156+
157+ auto container = Container::Horizontal({
158+ appContainer,
159+ });
160+ auto renderer = Renderer(container, [&] {
161+ return vbox({
162+ center(text(L" Fluffy v0.1 ")),
163+ appContainer->Render(),
164+ }) |
165+ border | size(WIDTH, LESS_THAN, 120);
166+ });
167+ menu_screen.Loop(renderer);
134 168
135- if (newCreation) {169+}
136- initialize_database(database);
137- }
138 170
139- exit = sqlite3_prepare_v2(database, select_all_games_command, -1, &stmt, 0);171+auto main(int argc, char const *argv[]) -> int {
172+ bool newCreation = not std::filesystem::exists("data.db");
173+ char *messageError;
174+ sqlite3 *database;
175+ sqlite3_stmt *stmt;
176+ int exit = 0;
177+ exit = sqlite3_open("data.db", &database);
140 178
141- if (exit) {179+ if (exit) {
142- std::cerr << "Error retrieving data" << sqlite3_errmsg(database) << std::endl;180+ std::cerr << "Error opening database" << sqlite3_errmsg(database)
143- sqlite3_close(database);181+ << std::endl;
144- return -1;182+ return -1;
145- }183+ }
146 184
147- while (sqlite3_step(stmt) == SQLITE_ROW) {185+ printMessage("Opened database successfully!");
148- int id = sqlite3_column_int(stmt, 0);
149- const unsigned char* gameName = sqlite3_column_text(stmt, 1);
150- const unsigned char* gamePath = sqlite3_column_text(stmt, 2);
151 186
152- std::string name{reinterpret_cast<const char*>(gameName)};187+ if (newCreation) {
153- std::string path{reinterpret_cast<const char*>(gamePath)};188+ initialize_database(database);
154- games[name] = path;189+ }
155- }
156- sqlite3_finalize(stmt);
157 190
158- if (argc > 1) {191+ exit = sqlite3_prepare_v2(database, select_all_games_command.c_str(), -1, &stmt, nullptr);
159- handleCommand(argc, argv, database);
160- return 0;
161- }
162 192
163- int exit_id = games.size();193+ if (exit) {
164- int choice = 0;194+ std::cerr << "Error retrieving data" << sqlite3_errmsg(database)
165- do {195+ << std::endl;
166- system("clear");
167- auto document = vbox({
168- center(text(L" Fluffy v0.1 ")),
169- });
170-
171- document = document | size(WIDTH, LESS_THAN, 120);
172-
173- auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
174- Render(screen, document);
175-
176- std::cout << screen.ToString() << '\0' << std::endl;
177-
178-
179- auto menu_screen = ScreenInteractive::TerminalOutput();
180-
181- std::vector<std::string> localGames = {};
182- for (const auto& [name, path] : games) {
183- localGames.push_back(name);
184- }
185- localGames.push_back("Exit");
186-
187- MenuOption option;
188- option.on_enter = menu_screen.ExitLoopClosure();
189- auto menu = Menu(&localGames, &choice, option);
190- menu_screen.Loop(menu);
191-
192- if (choice != exit_id) {
193- int i{ 0 };
194- std::string gameToRun = "";
195- for (const auto& [name, path] : games) {
196-
197- if (i == choice) {
198- gameToRun = name;
199-
200- }
201- i++;
202- }
203- runGame(database, gameToRun);
204- }
205- } while (choice != exit_id);
206 sqlite3_close(database);196 sqlite3_close(database);
207- return EXIT_SUCCESS;197+ return -1;
198+ }
199+
200+ while (sqlite3_step(stmt) == SQLITE_ROW) {
201+ int id = sqlite3_column_int(stmt, 0);
202+ const unsigned char *gameName = sqlite3_column_text(stmt, 1);
203+ const unsigned char *gamePath = sqlite3_column_text(stmt, 2);
204+
205+ games.emplace_back(Game{id, reinterpret_cast<const char *>(gameName),
206+ reinterpret_cast<const char *>(gamePath)});
207+ }
208+ sqlite3_finalize(stmt);
209+
210+ if (argc > 1) {
211+ handleCommand(argc, argv, database);
212+ }
213+ else {
214+ runConsoleApp(database);
215+ }
216+
217+ sqlite3_close(database);
218+ return EXIT_SUCCESS;
208 }219 }
\ No newline at end of file\ No newline at end of file