#pragma once #include #include #include #include #include "json.hpp" #include "Constants.h" // Header-only instance registry. // Stores {channelName: port} in a JSON file at /tmp/pluginbridge-registry.json // Multiple PluginBridge instances write to this file (one per track). // Atomic writes via write-to-temp + rename (POSIX rename is atomic on same filesystem). namespace InstanceRegistry { inline std::map readAll() { std::map result; std::ifstream file(PluginBridgeConstants::kRegistryPath); if (!file.is_open()) return result; try { nlohmann::json j; file >> j; for (auto& [key, val] : j.items()) { if (val.is_number_integer()) result[key] = val.get(); } } catch (...) {} return result; } inline void registerInstance(const std::string& channelName, int port) { // Read existing auto registry = readAll(); // Update entry registry[channelName] = port; // Write to temp file, then atomic rename std::string tmpPath = std::string(PluginBridgeConstants::kRegistryPath) + ".tmp"; nlohmann::json j(registry); std::ofstream tmp(tmpPath); if (tmp.is_open()) { tmp << j.dump(2); tmp.close(); std::rename(tmpPath.c_str(), PluginBridgeConstants::kRegistryPath); } } inline void unregisterInstance(const std::string& channelName) { auto registry = readAll(); auto it = registry.find(channelName); if (it == registry.end()) return; registry.erase(it); std::string tmpPath = std::string(PluginBridgeConstants::kRegistryPath) + ".tmp"; if (registry.empty()) { // Remove the file entirely std::remove(PluginBridgeConstants::kRegistryPath); return; } nlohmann::json j(registry); std::ofstream tmp(tmpPath); if (tmp.is_open()) { tmp << j.dump(2); tmp.close(); std::rename(tmpPath.c_str(), PluginBridgeConstants::kRegistryPath); } } } // namespace InstanceRegistry