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.

30 move all main code to fluffy class main should just run fluffyrun #31

Merged@github-juk3n wants to merge 30-move-all-main-code-to-fluffy-class-main-should-just-run-fluffyrun into main
Merged as 914b00a4104d.
5 files changed
modified app/CMakeLists.txt +1 -1
@@ -32,7 +32,7 @@ find_package(SQLite3 REQUIRED)
3232
3333 include_directories(${CMAKE_SOURCE_DIR}/include)
3434 enable_testing()
35-add_executable(fluffy src/main.cpp)
35+add_executable(fluffy src/main.cpp src/fluffyApplication.cpp)
3636
3737
3838
@@ -32,7 +32,7 @@ find_package(SQLite3 REQUIRED)
32 32
33 include_directories(${CMAKE_SOURCE_DIR}/include)33 include_directories(${CMAKE_SOURCE_DIR}/include)
34 enable_testing()34 enable_testing()
35-add_executable(fluffy src/main.cpp)35+add_executable(fluffy src/main.cpp src/fluffyApplication.cpp)
36 36
37 37
38 38
added app/include/fluffyApplication.hpp +57 -0
new file mode 100644
@@ -0,0 +1,57 @@
1+#pragma once
2+
3+
4+#include <ftxui/component/component.hpp>
5+#include <ftxui/component/component_base.hpp>
6+#include <ftxui/component/component_options.hpp>
7+#include <ftxui/component/screen_interactive.hpp>
8+#include <ftxui/dom/elements.hpp>
9+#include <ftxui/screen/screen.hpp>
10+#include <ftxui/screen/string.hpp>
11+
12+#include <cstdlib>
13+#include <filesystem>
14+#include <iostream>
15+#include <map>
16+#include <sqlite3.h>
17+#include <string>
18+#include <vector>
19+#include <unistd.h>
20+#include <limits.h>
21+#include <memory>
22+
23+#include <game.hpp>
24+#include <database.hpp>
25+#include <output.hpp>
26+
27+using namespace ftxui;
28+
29+class FluffyApplication {
30+public:
31+ FluffyApplication(int argc, char const *argv[]);
32+
33+private:
34+ std::shared_ptr<Output> output{};
35+ std::string version{ "v0.1.3" };
36+ std::vector<Game> games;
37+
38+ auto addGame(Database& database, std::string name, std::string path) -> void;
39+
40+ auto removeGame(Database& database, std::string name) -> void;
41+
42+ auto runGame(std::string gameName) -> void;
43+
44+ auto handleCommand(const std::string& command, const std::vector<std::string>& arguments, Database& database) -> void;
45+
46+ auto style() -> ButtonOption;
47+
48+ auto runConsoleApp() -> void;
49+
50+ auto handleFlags(std::vector<std::string> flags) -> void;
51+
52+ auto getExecutablePath() -> std::filesystem::path;
53+
54+ auto parseFlags(int argc, char const *argv[]) -> std::vector<std::string>;
55+
56+ auto parseCommand(int argc, char const* argv[]);
57+};
\ No newline at end of file
new file mode 100644
@@ -0,0 +1,57 @@
1+#pragma once
2+
3+
4+#include <ftxui/component/component.hpp>
5+#include <ftxui/component/component_base.hpp>
6+#include <ftxui/component/component_options.hpp>
7+#include <ftxui/component/screen_interactive.hpp>
8+#include <ftxui/dom/elements.hpp>
9+#include <ftxui/screen/screen.hpp>
10+#include <ftxui/screen/string.hpp>
11+
12+#include <cstdlib>
13+#include <filesystem>
14+#include <iostream>
15+#include <map>
16+#include <sqlite3.h>
17+#include <string>
18+#include <vector>
19+#include <unistd.h>
20+#include <limits.h>
21+#include <memory>
22+
23+#include <game.hpp>
24+#include <database.hpp>
25+#include <output.hpp>
26+
27+using namespace ftxui;
28+
29+class FluffyApplication {
30+public:
31+ FluffyApplication(int argc, char const *argv[]);
32+
33+private:
34+ std::shared_ptr<Output> output{};
35+ std::string version{ "v0.1.3" };
36+ std::vector<Game> games;
37+
38+ auto addGame(Database& database, std::string name, std::string path) -> void;
39+
40+ auto removeGame(Database& database, std::string name) -> void;
41+
42+ auto runGame(std::string gameName) -> void;
43+
44+ auto handleCommand(const std::string& command, const std::vector<std::string>& arguments, Database& database) -> void;
45+
46+ auto style() -> ButtonOption;
47+
48+ auto runConsoleApp() -> void;
49+
50+ auto handleFlags(std::vector<std::string> flags) -> void;
51+
52+ auto getExecutablePath() -> std::filesystem::path;
53+
54+ auto parseFlags(int argc, char const *argv[]) -> std::vector<std::string>;
55+
56+ auto parseCommand(int argc, char const* argv[]);
57+};
\ No newline at end of file\ No newline at end of file
modified app/include/output.hpp +1 -1
@@ -1,4 +1,4 @@
1-# pragma once
1+#pragma once
22
33 #include <iostream>
44 #include <string>
@@ -1,4 +1,4 @@
1-# pragma once1+#pragma once
2 2
3 #include <iostream>3 #include <iostream>
4 #include <string>4 #include <string>
added app/src/fluffyApplication.cpp +181 -0
new file mode 100644
@@ -0,0 +1,181 @@
1+#include "fluffyApplication.hpp"
2+
3+#include <iostream>
4+
5+auto FluffyApplication::addGame(Database& database, std::string name, std::string path) -> void {
6+ std::string command =
7+ "INSERT INTO games (GAME_NAME, GAME_PATH) VALUES (";
8+ command += "'" + name + "', \"" + path + "\");";
9+ database.executeSqlCommand(command);
10+}
11+
12+auto FluffyApplication::removeGame(Database& database, std::string name) -> void{
13+ std::string command = "DELETE FROM games WHERE GAME_NAME=";
14+ command += "'" + name + "';";
15+ database.executeSqlCommand(command);
16+}
17+
18+auto FluffyApplication::runGame(std::string gameName) -> void {
19+ std::string pathToRun = "";
20+ for (auto &game : games) {
21+ if (gameName == game.getName()) {
22+ pathToRun = game.getPath();
23+ }
24+ }
25+ system(pathToRun.c_str());
26+}
27+
28+auto FluffyApplication::handleCommand(const std::string& command, const std::vector<std::string>& arguments, Database& database) -> void{
29+ if (command == "show") {
30+ for (auto &game : games) {
31+ std::cout << game.getName() << ": " << game.getPath() << std::endl;
32+ }
33+ }
34+ else if (command == "rm") {
35+ std::string gameName{arguments[0]};
36+ removeGame(database, gameName);
37+ }
38+ else if (command == "add") {
39+ std::string gameName{arguments[0]};
40+ auto localPath = std::filesystem::path(arguments[1]);
41+ std::string globalPath =
42+ std::filesystem::absolute(localPath).lexically_normal().string();
43+ std::string temp{};
44+ for (const auto a : globalPath) {
45+ if (a != ' ') {
46+ temp += a;
47+ } else {
48+ temp += "\' \'";
49+ }
50+ }
51+
52+ addGame(database, gameName, temp);
53+ }
54+ else if (command == "play") {
55+ std::string gameName{arguments[0]};
56+ runGame(gameName);
57+ }
58+ else if (command == "--version") {
59+ output->printMessage("fluffy " + version);
60+ }
61+ else if (command == "--help") {
62+ output->printMessage("fluffy commands:\n \
63+ play <game_name> Runs a game\n \
64+ add <game_name> <game_path> Add a game library\n \
65+ show Show all games added to library\n \
66+ rm <game_name> Remove game from a library");
67+ }
68+ else {
69+ output->printMessage("fluffy: '" + command + "' is not a fluffy command. See 'fluffy --help'");
70+ }
71+}
72+
73+auto FluffyApplication::style() -> ButtonOption {
74+ auto option = ButtonOption::Border();
75+ option.transform = [](const EntryState &s) {
76+ auto element = text(s.label);
77+ if (s.focused) {
78+ element |= bold;
79+ }
80+ return element | size(HEIGHT, LESS_THAN, 10);
81+ };
82+ return option;
83+}
84+
85+auto FluffyApplication::runConsoleApp() -> void {
86+ system("clear");
87+
88+ std::vector<std::string> localGames = {};
89+ for (auto &game : games) {
90+ localGames.emplace_back(game.getName());
91+ }
92+ localGames.emplace_back("Exit");
93+
94+ auto gamesContainer{Container::Vertical({})};
95+ for (auto &game : games) {
96+ gamesContainer->Add(Button(
97+ game.getName(), [&] { runGame(game.getName()); }, style()));
98+ }
99+
100+ auto menu_screen = ScreenInteractive::TerminalOutput();
101+
102+ auto quitButton = Button("Exit", menu_screen.ExitLoopClosure(), style());
103+ gamesContainer->Add(quitButton);
104+
105+ int menuOptionSelected{0};
106+ auto appContainer =
107+ Container::Tab({gamesContainer}, &menuOptionSelected);
108+
109+ auto container = Container::Horizontal({
110+ appContainer,
111+ });
112+ auto renderer = Renderer(container, [&] {
113+ return vbox({
114+ center(text("Fluffy " + version)),
115+ appContainer->Render(),
116+ }) |
117+ border | size(WIDTH, LESS_THAN, 120);
118+ });
119+ menu_screen.Loop(renderer);
120+
121+}
122+
123+auto FluffyApplication::handleFlags(std::vector<std::string> flags) -> void {
124+ for (const auto& flag : flags) {
125+ if (flag == "-d") {
126+ output->turnOnDebug();
127+ }
128+ else {
129+ output->printMessage("unkown option: '" + flag + "'");
130+ }
131+ }
132+}
133+
134+auto FluffyApplication::getExecutablePath() -> std::filesystem::path {
135+ char result[PATH_MAX];
136+ ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
137+ return std::filesystem::path(std::string(result, (count > 0) ? count : 0));
138+}
139+
140+auto FluffyApplication::parseFlags(int argc, char const *argv[]) -> std::vector<std::string> {
141+ std::vector<std::string> flags;
142+ for (int i = 1; i < argc; i ++) {
143+ std::string appArgument = argv[i];
144+ if (appArgument.size() < 2) continue;
145+ if (appArgument[0] == '-' and appArgument[1] != '-') flags.emplace_back(appArgument);
146+ }
147+ return flags;
148+}
149+
150+auto FluffyApplication::parseCommand(int argc, char const* argv[]) {
151+ std::string command{};
152+ std::vector<std::string> arguments{};
153+ for (int i = 1; i < argc; i ++) {
154+ std::string appArgument = argv[i];
155+ if (appArgument.size() < 2) continue;
156+ if ((appArgument[0] == '-' and appArgument[1] == '-') or appArgument[0] != '-') {
157+ if (command == "") command = appArgument;
158+ else arguments.emplace_back(appArgument);
159+ }
160+ }
161+ struct Command { std::string command; std::vector<std::string> arguments; };
162+ return Command{command, arguments};
163+}
164+
165+FluffyApplication::FluffyApplication(int argc, char const *argv[]) {
166+ output = std::make_shared<Output>();
167+ auto flags = parseFlags(argc, argv);
168+ handleFlags(flags);
169+
170+ auto databasePath{ std::filesystem::path(getExecutablePath().parent_path().string() + "/data.db") };
171+ Database database{databasePath, output};
172+ games = database.getGames();
173+
174+ if (argc - flags.size() > 1) {
175+ auto [command, arguments] = parseCommand(argc, argv);
176+ if (command != "") handleCommand(command, arguments, database);
177+ }
178+ else {
179+ runConsoleApp();
180+ }
181+}
new file mode 100644
@@ -0,0 +1,181 @@
1+#include "fluffyApplication.hpp"
2+
3+#include <iostream>
4+
5+auto FluffyApplication::addGame(Database& database, std::string name, std::string path) -> void {
6+ std::string command =
7+ "INSERT INTO games (GAME_NAME, GAME_PATH) VALUES (";
8+ command += "'" + name + "', \"" + path + "\");";
9+ database.executeSqlCommand(command);
10+}
11+
12+auto FluffyApplication::removeGame(Database& database, std::string name) -> void{
13+ std::string command = "DELETE FROM games WHERE GAME_NAME=";
14+ command += "'" + name + "';";
15+ database.executeSqlCommand(command);
16+}
17+
18+auto FluffyApplication::runGame(std::string gameName) -> void {
19+ std::string pathToRun = "";
20+ for (auto &game : games) {
21+ if (gameName == game.getName()) {
22+ pathToRun = game.getPath();
23+ }
24+ }
25+ system(pathToRun.c_str());
26+}
27+
28+auto FluffyApplication::handleCommand(const std::string& command, const std::vector<std::string>& arguments, Database& database) -> void{
29+ if (command == "show") {
30+ for (auto &game : games) {
31+ std::cout << game.getName() << ": " << game.getPath() << std::endl;
32+ }
33+ }
34+ else if (command == "rm") {
35+ std::string gameName{arguments[0]};
36+ removeGame(database, gameName);
37+ }
38+ else if (command == "add") {
39+ std::string gameName{arguments[0]};
40+ auto localPath = std::filesystem::path(arguments[1]);
41+ std::string globalPath =
42+ std::filesystem::absolute(localPath).lexically_normal().string();
43+ std::string temp{};
44+ for (const auto a : globalPath) {
45+ if (a != ' ') {
46+ temp += a;
47+ } else {
48+ temp += "\' \'";
49+ }
50+ }
51+
52+ addGame(database, gameName, temp);
53+ }
54+ else if (command == "play") {
55+ std::string gameName{arguments[0]};
56+ runGame(gameName);
57+ }
58+ else if (command == "--version") {
59+ output->printMessage("fluffy " + version);
60+ }
61+ else if (command == "--help") {
62+ output->printMessage("fluffy commands:\n \
63+ play <game_name> Runs a game\n \
64+ add <game_name> <game_path> Add a game library\n \
65+ show Show all games added to library\n \
66+ rm <game_name> Remove game from a library");
67+ }
68+ else {
69+ output->printMessage("fluffy: '" + command + "' is not a fluffy command. See 'fluffy --help'");
70+ }
71+}
72+
73+auto FluffyApplication::style() -> ButtonOption {
74+ auto option = ButtonOption::Border();
75+ option.transform = [](const EntryState &s) {
76+ auto element = text(s.label);
77+ if (s.focused) {
78+ element |= bold;
79+ }
80+ return element | size(HEIGHT, LESS_THAN, 10);
81+ };
82+ return option;
83+}
84+
85+auto FluffyApplication::runConsoleApp() -> void {
86+ system("clear");
87+
88+ std::vector<std::string> localGames = {};
89+ for (auto &game : games) {
90+ localGames.emplace_back(game.getName());
91+ }
92+ localGames.emplace_back("Exit");
93+
94+ auto gamesContainer{Container::Vertical({})};
95+ for (auto &game : games) {
96+ gamesContainer->Add(Button(
97+ game.getName(), [&] { runGame(game.getName()); }, style()));
98+ }
99+
100+ auto menu_screen = ScreenInteractive::TerminalOutput();
101+
102+ auto quitButton = Button("Exit", menu_screen.ExitLoopClosure(), style());
103+ gamesContainer->Add(quitButton);
104+
105+ int menuOptionSelected{0};
106+ auto appContainer =
107+ Container::Tab({gamesContainer}, &menuOptionSelected);
108+
109+ auto container = Container::Horizontal({
110+ appContainer,
111+ });
112+ auto renderer = Renderer(container, [&] {
113+ return vbox({
114+ center(text("Fluffy " + version)),
115+ appContainer->Render(),
116+ }) |
117+ border | size(WIDTH, LESS_THAN, 120);
118+ });
119+ menu_screen.Loop(renderer);
120+
121+}
122+
123+auto FluffyApplication::handleFlags(std::vector<std::string> flags) -> void {
124+ for (const auto& flag : flags) {
125+ if (flag == "-d") {
126+ output->turnOnDebug();
127+ }
128+ else {
129+ output->printMessage("unkown option: '" + flag + "'");
130+ }
131+ }
132+}
133+
134+auto FluffyApplication::getExecutablePath() -> std::filesystem::path {
135+ char result[PATH_MAX];
136+ ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
137+ return std::filesystem::path(std::string(result, (count > 0) ? count : 0));
138+}
139+
140+auto FluffyApplication::parseFlags(int argc, char const *argv[]) -> std::vector<std::string> {
141+ std::vector<std::string> flags;
142+ for (int i = 1; i < argc; i ++) {
143+ std::string appArgument = argv[i];
144+ if (appArgument.size() < 2) continue;
145+ if (appArgument[0] == '-' and appArgument[1] != '-') flags.emplace_back(appArgument);
146+ }
147+ return flags;
148+}
149+
150+auto FluffyApplication::parseCommand(int argc, char const* argv[]) {
151+ std::string command{};
152+ std::vector<std::string> arguments{};
153+ for (int i = 1; i < argc; i ++) {
154+ std::string appArgument = argv[i];
155+ if (appArgument.size() < 2) continue;
156+ if ((appArgument[0] == '-' and appArgument[1] == '-') or appArgument[0] != '-') {
157+ if (command == "") command = appArgument;
158+ else arguments.emplace_back(appArgument);
159+ }
160+ }
161+ struct Command { std::string command; std::vector<std::string> arguments; };
162+ return Command{command, arguments};
163+}
164+
165+FluffyApplication::FluffyApplication(int argc, char const *argv[]) {
166+ output = std::make_shared<Output>();
167+ auto flags = parseFlags(argc, argv);
168+ handleFlags(flags);
169+
170+ auto databasePath{ std::filesystem::path(getExecutablePath().parent_path().string() + "/data.db") };
171+ Database database{databasePath, output};
172+ games = database.getGames();
173+
174+ if (argc - flags.size() > 1) {
175+ auto [command, arguments] = parseCommand(argc, argv);
176+ if (command != "") handleCommand(command, arguments, database);
177+ }
178+ else {
179+ runConsoleApp();
180+ }
181+}
modified app/src/main.cpp +2 -203
@@ -1,209 +1,8 @@
1-#include <ftxui/component/component.hpp>
2-#include <ftxui/component/component_base.hpp>
3-#include <ftxui/component/component_options.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>
8-
9-#include <cstdlib>
10-#include <filesystem>
11-#include <iostream>
12-#include <map>
13-#include <sqlite3.h>
14-#include <string>
15-#include <vector>
16-#include <unistd.h>
17-#include <limits.h>
18-#include <memory>
19-
20-#include <game.hpp>
21-#include <database.hpp>
22-#include <output.hpp>
23-
24-using namespace ftxui;
25-
26-std::shared_ptr<Output> output{};
27-std::string version{ "v0.1.2" };
28-std::vector<Game> games;
29-
30-auto addGame(Database& database, std::string name, std::string path) -> void {
31- std::string command =
32- "INSERT INTO games (GAME_NAME, GAME_PATH) VALUES (";
33- command += "'" + name + "', \"" + path + "\");";
34- database.executeSqlCommand(command);
35-}
36-
37-auto removeGame(Database& database, std::string name) -> void{
38- std::string command = "DELETE FROM games WHERE GAME_NAME=";
39- command += "'" + name + "';";
40- database.executeSqlCommand(command);
41-}
42-
43-auto runGame(std::string gameName) -> void {
44- std::string pathToRun = "";
45- for (auto &game : games) {
46- if (gameName == game.getName()) {
47- pathToRun = game.getPath();
48- }
49- }
50- system(pathToRun.c_str());
51-}
52-
53-auto handleCommand(const std::string& command, const std::vector<std::string>& arguments, Database& database) -> void{
54- if (command == "show") {
55- for (auto &game : games) {
56- std::cout << game.getName() << ": " << game.getPath() << std::endl;
57- }
58- }
59- else if (command == "rm") {
60- std::string gameName{arguments[0]};
61- removeGame(database, gameName);
62- }
63- else if (command == "add") {
64- std::string gameName{arguments[0]};
65- auto localPath = std::filesystem::path(arguments[1]);
66- std::string globalPath =
67- std::filesystem::absolute(localPath).lexically_normal().string();
68- std::string temp{};
69- for (const auto a : globalPath) {
70- if (a != ' ') {
71- temp += a;
72- } else {
73- temp += "\' \'";
74- }
75- }
76-
77- addGame(database, gameName, temp);
78- }
79- else if (command == "play") {
80- std::string gameName{arguments[0]};
81- runGame(gameName);
82- }
83- else if (command == "--version") {
84- output->printMessage("fluffy " + version);
85- }
86- else if (command == "--help") {
87- output->printMessage("fluffy commands:\n \
88- play <game_name> Runs a game\n \
89- add <game_name> <game_path> Add a game library\n \
90- show Show all games added to library\n \
91- rm <game_name> Remove game from a library");
92- }
93- else {
94- output->printMessage("fluffy: '" + command + "' is not a fluffy command. See 'fluffy --help'");
95- }
96-}
97-
98-auto style() -> ButtonOption {
99- auto option = ButtonOption::Border();
100- option.transform = [](const EntryState &s) {
101- auto element = text(s.label);
102- if (s.focused) {
103- element |= bold;
104- }
105- return element | size(HEIGHT, LESS_THAN, 10);
106- };
107- return option;
108-}
109-
110-auto runConsoleApp() -> void {
111- system("clear");
112-
113- std::vector<std::string> localGames = {};
114- for (auto &game : games) {
115- localGames.emplace_back(game.getName());
116- }
117- localGames.emplace_back("Exit");
118-
119- auto gamesContainer{Container::Vertical({})};
120- for (auto &game : games) {
121- gamesContainer->Add(Button(
122- game.getName(), [&] { runGame(game.getName()); }, style()));
123- }
124-
125- auto menu_screen = ScreenInteractive::TerminalOutput();
126-
127- auto quitButton = Button("Exit", menu_screen.ExitLoopClosure(), style());
128- gamesContainer->Add(quitButton);
129-
130- int menuOptionSelected{0};
131- auto appContainer =
132- Container::Tab({gamesContainer}, &menuOptionSelected);
133-
134- auto container = Container::Horizontal({
135- appContainer,
136- });
137- auto renderer = Renderer(container, [&] {
138- return vbox({
139- center(text("Fluffy " + version)),
140- appContainer->Render(),
141- }) |
142- border | size(WIDTH, LESS_THAN, 120);
143- });
144- menu_screen.Loop(renderer);
145-
146-}
147-
148-auto handleFlags(std::vector<std::string> flags) -> void {
149- for (const auto& flag : flags) {
150- if (flag == "-d") {
151- output->turnOnDebug();
152- }
153- else {
154- output->printMessage("unkown option: '" + flag + "'");
155- }
156- }
157-}
158-
159-auto getExecutablePath() -> std::filesystem::path {
160- char result[PATH_MAX];
161- ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
162- return std::filesystem::path(std::string(result, (count > 0) ? count : 0));
163-}
164-
165-auto parseFlags(int argc, char const *argv[]) -> std::vector<std::string> {
166- std::vector<std::string> flags;
167- for (int i = 1; i < argc; i ++) {
168- std::string appArgument = argv[i];
169- if (appArgument.size() < 2) continue;
170- if (appArgument[0] == '-' and appArgument[1] != '-') flags.emplace_back(appArgument);
171- }
172- return flags;
173-}
174-
175-auto parseCommand(int argc, char const* argv[]) {
176- std::string command{};
177- std::vector<std::string> arguments{};
178- for (int i = 1; i < argc; i ++) {
179- std::string appArgument = argv[i];
180- if (appArgument.size() < 2) continue;
181- if ((appArgument[0] == '-' and appArgument[1] == '-') or appArgument[0] != '-') {
182- if (command == "") command = appArgument;
183- else arguments.emplace_back(appArgument);
184- }
185- }
186- struct Command { std::string command; std::vector<std::string> arguments; };
187- return Command{command, arguments};
188-}
1+#include "fluffyApplication.hpp"
1892
1903 auto main(int argc, char const *argv[]) -> int {
1914 try {
192- output = std::make_shared<Output>();
193- auto flags = parseFlags(argc, argv);
194- handleFlags(flags);
195-
196- auto databasePath{ std::filesystem::path(getExecutablePath().parent_path().string() + "/data.db")};
197- Database database{databasePath, output};
198- games = database.getGames();
199-
200- if (argc - flags.size() > 1) {
201- auto [command, arguments] = parseCommand(argc, argv);
202- if (command != "") handleCommand(command, arguments, database);
203- }
204- else {
205- runConsoleApp();
206- }
5+ auto app = FluffyApplication{argc, argv};
2076 }
2087 catch(...) {
2098 return EXIT_FAILURE;
@@ -1,209 +1,8 @@
1-#include <ftxui/component/component.hpp>1+#include "fluffyApplication.hpp"
2-#include <ftxui/component/component_base.hpp>
3-#include <ftxui/component/component_options.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>
8-
9-#include <cstdlib>
10-#include <filesystem>
11-#include <iostream>
12-#include <map>
13-#include <sqlite3.h>
14-#include <string>
15-#include <vector>
16-#include <unistd.h>
17-#include <limits.h>
18-#include <memory>
19-
20-#include <game.hpp>
21-#include <database.hpp>
22-#include <output.hpp>
23-
24-using namespace ftxui;
25-
26-std::shared_ptr<Output> output{};
27-std::string version{ "v0.1.2" };
28-std::vector<Game> games;
29-
30-auto addGame(Database& database, std::string name, std::string path) -> void {
31- std::string command =
32- "INSERT INTO games (GAME_NAME, GAME_PATH) VALUES (";
33- command += "'" + name + "', \"" + path + "\");";
34- database.executeSqlCommand(command);
35-}
36-
37-auto removeGame(Database& database, std::string name) -> void{
38- std::string command = "DELETE FROM games WHERE GAME_NAME=";
39- command += "'" + name + "';";
40- database.executeSqlCommand(command);
41-}
42-
43-auto runGame(std::string gameName) -> void {
44- std::string pathToRun = "";
45- for (auto &game : games) {
46- if (gameName == game.getName()) {
47- pathToRun = game.getPath();
48- }
49- }
50- system(pathToRun.c_str());
51-}
52-
53-auto handleCommand(const std::string& command, const std::vector<std::string>& arguments, Database& database) -> void{
54- if (command == "show") {
55- for (auto &game : games) {
56- std::cout << game.getName() << ": " << game.getPath() << std::endl;
57- }
58- }
59- else if (command == "rm") {
60- std::string gameName{arguments[0]};
61- removeGame(database, gameName);
62- }
63- else if (command == "add") {
64- std::string gameName{arguments[0]};
65- auto localPath = std::filesystem::path(arguments[1]);
66- std::string globalPath =
67- std::filesystem::absolute(localPath).lexically_normal().string();
68- std::string temp{};
69- for (const auto a : globalPath) {
70- if (a != ' ') {
71- temp += a;
72- } else {
73- temp += "\' \'";
74- }
75- }
76-
77- addGame(database, gameName, temp);
78- }
79- else if (command == "play") {
80- std::string gameName{arguments[0]};
81- runGame(gameName);
82- }
83- else if (command == "--version") {
84- output->printMessage("fluffy " + version);
85- }
86- else if (command == "--help") {
87- output->printMessage("fluffy commands:\n \
88- play <game_name> Runs a game\n \
89- add <game_name> <game_path> Add a game library\n \
90- show Show all games added to library\n \
91- rm <game_name> Remove game from a library");
92- }
93- else {
94- output->printMessage("fluffy: '" + command + "' is not a fluffy command. See 'fluffy --help'");
95- }
96-}
97-
98-auto style() -> ButtonOption {
99- auto option = ButtonOption::Border();
100- option.transform = [](const EntryState &s) {
101- auto element = text(s.label);
102- if (s.focused) {
103- element |= bold;
104- }
105- return element | size(HEIGHT, LESS_THAN, 10);
106- };
107- return option;
108-}
109-
110-auto runConsoleApp() -> void {
111- system("clear");
112-
113- std::vector<std::string> localGames = {};
114- for (auto &game : games) {
115- localGames.emplace_back(game.getName());
116- }
117- localGames.emplace_back("Exit");
118-
119- auto gamesContainer{Container::Vertical({})};
120- for (auto &game : games) {
121- gamesContainer->Add(Button(
122- game.getName(), [&] { runGame(game.getName()); }, style()));
123- }
124-
125- auto menu_screen = ScreenInteractive::TerminalOutput();
126-
127- auto quitButton = Button("Exit", menu_screen.ExitLoopClosure(), style());
128- gamesContainer->Add(quitButton);
129-
130- int menuOptionSelected{0};
131- auto appContainer =
132- Container::Tab({gamesContainer}, &menuOptionSelected);
133-
134- auto container = Container::Horizontal({
135- appContainer,
136- });
137- auto renderer = Renderer(container, [&] {
138- return vbox({
139- center(text("Fluffy " + version)),
140- appContainer->Render(),
141- }) |
142- border | size(WIDTH, LESS_THAN, 120);
143- });
144- menu_screen.Loop(renderer);
145-
146-}
147-
148-auto handleFlags(std::vector<std::string> flags) -> void {
149- for (const auto& flag : flags) {
150- if (flag == "-d") {
151- output->turnOnDebug();
152- }
153- else {
154- output->printMessage("unkown option: '" + flag + "'");
155- }
156- }
157-}
158-
159-auto getExecutablePath() -> std::filesystem::path {
160- char result[PATH_MAX];
161- ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
162- return std::filesystem::path(std::string(result, (count > 0) ? count : 0));
163-}
164-
165-auto parseFlags(int argc, char const *argv[]) -> std::vector<std::string> {
166- std::vector<std::string> flags;
167- for (int i = 1; i < argc; i ++) {
168- std::string appArgument = argv[i];
169- if (appArgument.size() < 2) continue;
170- if (appArgument[0] == '-' and appArgument[1] != '-') flags.emplace_back(appArgument);
171- }
172- return flags;
173-}
174-
175-auto parseCommand(int argc, char const* argv[]) {
176- std::string command{};
177- std::vector<std::string> arguments{};
178- for (int i = 1; i < argc; i ++) {
179- std::string appArgument = argv[i];
180- if (appArgument.size() < 2) continue;
181- if ((appArgument[0] == '-' and appArgument[1] == '-') or appArgument[0] != '-') {
182- if (command == "") command = appArgument;
183- else arguments.emplace_back(appArgument);
184- }
185- }
186- struct Command { std::string command; std::vector<std::string> arguments; };
187- return Command{command, arguments};
188-}
189 2
190 auto main(int argc, char const *argv[]) -> int {3 auto main(int argc, char const *argv[]) -> int {
191 try {4 try {
192- output = std::make_shared<Output>();5+ auto app = FluffyApplication{argc, argv};
193- auto flags = parseFlags(argc, argv);
194- handleFlags(flags);
195-
196- auto databasePath{ std::filesystem::path(getExecutablePath().parent_path().string() + "/data.db")};
197- Database database{databasePath, output};
198- games = database.getGames();
199-
200- if (argc - flags.size() > 1) {
201- auto [command, arguments] = parseCommand(argc, argv);
202- if (command != "") handleCommand(command, arguments, database);
203- }
204- else {
205- runConsoleApp();
206- }
207 }6 }
208 catch(...) {7 catch(...) {
209 return EXIT_FAILURE;8 return EXIT_FAILURE;