annotate src/library/library.cc @ 409:8d06825d96d1

library: refresh in a separate thread this is fugly but it works
author Paper <paper@tflc.us>
date Thu, 02 Apr 2026 00:18:56 -0400
parents 650a9159a0e7
children eb554255ea5f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
222
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
1 #include "library/library.h"
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
2 #include "core/anime_db.h"
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents: 228
diff changeset
3 #include "core/session.h"
222
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
4 #include "core/strings.h"
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
5
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
6 #include "anitomy/anitomy.h"
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
7
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
8 #include <filesystem>
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents: 228
diff changeset
9 #include <string>
222
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
10 #include <unordered_map>
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
11
223
84e0a3c4737a library: implement menu bar buttons
Paper <mrpapersonic@gmail.com>
parents: 222
diff changeset
12 #include <iostream>
84e0a3c4737a library: implement menu bar buttons
Paper <mrpapersonic@gmail.com>
parents: 222
diff changeset
13
84e0a3c4737a library: implement menu bar buttons
Paper <mrpapersonic@gmail.com>
parents: 222
diff changeset
14 namespace Library {
84e0a3c4737a library: implement menu bar buttons
Paper <mrpapersonic@gmail.com>
parents: 222
diff changeset
15
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
16 Database::Database()
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
17 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
18 /* Do this immediately :) */
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
19 /* Nevermind, this causes an immediate segfault on Windows
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
20 UpdateWatchers();
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
21 */
409
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
22 /* Also, this would be completely useless as the paths in
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
23 * the config are not filled until after main() is
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
24 * called. */
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
25 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
26
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
27 void Database::UpdateWatchers()
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
28 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
29 /* TODO also need to remove unused watchers */
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
30
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
31 for (const auto &p : session.config.library.paths) {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
32 if (watchers_.count(p))
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
33 continue;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
34
393
963047512d34 *: clang-format
Paper <paper@tflc.us>
parents: 383
diff changeset
35 watchers_[p].reset(
963047512d34 *: clang-format
Paper <paper@tflc.us>
parents: 383
diff changeset
36 Filesystem::GetRecursiveFilesystemWatcher(reinterpret_cast<void *>(this), p, Database::StaticEventHandler));
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
37 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
38 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
39
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
40 bool Database::GetPathAnimeAndEpisode(const std::string &basename, int *aid, int *ep)
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
41 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
42 anitomy::Anitomy anitomy;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
43 anitomy.Parse(basename);
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
44
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
45 const auto &elements = anitomy.elements();
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
46
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
47 const std::string title = Strings::ToUtf8String(elements.get(anitomy::kElementAnimeTitle));
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
48
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
49 const int id = Anime::db.LookupAnimeTitle(title);
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
50 if (id <= 0 || (find_id_ && find_id_.value() != id))
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
51 return false;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
52
393
963047512d34 *: clang-format
Paper <paper@tflc.us>
parents: 383
diff changeset
53 const int episode = Strings::ToInt<int>(Strings::ToUtf8String(elements.get(anitomy::kElementEpisodeNumber)));
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
54
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
55 *aid = id;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
56 *ep = episode;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
57 return true;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
58 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
59
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
60 void Database::EventHandler(const std::filesystem::path &path, Filesystem::IWatcher::Event event)
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
61 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
62 std::string bname = path.filename().u8string();
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
63 int aid, ep;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
64
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
65 if (!GetPathAnimeAndEpisode(bname, &aid, &ep))
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
66 return;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
67
409
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
68 /* Lock the items mutex */
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
69 const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
70
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
71 switch (event) {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
72 case Filesystem::IWatcher::Created:
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
73 items[aid][ep] = path;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
74 break;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
75 case Filesystem::IWatcher::Deleted:
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
76 /* kill it off */
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
77 items[aid].erase(ep);
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
78 if (items[aid].empty())
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
79 items.erase(aid);
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
80 break;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
81 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
82 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
83
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
84 void Database::StaticEventHandler(void *opaque, const std::filesystem::path &path, Filesystem::IWatcher::Event event)
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
85 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
86 /* Forward to class function */
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
87 reinterpret_cast<Database *>(opaque)->EventHandler(path, event);
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
88 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
89
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
90 std::optional<std::filesystem::path> Database::GetAnimeFolder(int id)
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
91 {
366
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
92 // this function sucks, but it's the most I can really do for now.
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
93 //
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
94 // in the future the Refresh() function should look for directories
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
95 // as well that fit the anime name and *also* have episodes in them.
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
96 // it should give each of these directories a rating by how many
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
97 // episodes are contained in them. whichever directory has more episodes
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
98 // wins, or the first found if there is an equal amount.
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
99
409
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
100 /* TODO use a shared lock instead */
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
101 const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
102
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
103 for (const auto &[anime_id, episodes] : items) {
366
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
104 if (id != anime_id)
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
105 continue;
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
106
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
107 for (const auto &[episode, path] : episodes)
366
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
108 return path.parent_path();
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
109
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
110 break;
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
111 }
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
112
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
113 return std::nullopt;
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
114 }
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
115
409
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
116 void Database::RefreshThread()
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
117 {
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
118 for (const auto &w : watchers_)
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
119 w.second->Process();
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
120 }
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
121
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
122 /* TODO the threading code for this could be better */
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
123 void Database::Refresh(std::optional<int> find_id)
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
124 {
409
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
125 /* Join the thread if it was already run */
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
126 if (refresh_thread_.joinable())
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
127 refresh_thread_.join();
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
128
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
129 /* This is terrible */
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
130 find_id_ = find_id;
222
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
131
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 369
diff changeset
132 UpdateWatchers();
222
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
133
409
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
134 refresh_thread_ = std::thread(&Database::RefreshThread, this);
222
b9f111d84d95 *: move to semver, remove old macos build, add library files
Paper <paper@paper.us.eu.org>
parents:
diff changeset
135 }
223
84e0a3c4737a library: implement menu bar buttons
Paper <mrpapersonic@gmail.com>
parents: 222
diff changeset
136
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
137 void Database::Refresh()
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
138 {
366
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
139 Refresh(std::nullopt);
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
140 }
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
141
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
142 void Database::Refresh(int id)
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 366
diff changeset
143 {
366
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
144 Refresh(std::optional<int>(id));
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
145 }
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
146
409
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
147 std::optional<std::filesystem::path> Database::GetAnimeEpisodePath(int anime, int episode)
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
148 {
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
149 const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
150
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
151 if (items.find(anime) == items.end() || items[anime].find(episode) == items[anime].end())
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
152 return std::nullopt;
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
153
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
154 return items[anime][episode];
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
155 }
8d06825d96d1 library: refresh in a separate thread
Paper <paper@tflc.us>
parents: 398
diff changeset
156
383
27c462bc7815 make the "Now Playing" page actually work
Paper <paper@tflc.us>
parents: 382
diff changeset
157 // TODO export to JSON on exit
366
886f66775f31 animone: add preliminary AT-SPI stuff
Paper <paper@tflc.us>
parents: 347
diff changeset
158
328
71396ecb6f7e library: convert to class + database
Paper <paper@paper.us.eu.org>
parents: 319
diff changeset
159 Database db;
71396ecb6f7e library: convert to class + database
Paper <paper@paper.us.eu.org>
parents: 319
diff changeset
160
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents: 228
diff changeset
161 } // namespace Library