From 4bc848e2f15b026d8aba504a9aa56b8e7b2d4baf Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Tue, 3 Feb 2026 11:36:29 -0600 Subject: [PATCH] Apply profiles server-side rather than client-side, signal active profile update, forward loaded profile to local client for plugins --- NetworkClient.cpp | 55 +++++++ NetworkClient.h | 4 + NetworkProtocol.h | 6 + NetworkServer.cpp | 403 ++++++++++++++++++++++++++++++++++----------- NetworkServer.h | 22 ++- ProfileManager.cpp | 65 +++++++- ProfileManager.h | 4 + 7 files changed, 456 insertions(+), 103 deletions(-) diff --git a/NetworkClient.cpp b/NetworkClient.cpp index f7e352e03..34c64f462 100644 --- a/NetworkClient.cpp +++ b/NetworkClient.cpp @@ -12,6 +12,8 @@ #include #include "LogManager.h" #include "NetworkClient.h" +#include "ProfileManager.h" +#include "ResourceManager.h" #include "RGBController_Network.h" #include "StringUtils.h" @@ -1103,6 +1105,18 @@ void NetworkClient::ListenThreadFunction() } break; + case NET_PACKET_ID_PROFILEMANAGER_ACTIVE_PROFILE_CHANGED: + ProcessRequest_ProfileManager_ActiveProfileChanged(header.pkt_size, data); + break; + + case NET_PACKET_ID_PROFILEMANAGER_PROFILE_LOADED: + ProcessRequest_ProfileManager_ProfileLoaded(header.pkt_size, data); + break; + + case NET_PACKET_ID_PROFILEMANAGER_PROFILE_ABOUT_TO_LOAD: + ProcessRequest_ProfileManager_ProfileAboutToLoad(); + break; + case NET_PACKET_ID_RGBCONTROLLER_SIGNALUPDATE: ProcessRequest_RGBController_SignalUpdate(header.pkt_size, data, header.pkt_dev_id); break; @@ -1341,6 +1355,47 @@ void NetworkClient::ProcessRequest_DeviceListChanged() server_initialized = false; } +void NetworkClient::ProcessRequest_ProfileManager_ActiveProfileChanged(unsigned int data_size, char * data) +{ + if(data_size == 0 || data == NULL) + { + return; + } + + std::string profile_name; + profile_name.assign(data, data_size); + profile_name = StringUtils::remove_null_terminating_chars(profile_name); + + ResourceManager::get()->GetProfileManager()->SetActiveProfile(profile_name); +} + +void NetworkClient::ProcessRequest_ProfileManager_ProfileAboutToLoad() +{ + ResourceManager::get()->GetProfileManager()->OnProfileAboutToLoad(); + + NetPacketHeader pkt_hdr; + + InitNetPacketHeader(&pkt_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_PROFILE_ABOUT_TO_LOAD, 0); + + send_in_progress.lock(); + send(client_sock, (char *)&pkt_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send_in_progress.unlock(); +} + +void NetworkClient::ProcessRequest_ProfileManager_ProfileLoaded(unsigned int data_size, char * data) +{ + if(data_size == 0 || data == NULL) + { + return; + } + + std::string profile_json_str; + profile_json_str.assign(data, data_size); + profile_json_str = StringUtils::remove_null_terminating_chars(profile_json_str); + + ResourceManager::get()->GetProfileManager()->OnProfileLoaded(profile_json_str); +} + void NetworkClient::ProcessRequest_RGBController_SignalUpdate(unsigned int data_size, char * data, unsigned int dev_id) { RGBController * controller; diff --git a/NetworkClient.h b/NetworkClient.h index 68c83e0f3..674d369ba 100644 --- a/NetworkClient.h +++ b/NetworkClient.h @@ -226,6 +226,10 @@ private: void ProcessRequest_ServerFlags(unsigned int data_size, char * data); void ProcessRequest_ServerString(unsigned int data_size, char * data); + void ProcessRequest_ProfileManager_ActiveProfileChanged(unsigned int data_size, char * data); + void ProcessRequest_ProfileManager_ProfileAboutToLoad(); + void ProcessRequest_ProfileManager_ProfileLoaded(unsigned int data_size, char * data); + void SendData_ClientFlags(); void SendData_ClientString(); void SendRequest_ControllerIDs(); diff --git a/NetworkProtocol.h b/NetworkProtocol.h index 121363c10..c32947421 100644 --- a/NetworkProtocol.h +++ b/NetworkProtocol.h @@ -106,6 +106,12 @@ enum NET_PACKET_ID_PROFILEMANAGER_UPLOAD_PROFILE = 154, /* Upload a profile to the server in JSON format */ NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE = 155, /* Download a profile from the server in JSON format*/ NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE = 156, /* Get the active profile name */ + NET_PACKET_ID_PROFILEMANAGER_ACTIVE_PROFILE_CHANGED + = 157, /* Indicate to clients active profile has changed */ + NET_PACKET_ID_PROFILEMANAGER_PROFILE_LOADED = 158, /* Notify to active client that profile has loaded */ + /* Forwards loaded profile data */ + NET_PACKET_ID_PROFILEMANAGER_PROFILE_ABOUT_TO_LOAD + = 159, /* Indicate to clients profile about to load */ /*----------------------------------------------------------------------------------------------------------*\ | PluginManager functions | diff --git a/NetworkServer.cpp b/NetworkServer.cpp index 1ca33f392..f641c1b0e 100644 --- a/NetworkServer.cpp +++ b/NetworkServer.cpp @@ -389,6 +389,16 @@ void NetworkServer::StartServer() freeaddrinfo(result); server_online = true; + /*-----------------------------------------------------*\ + | Start the ProfileManager thread | + \*-----------------------------------------------------*/ + profilemanager_thread = new NetworkServerControllerThread; + + profilemanager_thread->id = 0; + profilemanager_thread->index = 0; + profilemanager_thread->online = true; + profilemanager_thread->thread = new std::thread(&NetworkServer::ProfileManagerListenThread, this, profilemanager_thread); + /*-----------------------------------------------------*\ | Start the connection thread | \*-----------------------------------------------------*/ @@ -852,7 +862,7 @@ void NetworkServer::ControllerListenThread(NetworkServerControllerThread * this_ controller_ids_mutex.lock_shared(); - switch(queue_entry.pkt_id) + switch(queue_entry.header.pkt_id) { case NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS: ProcessRequest_RGBController_UpdateLEDs(this_thread->id, (unsigned char *)queue_entry.data, queue_entry.client_protocol_version); @@ -887,6 +897,58 @@ void NetworkServer::ControllerListenThread(NetworkServerControllerThread * this_ } } +void NetworkServer::ProfileManagerListenThread(NetworkServerControllerThread * this_thread) +{ + while(this_thread->online == true) + { + std::unique_lock start_lock(this_thread->start_mutex); + this_thread->start_cv.wait(start_lock); + + while(this_thread->queue.size() > 0) + { + NetworkServerControllerThreadQueueEntry queue_entry; + + this_thread->queue_mutex.lock(); + queue_entry = this_thread->queue.front(); + this_thread->queue.pop(); + this_thread->queue_mutex.unlock(); + + switch(queue_entry.header.pkt_id) + { + case NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST: + SendReply_ProfileList(queue_entry.client_sock); + break; + + case NET_PACKET_ID_PROFILEMANAGER_SAVE_PROFILE: + ProcessRequest_ProfileManager_SaveProfile(queue_entry.header.pkt_size, queue_entry.data); + break; + + case NET_PACKET_ID_PROFILEMANAGER_LOAD_PROFILE: + ProcessRequest_ProfileManager_LoadProfile(queue_entry.header.pkt_size, queue_entry.data); + break; + + case NET_PACKET_ID_PROFILEMANAGER_DELETE_PROFILE: + ProcessRequest_ProfileManager_DeleteProfile(queue_entry.header.pkt_size, queue_entry.data); + break; + + case NET_PACKET_ID_PROFILEMANAGER_UPLOAD_PROFILE: + ProcessRequest_ProfileManager_UploadProfile(queue_entry.header.pkt_size, queue_entry.data); + break; + + case NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE: + ProcessRequest_ProfileManager_DownloadProfile(queue_entry.client_sock, queue_entry.header.pkt_size, queue_entry.data); + break; + + case NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE: + ProcessRequest_ProfileManager_GetActiveProfile(queue_entry.client_sock); + break; + } + + delete[] queue_entry.data; + } + } +} + void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) { SOCKET client_sock = client_info->client_sock; @@ -1030,118 +1092,37 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) break; /*-------------------------------------------------*\ - | ProfileManager functions | + | ProfileManager functions are handled in a | + | separate thread, queue the messages | \*-------------------------------------------------*/ case NET_PACKET_ID_PROFILEMANAGER_GET_PROFILE_LIST: - SendReply_ProfileList(client_sock); - break; - case NET_PACKET_ID_PROFILEMANAGER_SAVE_PROFILE: - if(data == NULL) - { - break; - } - - if(profile_manager) - { - std::string profile_name; - profile_name.assign(data, header.pkt_size); - profile_name = StringUtils::remove_null_terminating_chars(profile_name); - - profile_manager->SaveProfile(profile_name); - } - break; - case NET_PACKET_ID_PROFILEMANAGER_LOAD_PROFILE: - if(data == NULL) - { - break; - } - - if(profile_manager) - { - std::string profile_name; - profile_name.assign(data, header.pkt_size); - profile_name = StringUtils::remove_null_terminating_chars(profile_name); - - profile_manager->LoadProfile(profile_name); - } - break; - case NET_PACKET_ID_PROFILEMANAGER_DELETE_PROFILE: - if(data == NULL) - { - break; - } - - if(profile_manager) - { - std::string profile_name; - profile_name.assign(data, header.pkt_size); - profile_name = StringUtils::remove_null_terminating_chars(profile_name); - - profile_manager->DeleteProfile(profile_name); - } - break; - case NET_PACKET_ID_PROFILEMANAGER_UPLOAD_PROFILE: - if(data == NULL) - { - break; - } - - if(profile_manager) - { - std::string profile_json_string; - profile_json_string.assign(data, header.pkt_size); - profile_json_string = StringUtils::remove_null_terminating_chars(profile_json_string); - - nlohmann::json profile_json = nlohmann::json::parse(profile_json_string); - - profile_manager->SaveProfileFromJSON(profile_json); - } - break; - case NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE: - if(data == NULL) - { - break; - } - - if(profile_manager) - { - std::string profile_name; - profile_name.assign(data, header.pkt_size); - profile_name = StringUtils::remove_null_terminating_chars(profile_name); - - std::string profile_json_string = profile_manager->ReadProfileJSON(profile_name).dump(); - - NetPacketHeader reply_hdr; - - InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE, (unsigned int)strlen(profile_json_string.c_str()) + 1); - - send_in_progress.lock(); - send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); - send(client_sock, (char *)profile_json_string.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL); - send_in_progress.unlock(); - } - break; - case NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE: { - std::string active_profile_name = profile_manager->GetActiveProfile(); + profilemanager_thread->queue_mutex.lock(); - NetPacketHeader reply_hdr; + NetworkServerControllerThreadQueueEntry new_entry; + new_entry.data = data; + new_entry.header = header; + new_entry.client_sock = client_sock; + new_entry.client_protocol_version = client_info->client_protocol_version; - InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE, (unsigned int)strlen(active_profile_name.c_str()) + 1); + profilemanager_thread->queue.push(new_entry); + profilemanager_thread->queue_mutex.unlock(); + profilemanager_thread->start_cv.notify_all(); - send_in_progress.lock(); - send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); - send(client_sock, (char *)active_profile_name.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL); - send_in_progress.unlock(); + delete_data = false; } break; + case NET_PACKET_ID_PROFILEMANAGER_PROFILE_ABOUT_TO_LOAD: + profile_about_to_load_acks++; + break; + /*-------------------------------------------------*\ | PluginManager functions | \*-------------------------------------------------*/ @@ -1293,8 +1274,8 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info) NetworkServerControllerThreadQueueEntry new_entry; new_entry.data = data; - new_entry.pkt_id = header.pkt_id; - new_entry.size = header.pkt_size; + new_entry.header = header; + new_entry.client_sock = client_sock; new_entry.client_protocol_version = client_info->client_protocol_version; controller_threads[controller_thread_idx]->queue.push(new_entry); @@ -1487,6 +1468,119 @@ void NetworkServer::ProcessRequest_RescanDevices() ResourceManager::get()->RescanDevices(); } +void NetworkServer::ProcessRequest_ProfileManager_DeleteProfile(unsigned int data_size, char * data) +{ + if(data == NULL) + { + return; + } + + if(profile_manager) + { + std::string profile_name; + profile_name.assign(data, data_size); + profile_name = StringUtils::remove_null_terminating_chars(profile_name); + + profile_manager->DeleteProfile(profile_name); + } +} + +void NetworkServer::ProcessRequest_ProfileManager_DownloadProfile(SOCKET client_sock, unsigned int data_size, char * data) +{ + if(data == NULL) + { + return; + } + + if(profile_manager) + { + std::string profile_name; + profile_name.assign(data, data_size); + profile_name = StringUtils::remove_null_terminating_chars(profile_name); + + std::string profile_json_string = profile_manager->ReadProfileJSON(profile_name).dump(); + + NetPacketHeader reply_hdr; + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_DOWNLOAD_PROFILE, (unsigned int)strlen(profile_json_string.c_str()) + 1); + + send_in_progress.lock(); + send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_sock, (char *)profile_json_string.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL); + send_in_progress.unlock(); + } +} + +void NetworkServer::ProcessRequest_ProfileManager_GetActiveProfile(SOCKET client_sock) +{ + if(profile_manager) + { + std::string active_profile_name = profile_manager->GetActiveProfile(); + + NetPacketHeader reply_hdr; + + InitNetPacketHeader(&reply_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_GET_ACTIVE_PROFILE, (unsigned int)strlen(active_profile_name.c_str()) + 1); + + send_in_progress.lock(); + send(client_sock, (char *)&reply_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_sock, (char *)active_profile_name.c_str(), reply_hdr.pkt_size, MSG_NOSIGNAL); + send_in_progress.unlock(); + } +} + +void NetworkServer::ProcessRequest_ProfileManager_LoadProfile(unsigned int data_size, char * data) +{ + if(data == NULL) + { + return; + } + + if(profile_manager) + { + std::string profile_name; + profile_name.assign(data, data_size); + profile_name = StringUtils::remove_null_terminating_chars(profile_name); + + profile_manager->LoadProfile(profile_name); + } +} + +void NetworkServer::ProcessRequest_ProfileManager_SaveProfile(unsigned int data_size, char * data) +{ + if(data == NULL) + { + return; + } + + if(profile_manager) + { + std::string profile_name; + profile_name.assign(data, data_size); + profile_name = StringUtils::remove_null_terminating_chars(profile_name); + + profile_manager->SaveProfile(profile_name); + } +} + +void NetworkServer::ProcessRequest_ProfileManager_UploadProfile(unsigned int data_size, char * data) +{ + if(data == NULL) + { + return; + } + + if(profile_manager) + { + std::string profile_json_string; + profile_json_string.assign(data, data_size); + profile_json_string = StringUtils::remove_null_terminating_chars(profile_json_string); + + nlohmann::json profile_json = nlohmann::json::parse(profile_json_string); + + profile_manager->SaveProfileFromJSON(profile_json); + } +} + void NetworkServer::ProcessRequest_RGBController_AddSegment(unsigned int controller_id, unsigned char * data_ptr, unsigned int protocol_version) { /*-----------------------------------------------------*\ @@ -2378,6 +2472,115 @@ void NetworkServer::SendRequest_DeviceListChanged(SOCKET client_sock) send_in_progress.unlock(); } +void NetworkServer::ProfileManager_ProfileAboutToLoad() +{ + SendRequest_ProfileManager_ProfileAboutToLoad(); + + /*-----------------------------------------------------*\ + | Wait for about to load completion or timeout | + \*-----------------------------------------------------*/ + unsigned int timeout = 0; + + while(true) + { + /*-------------------------------------------------*\ + | Test for the following conditions: | + | 1. All acks to ProfileAboutToLoad have been | + | received from clients | + | 2. All RGBController queues have been emptied | + | 3. We haven't exceeded the 1 second timeout | + \*-------------------------------------------------*/ + bool all_acks_received = (profile_about_to_load_acks >= profile_about_to_load_count); + + bool all_rgbcontroller_queues_emptied = true; + + controller_threads_mutex.lock_shared(); + for(std::size_t controller_thread_idx = 0; controller_thread_idx < controller_threads.size(); controller_thread_idx++) + { + if(controller_threads[controller_thread_idx]->queue.size() > 0) + { + all_rgbcontroller_queues_emptied = false; + break; + } + } + controller_threads_mutex.unlock_shared(); + + bool timed_out = (timeout >= 1000); + + if((all_acks_received && all_rgbcontroller_queues_emptied) || timed_out) + { + break; + } + + timeout++; + std::this_thread::sleep_for(1ms); + } +} + +void NetworkServer::SendRequest_ProfileManager_ActiveProfileChanged(std::string profile_name) +{ + NetPacketHeader pkt_hdr; + + InitNetPacketHeader(&pkt_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_ACTIVE_PROFILE_CHANGED, strlen(profile_name.c_str()) + 1); + + for(std::size_t client_idx = 0; client_idx < ServerClients.size(); client_idx++) + { + if(ServerClients[client_idx]->client_flags & NET_CLIENT_FLAG_SUPPORTS_PROFILEMANAGER) + { + SOCKET client_sock = ServerClients[client_idx]->client_sock; + + send_in_progress.lock(); + send(client_sock, (char *)&pkt_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_sock, (char *)profile_name.c_str(), pkt_hdr.pkt_size, MSG_NOSIGNAL); + send_in_progress.unlock(); + } + } +} + +void NetworkServer::SendRequest_ProfileManager_ProfileAboutToLoad() +{ + NetPacketHeader pkt_hdr; + + InitNetPacketHeader(&pkt_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_PROFILE_ABOUT_TO_LOAD, 0); + + profile_about_to_load_acks = 0; + profile_about_to_load_count = 0; + + for(std::size_t client_idx = 0; client_idx < ServerClients.size(); client_idx++) + { + if(ServerClients[client_idx]->client_flags & NET_CLIENT_FLAG_SUPPORTS_PROFILEMANAGER) + { + profile_about_to_load_count++; + + SOCKET client_sock = ServerClients[client_idx]->client_sock; + + send_in_progress.lock(); + send(client_sock, (char *)&pkt_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send_in_progress.unlock(); + } + } +} + +void NetworkServer::SendRequest_ProfileManager_ProfileLoaded(std::string profile_json_string) +{ + NetPacketHeader pkt_hdr; + + InitNetPacketHeader(&pkt_hdr, 0, NET_PACKET_ID_PROFILEMANAGER_PROFILE_LOADED, strlen(profile_json_string.c_str()) + 1); + + for(std::size_t client_idx = 0; client_idx < ServerClients.size(); client_idx++) + { + if((ServerClients[client_idx]->client_flags & NET_CLIENT_FLAG_SUPPORTS_PROFILEMANAGER) && (ServerClients[client_idx]->client_is_local_client)) + { + SOCKET client_sock = ServerClients[client_idx]->client_sock; + + send_in_progress.lock(); + send(client_sock, (char *)&pkt_hdr, sizeof(NetPacketHeader), MSG_NOSIGNAL); + send(client_sock, (char *)profile_json_string.c_str(), pkt_hdr.pkt_size, MSG_NOSIGNAL); + send_in_progress.unlock(); + } + } +} + void NetworkServer::SendRequest_RGBController_SignalUpdate(RGBController * controller_ptr, unsigned int update_reason) { /*-----------------------------------------------------*\ diff --git a/NetworkServer.h b/NetworkServer.h index 2cc61606b..10c705d52 100644 --- a/NetworkServer.h +++ b/NetworkServer.h @@ -32,9 +32,9 @@ typedef void (*NetServerCallback)(void *); typedef struct { + NetPacketHeader header; char * data; - unsigned int pkt_id; - unsigned int size; + SOCKET client_sock; unsigned int client_protocol_version; } NetworkServerControllerThreadQueueEntry; @@ -128,6 +128,10 @@ public: void SetProfileManager(ProfileManagerInterface* profile_manager_pointer); void SetSettingsManager(SettingsManagerInterface* settings_manager_pointer); + void ProfileManager_ProfileAboutToLoad(); + + void SendRequest_ProfileManager_ActiveProfileChanged(std::string profile_name); + void SendRequest_ProfileManager_ProfileLoaded(std::string profile_json_string); void SendRequest_RGBController_SignalUpdate(RGBController * controller_ptr, unsigned int update_reason); private: @@ -156,6 +160,8 @@ private: std::shared_mutex controller_threads_mutex; bool controller_updating; + NetworkServerControllerThread * profilemanager_thread; + /*-----------------------------------------------------*\ | Server clients | \*-----------------------------------------------------*/ @@ -184,6 +190,8 @@ private: ProfileManagerInterface* profile_manager; SettingsManagerInterface* settings_manager; + unsigned int profile_about_to_load_acks; + unsigned int profile_about_to_load_count; private: #ifdef WIN32 /*-----------------------------------------------------*\ @@ -208,6 +216,7 @@ private: void ConnectionThreadFunction(int socket_idx); void ControllerListenThread(NetworkServerControllerThread * this_thread); void ListenThreadFunction(NetworkClientInfo * client_sock); + void ProfileManagerListenThread(NetworkServerControllerThread * this_thread); /*-----------------------------------------------------*\ | Server Protocol functions | @@ -217,6 +226,13 @@ private: void ProcessRequest_ClientString(SOCKET client_sock, unsigned int data_size, char * data); void ProcessRequest_RescanDevices(); + void ProcessRequest_ProfileManager_DeleteProfile(unsigned int data_size, char * data); + void ProcessRequest_ProfileManager_DownloadProfile(SOCKET client_sock, unsigned int data_size, char * data); + void ProcessRequest_ProfileManager_GetActiveProfile(SOCKET client_sock); + void ProcessRequest_ProfileManager_LoadProfile(unsigned int data_size, char * data); + void ProcessRequest_ProfileManager_SaveProfile(unsigned int data_size, char * data); + void ProcessRequest_ProfileManager_UploadProfile(unsigned int data_size, char * data); + void ProcessRequest_RGBController_AddSegment(unsigned int controller_id, unsigned char * data_ptr, unsigned int protocol_version); void ProcessRequest_RGBController_ClearSegments(unsigned int controller_id, unsigned char * data_ptr, unsigned int protocol_version); void ProcessRequest_RGBController_ResizeZone(unsigned int controller_id, unsigned char * data_ptr, unsigned int protocol_version); @@ -242,6 +258,8 @@ private: void SendRequest_DetectionStarted(SOCKET client_sock, unsigned int protocol_version); void SendRequest_DeviceListChanged(SOCKET client_sock); + void SendRequest_ProfileManager_ProfileAboutToLoad(); + /*-----------------------------------------------------*\ | Private helper functions | \*-----------------------------------------------------*/ diff --git a/ProfileManager.cpp b/ProfileManager.cpp index 678f19f3e..7e19f85dd 100644 --- a/ProfileManager.cpp +++ b/ProfileManager.cpp @@ -16,6 +16,7 @@ #include "LogManager.h" #include "NetworkClient.h" #include "NetworkProtocol.h" +#include "NetworkServer.h" #include "PluginManagerInterface.h" #include "ProfileManager.h" #include "ResourceManager.h" @@ -230,7 +231,57 @@ bool ProfileManager::LoadAutoProfileSuspend() bool ProfileManager::LoadProfile(std::string profile_name) { - return(LoadProfileWithOptions(profile_name, false, true)); + if(ResourceManager::get()->IsLocalClient() && (ResourceManager::get()->GetLocalClient()->GetSupportsProfileManagerAPI())) + { + ResourceManager::get()->GetLocalClient()->ProfileManager_LoadProfile(profile_name); + + return(true); + } + else + { + bool success = false; + + success = LoadProfileWithOptions(profile_name, false, true); + + if(success) + { + ResourceManager::get()->GetServer()->SendRequest_ProfileManager_ActiveProfileChanged(profile_name); + } + + return(success); + } +} + +void ProfileManager::OnProfileAboutToLoad() +{ + /*-------------------------------------------------*\ + | Signal to plugins that a profile is about to load | + \*-------------------------------------------------*/ + PluginManagerInterface* plugin_manager = ResourceManager::get()->GetPluginManager(); + + if(plugin_manager != NULL) + { + plugin_manager->OnProfileAboutToLoad(); + } + + ResourceManager::get()->GetServer()->ProfileManager_ProfileAboutToLoad(); +} + +void ProfileManager::OnProfileLoaded(std::string profile_json_string) +{ + nlohmann::json profile_json; + + profile_json = nlohmann::json::parse(profile_json_string); + + /*-------------------------------------------------*\ + | Get plugin profile data | + \*-------------------------------------------------*/ + PluginManagerInterface* plugin_manager = ResourceManager::get()->GetPluginManager(); + + if(plugin_manager != NULL && profile_json.contains("plugins")) + { + plugin_manager->OnProfileLoad(profile_json["plugins"]); + } } nlohmann::json ProfileManager::ReadProfileJSON(std::string profile_name) @@ -421,6 +472,11 @@ bool ProfileManager::SaveSizes() return(true); } +void ProfileManager::SetActiveProfile(std::string profile_name) +{ + active_profile = profile_name; +} + void ProfileManager::SetConfigurationDirectory(const filesystem::path& directory) { configuration_directory = directory; @@ -775,6 +831,8 @@ bool ProfileManager::LoadProfileWithOptions plugin_manager->OnProfileAboutToLoad(); } + ResourceManager::get()->GetServer()->ProfileManager_ProfileAboutToLoad(); + /*-------------------------------------------------*\ | Set up used flag vector | \*-------------------------------------------------*/ @@ -814,6 +872,11 @@ bool ProfileManager::LoadProfileWithOptions plugin_manager->OnProfileLoad(profile_json["plugins"]); } + /*-------------------------------------------------*\ + | Notify local client | + \*-------------------------------------------------*/ + ResourceManager::get()->GetServer()->SendRequest_ProfileManager_ProfileLoaded(profile_json.dump()); + return(ret_val); } diff --git a/ProfileManager.h b/ProfileManager.h index 4c68a6570..16a76ed8d 100644 --- a/ProfileManager.h +++ b/ProfileManager.h @@ -82,12 +82,16 @@ public: bool LoadProfile(std::string profile_name); + void OnProfileAboutToLoad(); + void OnProfileLoaded(std::string profile_json_string); + nlohmann::json ReadProfileJSON(std::string profile_name); bool SaveProfile(std::string profile_name); bool SaveProfileFromJSON(nlohmann::json profile_json); bool SaveSizes(); + void SetActiveProfile(std::string profile_name); void SetConfigurationDirectory(const filesystem::path& directory); void SetProfileListFromDescription(char * data_buf);