2026-05-11 23:06:39 +03:00
/*
* InfiniPaint
* Copyright ( C ) 2025 - 2026 Yousef Khadadeh
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https : //www.gnu.org/licenses/>.
*/
2025-12-06 14:16:50 +03:00
# include "NetObjManager.hpp"
2025-12-11 16:05:41 +03:00
# include "NetObjTemporaryPtr.hpp"
2025-12-06 14:16:50 +03:00
namespace NetworkingObjects {
2025-12-13 13:03:27 +03:00
NetObjManager : : NetObjManager ( bool initIsServer ) :
2025-12-07 17:35:27 +03:00
isServer ( initIsServer ) ,
2025-12-06 14:16:50 +03:00
nextTypeID ( 0 )
{ }
2025-12-07 23:09:17 +03:00
bool NetObjManager : : is_server ( ) const {
return isServer ;
}
2025-12-07 17:35:27 +03:00
void NetObjManager : : read_update_message ( cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & clientReceivedFrom ) {
2025-12-06 14:16:50 +03:00
NetObjID id ;
a ( id ) ;
auto it = objectData . find ( id ) ;
if ( it = = objectData . end ( ) )
return ;
2025-12-13 13:03:27 +03:00
typeList . get_net_type_data ( isServer , it - > second . netTypeID ) . readUpdateFunc ( NetObjTemporaryPtr < void > ( this , id , it - > second . p ) , a , clientReceivedFrom ) ;
2025-12-06 14:16:50 +03:00
}
2025-12-23 14:10:33 +03:00
void NetObjManager : : read_many_update_message ( cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & clientReceivedFrom ) {
for ( ; ; ) {
bool objExists ;
a ( objExists ) ;
if ( ! objExists )
break ;
read_update_message ( a , clientReceivedFrom ) ;
}
}
void NetObjManager : : set_client ( std : : shared_ptr < NetClient > initClient , MessageCommandType initUpdateCommandID , MessageCommandType initMultiUpdateCommandID ) {
2025-12-06 14:16:50 +03:00
client = initClient ;
updateCommandID = initUpdateCommandID ;
2025-12-23 14:10:33 +03:00
multiUpdateCommandID = initMultiUpdateCommandID ;
2025-12-06 14:16:50 +03:00
}
2025-12-23 14:10:33 +03:00
void NetObjManager : : set_server ( std : : shared_ptr < NetServer > initServer , MessageCommandType initUpdateCommandID , MessageCommandType initMultiUpdateCommandID ) {
2025-12-06 14:16:50 +03:00
server = initServer ;
updateCommandID = initUpdateCommandID ;
2025-12-23 14:10:33 +03:00
multiUpdateCommandID = initMultiUpdateCommandID ;
2025-12-06 14:16:50 +03:00
}
2025-12-17 15:50:14 +03:00
void NetObjManager : : disconnect ( ) {
server = nullptr ;
client = nullptr ;
}
2025-12-23 14:10:33 +03:00
bool NetObjManager : : is_connected ( ) const {
return ( server & & ! server - > is_disconnected ( ) ) | | ( client & & ! client - > is_disconnected ( ) ) ;
}
2026-01-02 17:11:32 +03:00
void NetObjManager : : set_netid_reassign_callback ( const std : : function < void ( const NetworkingObjects : : NetObjID & oldID , const NetworkingObjects : : NetObjID & newID ) > & newNetIDReassignCallback ) {
netIDReassignCallback = newNetIDReassignCallback ;
}
void NetObjManager : : set_netobj_destroy_callback ( const std : : function < void ( const NetworkingObjects : : NetObjID & netID ) > & newDestroyCallback ) {
destroyCallback = newDestroyCallback ;
}
2025-12-23 14:10:33 +03:00
void NetObjManager : : send_multi_update_messsage ( std : : function < void ( ) > captureSendBlock , SendUpdateType updateType , const std : : shared_ptr < NetServer : : ClientData > & specificClient ) {
2026-05-28 21:55:30 +03:00
if ( is_connected ( ) & & multiUpdateData . expired ( ) ) { // Check for multiUpdateData.expired() to make sure we aren't overriding a previous call to send_multi_update_messsage
2025-12-23 14:10:33 +03:00
std : : shared_ptr < MultiUpdateData > d = std : : make_shared < MultiUpdateData > ( ) ;
d - > ss = std : : make_shared < std : : stringstream > ( std : : ios : : binary | std : : ios : : out ) ;
d - > outArchive = std : : make_unique < cereal : : PortableBinaryOutputArchive > ( * d - > ss ) ;
( * d - > outArchive ) ( multiUpdateCommandID ) ;
multiUpdateData = d ; // Using weak pointer here ensures that object will be freed
captureSendBlock ( ) ;
if ( ! d - > channelToSendTo . empty ( ) ) {
( * d - > outArchive ) ( false ) ;
d - > outArchive = nullptr ; // Destroy output archive to finalize serialization
send_update_data_by_type ( d - > channelToSendTo , d - > ss , updateType , specificClient ) ;
}
}
else
captureSendBlock ( ) ;
}
void NetObjManager : : send_update_data_by_type ( const std : : string & channel , const std : : shared_ptr < std : : stringstream > & ss , SendUpdateType updateType , const std : : shared_ptr < NetServer : : ClientData > & specificClient ) {
if ( client & & updateType ! = SendUpdateType : : SEND_TO_ALL )
throw std : : runtime_error ( " [NetObjManager::send_update_data_by_type] Client can only send to all (to server) " ) ;
switch ( updateType ) {
case SendUpdateType : : SEND_TO_ALL :
if ( client )
client - > send_string_stream_to_server ( channel , ss ) ;
else
server - > send_string_stream_to_all_clients ( channel , ss ) ;
break ;
case SendUpdateType : : SEND_TO_ALL_EXCEPT :
server - > send_string_stream_to_all_clients_except ( specificClient , channel , ss ) ;
break ;
case SendUpdateType : : SEND_TO_SPECIFIC_CLIENT :
server - > send_string_stream_to_client ( specificClient , channel , ss ) ;
break ;
}
}
2025-12-06 14:16:50 +03:00
}