| 119 | } |
| 120 | |
| 121 | void WatcherThread() { |
| 122 | const size_t numDirs = g_watchDirs.size(); |
| 123 | std::vector<OSTPlatform::DirectoryWatch::Watch> watches(numDirs); |
| 124 | std::vector<OSTPlatform::DirectoryWatch::Watch*> watchPtrs(numDirs, nullptr); |
| 125 | |
| 126 | for (size_t i = 0; i < numDirs; ++i) { |
| 127 | if (!watches[i].Open(g_watchDirs[i], 65536)) { |
| 128 | LOG_PACKAGE_WARN("Failed to open Lua watch directory: {}", g_watchDirs[i]); |
| 129 | continue; |
| 130 | } |
| 131 | if (!watches[i].IssueRead()) { |
| 132 | watches[i].Cancel(); |
| 133 | continue; |
| 134 | } |
| 135 | |
| 136 | watchPtrs[i] = &watches[i]; |
| 137 | LOG_PACKAGE_DEBUG("Watching Lua directory: {}", g_watchDirs[i]); |
| 138 | } |
| 139 | |
| 140 | bool allFailed = true; |
| 141 | for (auto* watch : watchPtrs) { |
| 142 | if (watch && watch->IsOpen()) { |
| 143 | allFailed = false; |
| 144 | break; |
| 145 | } |
| 146 | } |
| 147 | if (allFailed) { |
| 148 | LOG_PACKAGE_WARN("No Lua watch directories could be opened"); |
| 149 | return; |
| 150 | } |
| 151 | |
| 152 | auto drainEvent = [&](size_t idx, |
| 153 | std::unordered_map<std::string, ChangeAction>& accumulated, |
| 154 | std::vector<std::string>& order) { |
| 155 | auto* watch = idx < watchPtrs.size() ? watchPtrs[idx] : nullptr; |
| 156 | if (!watch || !watch->IsOpen()) return; |
| 157 | |
| 158 | MergeChanges(accumulated, order, ToFileChanges(g_watchDirs[idx], watch->Drain())); |
| 159 | watch->IssueRead(); |
| 160 | }; |
| 161 | |
| 162 | while (g_running) { |
| 163 | auto waitResult = OSTPlatform::DirectoryWatch::WaitAny(watchPtrs, 1000); |
| 164 | |
| 165 | if (!g_running) break; |
| 166 | if (waitResult.status == OSTPlatform::DirectoryWatch::WaitStatus::Timeout) continue; |
| 167 | if (waitResult.status != OSTPlatform::DirectoryWatch::WaitStatus::Signaled || |
| 168 | waitResult.index >= numDirs) { |
| 169 | continue; |
| 170 | } |
| 171 | |
| 172 | std::unordered_map<std::string, ChangeAction> accumulated; |
| 173 | std::vector<std::string> order; |
| 174 | |
| 175 | drainEvent(waitResult.index, accumulated, order); |
| 176 | |
| 177 | while (g_running) { |
| 178 | auto debounceResult = OSTPlatform::DirectoryWatch::WaitAny(watchPtrs, kDebounceMs); |
nothing calls this directly
no test coverage detected