#include "NetworkAgentFactory.hpp" #include "IPrinterAgent.hpp" #include "ICloudServiceAgent.hpp" #include "BBLPrinterAgent.hpp" #include "OrcaPrinterAgent.hpp" #include "QidiPrinterAgent.hpp" #include "SnapmakerPrinterAgent.hpp" #include "MoonrakerPrinterAgent.hpp" #include #include #include namespace Slic3r { namespace { static std::mutex s_registry_mutex; std::map& get_printer_agents() { static std::map agents; return agents; } std::map>& get_printer_agent_cache() { static std::map> cache; return cache; } // Helper to register a printer agent type with the standard factory pattern. // AgentTypes that take a log_dir constructor arg use the default; BBLPrinterAgent // (no log_dir) is registered separately. template void register_agent() { auto info = T::get_agent_info_static(); NetworkAgentFactory::register_printer_agent( info.id, info.name, [](std::shared_ptr cloud_agent, const std::string& log_dir) -> std::shared_ptr { auto agent = std::make_shared(log_dir); if (cloud_agent) agent->set_cloud_agent(cloud_agent); return agent; }); } } // anonymous namespace bool NetworkAgentFactory::register_printer_agent(const std::string& id, const std::string& display_name, PrinterAgentFactory factory) { std::lock_guard lock(s_registry_mutex); auto& agents = get_printer_agents(); return agents.emplace(id, PrinterAgentInfo(id, display_name, std::move(factory))).second; } bool NetworkAgentFactory::is_printer_agent_registered(const std::string& id) { std::lock_guard lock(s_registry_mutex); auto& agents = get_printer_agents(); return agents.find(id) != agents.end(); } const PrinterAgentInfo* NetworkAgentFactory::get_printer_agent_info(const std::string& id) { std::lock_guard lock(s_registry_mutex); auto& agents = get_printer_agents(); auto it = agents.find(id); return (it != agents.end()) ? &it->second : nullptr; } std::vector NetworkAgentFactory::get_registered_printer_agents() { std::lock_guard lock(s_registry_mutex); auto& agents = get_printer_agents(); std::vector result; result.reserve(agents.size()); for (const auto& pair : agents) { result.push_back(pair.second); } return result; } std::shared_ptr NetworkAgentFactory::create_printer_agent_by_id(const std::string& id, std::shared_ptr cloud_agent, const std::string& log_dir) { std::lock_guard lock(s_registry_mutex); // Check cache first auto& cache = get_printer_agent_cache(); auto cache_it = cache.find(id); if (cache_it != cache.end()) { BOOST_LOG_TRIVIAL(info) << "Reusing cached printer agent: " << id; if (cloud_agent) cache_it->second->set_cloud_agent(cloud_agent); return cache_it->second; } // Not cached — create via factory auto& agents = get_printer_agents(); auto it = agents.find(id); if (it == agents.end()) { BOOST_LOG_TRIVIAL(warning) << "Unknown printer agent ID: " << id; return nullptr; } auto agent = it->second.factory(cloud_agent, log_dir); if (agent) { BOOST_LOG_TRIVIAL(info) << "Created and cached printer agent: " << id; cache[id] = agent; } return agent; } void NetworkAgentFactory::clear_printer_agent_cache() { std::lock_guard lock(s_registry_mutex); auto& cache = get_printer_agent_cache(); for (auto& pair : cache) { if (pair.second) pair.second->disconnect_printer(); } cache.clear(); BOOST_LOG_TRIVIAL(info) << "Printer agent cache cleared"; } void NetworkAgentFactory::register_all_agents() { register_agent(); register_agent(); register_agent(); register_agent(); // BBLPrinterAgent takes no constructor args, so register manually { auto info = BBLPrinterAgent::get_agent_info_static(); register_printer_agent(info.id, info.name, [](std::shared_ptr cloud_agent, const std::string& /*log_dir*/) -> std::shared_ptr { auto agent = std::make_shared(); if (cloud_agent) agent->set_cloud_agent(cloud_agent); return agent; }); } } std::unique_ptr create_agent_from_config(const std::string& log_dir, AppConfig* app_config) { if (!app_config) return std::make_unique(nullptr, nullptr); // Always create Orca cloud agent as the primary provider auto cloud_agent = NetworkAgentFactory::create_cloud_agent(ORCA_CLOUD_PROVIDER, log_dir); if (!cloud_agent) { BOOST_LOG_TRIVIAL(error) << "Failed to create cloud agent"; } auto agent = std::make_unique(std::move(cloud_agent), nullptr); if (agent) { // create orca cloud agent first auto* orca_cloud = dynamic_cast(agent->get_cloud_agent().get()); if (orca_cloud) { orca_cloud->configure_urls(app_config); } // Initialize third-party cloud agents from config auto providers = app_config->get_cloud_providers(); for (const auto& provider : providers) { if (provider == ORCA_CLOUD_PROVIDER) continue; // Primary agent already created above auto third_party_agent = NetworkAgentFactory::create_cloud_agent(provider, log_dir); if (third_party_agent) { agent->add_cloud_agent(provider, std::move(third_party_agent)); BOOST_LOG_TRIVIAL(info) << "Initialized third-party cloud agent: " << provider; } } } return agent; } } // namespace Slic3r