comparison 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
comparison
equal deleted inserted replaced
408:9323153786dc 409:8d06825d96d1
17 { 17 {
18 /* Do this immediately :) */ 18 /* Do this immediately :) */
19 /* Nevermind, this causes an immediate segfault on Windows 19 /* Nevermind, this causes an immediate segfault on Windows
20 UpdateWatchers(); 20 UpdateWatchers();
21 */ 21 */
22 /* Also, this would be completely useless as the paths in
23 * the config are not filled until after main() is
24 * called. */
22 } 25 }
23 26
24 void Database::UpdateWatchers() 27 void Database::UpdateWatchers()
25 { 28 {
26 /* TODO also need to remove unused watchers */ 29 /* TODO also need to remove unused watchers */
60 int aid, ep; 63 int aid, ep;
61 64
62 if (!GetPathAnimeAndEpisode(bname, &aid, &ep)) 65 if (!GetPathAnimeAndEpisode(bname, &aid, &ep))
63 return; 66 return;
64 67
68 /* Lock the items mutex */
69 const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
70
65 switch (event) { 71 switch (event) {
66 case Filesystem::IWatcher::Created: 72 case Filesystem::IWatcher::Created:
67 items[aid][ep] = path; 73 items[aid][ep] = path;
68 break; 74 break;
69 case Filesystem::IWatcher::Deleted: 75 case Filesystem::IWatcher::Deleted:
89 // as well that fit the anime name and *also* have episodes in them. 95 // as well that fit the anime name and *also* have episodes in them.
90 // it should give each of these directories a rating by how many 96 // it should give each of these directories a rating by how many
91 // episodes are contained in them. whichever directory has more episodes 97 // episodes are contained in them. whichever directory has more episodes
92 // wins, or the first found if there is an equal amount. 98 // wins, or the first found if there is an equal amount.
93 99
100 /* TODO use a shared lock instead */
101 const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
102
94 for (const auto &[anime_id, episodes] : items) { 103 for (const auto &[anime_id, episodes] : items) {
95 if (id != anime_id) 104 if (id != anime_id)
96 continue; 105 continue;
97 106
98 for (const auto &[episode, path] : episodes) 107 for (const auto &[episode, path] : episodes)
102 } 111 }
103 112
104 return std::nullopt; 113 return std::nullopt;
105 } 114 }
106 115
107 /* TODO shove this into a separate thread; currently it blocks */ 116 void Database::RefreshThread()
117 {
118 for (const auto &w : watchers_)
119 w.second->Process();
120 }
121
122 /* TODO the threading code for this could be better */
108 void Database::Refresh(std::optional<int> find_id) 123 void Database::Refresh(std::optional<int> find_id)
109 { 124 {
125 /* Join the thread if it was already run */
126 if (refresh_thread_.joinable())
127 refresh_thread_.join();
128
129 /* This is terrible */
110 find_id_ = find_id; 130 find_id_ = find_id;
111 131
112 UpdateWatchers(); 132 UpdateWatchers();
113 133
114 for (const auto &w : watchers_) 134 refresh_thread_ = std::thread(&Database::RefreshThread, this);
115 w.second->Process();
116 } 135 }
117 136
118 void Database::Refresh() 137 void Database::Refresh()
119 { 138 {
120 Refresh(std::nullopt); 139 Refresh(std::nullopt);
123 void Database::Refresh(int id) 142 void Database::Refresh(int id)
124 { 143 {
125 Refresh(std::optional<int>(id)); 144 Refresh(std::optional<int>(id));
126 } 145 }
127 146
147 std::optional<std::filesystem::path> Database::GetAnimeEpisodePath(int anime, int episode)
148 {
149 const std::lock_guard<std::recursive_mutex> lock(items_mutex_);
150
151 if (items.find(anime) == items.end() || items[anime].find(episode) == items[anime].end())
152 return std::nullopt;
153
154 return items[anime][episode];
155 }
156
128 // TODO export to JSON on exit 157 // TODO export to JSON on exit
129 158
130 Database db; 159 Database db;
131 160
132 } // namespace Library 161 } // namespace Library