2025-12-07 17:35:27 +03:00
# pragma once
# include "Helpers/Networking/NetLibrary.hpp"
2025-12-11 16:05:41 +03:00
# include "NetObjOwnerPtr.hpp"
# include "NetObjTemporaryPtr.hpp"
2025-12-08 14:28:01 +03:00
# include "NetObjID.hpp"
2025-12-07 17:35:27 +03:00
# include "cereal/archives/portable_binary.hpp"
# include "NetObjManagerTypeList.hpp"
namespace NetworkingObjects {
enum class ObjPtrOrderedListCommand_StoC : uint8_t {
2025-12-11 16:05:41 +03:00
INSERT_SINGLE_CONSTRUCT ,
INSERT_SINGLE_REFERENCE ,
2025-12-07 17:35:27 +03:00
ERASE_SINGLE
} ;
enum class ObjPtrOrderedListCommand_CtoS : uint8_t {
INSERT_SINGLE ,
ERASE_SINGLE
} ;
2025-12-10 10:24:57 +03:00
template < typename T > struct NetObjOrderedListObjectInfo {
2025-12-11 16:05:41 +03:00
NetObjOrderedListObjectInfo ( NetObjOwnerPtr < T > iObj , uint32_t iPos ) :
obj ( std : : move ( iObj ) ) ,
pos ( iPos )
2025-12-10 10:24:57 +03:00
{ }
NetObjOrderedListObjectInfo ( ) = delete ;
2025-12-11 16:05:41 +03:00
NetObjOwnerPtr < T > obj ;
2025-12-10 10:24:57 +03:00
uint32_t pos ;
2025-12-07 17:35:27 +03:00
} ;
template < typename T > using NetObjOrderedListObjectInfoPtr = std : : shared_ptr < NetObjOrderedListObjectInfo < T > > ;
template < typename T > void set_positions_for_object_info_vector ( std : : vector < NetObjOrderedListObjectInfoPtr < T > > & v , uint32_t i = 0 ) {
uint32_t vSize = static_cast < uint32_t > ( v . size ( ) ) ;
for ( ; i < vSize ; i + + )
v [ i ] - > pos = i ;
}
template < typename T > class NetObjOrderedList {
public :
2025-12-08 20:51:11 +03:00
// Don't use this function unless you're sure that class T isn't a base class
2025-12-11 16:05:41 +03:00
template < typename . . . Args > NetObjTemporaryPtr < T > emplace_back_direct ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , Args & & . . . items ) {
NetObjOwnerPtr < T > newObj = l . get_obj_man ( ) - > template make_obj_direct < T > ( items . . . ) ;
NetObjTemporaryPtr < T > tempPtr ( newObj ) ;
l - > insert ( l , nullptr , l - > size ( ) , std : : move ( newObj ) ) ;
return tempPtr ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
static void push_back_and_send_create ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , T * newObj ) {
l - > insert ( l , nullptr , l - > size ( ) , newObj ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
static void insert_and_send_create ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , uint32_t posToInsertAt , const NetObjTemporaryPtr < T > & newObj ) {
l - > insert ( l , nullptr , posToInsertAt , newObj ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
static void erase ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , uint32_t indexToErase ) {
2025-12-10 10:24:57 +03:00
return l - > erase_by_index ( l , indexToErase ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
static uint32_t erase ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const NetObjTemporaryPtr < T > & p ) {
2025-12-10 10:24:57 +03:00
return l - > erase_by_ptr ( l , p ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
virtual bool contains ( const NetObjTemporaryPtr < T > & p ) const = 0 ;
2025-12-07 17:35:27 +03:00
virtual uint32_t size ( ) const = 0 ;
2025-12-11 16:05:41 +03:00
virtual const NetObjOwnerPtr < T > & at ( uint32_t index ) const = 0 ;
2025-12-09 19:29:58 +03:00
virtual bool empty ( ) const = 0 ;
2025-12-08 20:51:11 +03:00
virtual ~ NetObjOrderedList ( ) { }
2025-12-07 17:35:27 +03:00
protected :
2025-12-11 16:05:41 +03:00
virtual void insert ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & clientInserting , uint32_t posToInsertAt , NetObjOwnerPtr < T > newObj ) = 0 ;
virtual void erase_by_index ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , uint32_t indexToErase ) = 0 ;
virtual uint32_t erase_by_ptr ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const NetObjTemporaryPtr < T > & p ) = 0 ;
virtual void write_constructor ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryOutputArchive & a ) = 0 ;
virtual void read_update ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & ) = 0 ;
2025-12-11 22:41:53 +03:00
virtual void read_constructor ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & ) = 0 ;
2025-12-07 17:35:27 +03:00
private :
template < typename S > friend void register_ordered_list_class ( NetObjManagerTypeList & t ) ;
2025-12-11 16:05:41 +03:00
static void write_constructor_func ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryOutputArchive & a ) {
2025-12-07 17:35:27 +03:00
l - > write_constructor ( l , a ) ;
}
2025-12-11 16:05:41 +03:00
static void read_constructor_func ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & c ) {
2025-12-08 22:21:07 +03:00
l - > read_constructor ( l , a , c ) ;
}
2025-12-11 16:05:41 +03:00
static void read_update_func ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & c ) {
2025-12-07 17:35:27 +03:00
l - > read_update ( l , a , c ) ;
}
} ;
template < typename T > class NetObjOrderedListServer : public NetObjOrderedList < T > {
public :
2025-12-08 20:51:11 +03:00
NetObjOrderedListServer ( ) { }
2025-12-11 16:05:41 +03:00
virtual bool contains ( const NetObjTemporaryPtr < T > & p ) const override {
2025-12-10 13:06:45 +03:00
return idToDataMap . contains ( p . get_net_id ( ) ) ;
}
2025-12-07 17:35:27 +03:00
virtual uint32_t size ( ) const override {
return data . size ( ) ;
}
2025-12-11 16:05:41 +03:00
virtual const NetObjOwnerPtr < T > & at ( uint32_t index ) const override {
2025-12-09 19:29:58 +03:00
return data [ index ] - > obj ;
}
virtual bool empty ( ) const override {
return data . empty ( ) ;
}
2025-12-07 17:35:27 +03:00
protected :
2025-12-11 16:05:41 +03:00
virtual void insert ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & clientInserting , uint32_t posToInsertAt , NetObjOwnerPtr < T > newObj ) override {
posToInsertAt = std : : min < uint32_t > ( posToInsertAt , data . size ( ) ) ;
auto newObjInfoPtr = std : : make_shared < NetObjOrderedListObjectInfo < T > > ( std : : move ( newObj ) , 0 ) ;
data . insert ( data . begin ( ) + posToInsertAt , newObjInfoPtr ) ;
idToDataMap . emplace ( newObjInfoPtr - > obj . get_net_id ( ) , newObjInfoPtr ) ;
l . send_server_update_to_all_clients_except ( clientInserting , RELIABLE_COMMAND_CHANNEL , [ & newObjInfoPtr , posToInsertAt ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
a ( ObjPtrOrderedListCommand_StoC : : INSERT_SINGLE_CONSTRUCT , posToInsertAt ) ;
2025-12-07 17:35:27 +03:00
newObjInfoPtr - > obj . write_create_message ( a ) ;
} ) ;
2025-12-11 16:05:41 +03:00
l . send_server_update_to_client ( clientInserting , RELIABLE_COMMAND_CHANNEL , [ & newObjInfoPtr , posToInsertAt ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
a ( ObjPtrOrderedListCommand_StoC : : INSERT_SINGLE_REFERENCE , posToInsertAt , newObjInfoPtr - > obj . get_net_id ( ) ) ;
} ) ;
set_positions_for_object_info_vector < T > ( data , posToInsertAt ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
virtual void erase_by_index ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , uint32_t indexToErase ) override {
2025-12-09 13:00:38 +03:00
if ( data . empty ( ) )
2025-12-11 16:05:41 +03:00
return ;
2025-12-09 13:00:38 +03:00
indexToErase = std : : min < uint32_t > ( indexToErase , data . size ( ) - 1 ) ;
2025-12-11 16:05:41 +03:00
l . send_server_update_to_all_clients ( RELIABLE_COMMAND_CHANNEL , [ indexToErase ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
2025-12-07 17:35:27 +03:00
a ( ObjPtrOrderedListCommand_StoC : : ERASE_SINGLE , indexToErase ) ;
} ) ;
2025-12-09 13:00:38 +03:00
NetObjID idToErase = data [ indexToErase ] - > obj . get_net_id ( ) ;
2025-12-07 17:35:27 +03:00
data . erase ( data . begin ( ) + indexToErase ) ;
2025-12-09 13:00:38 +03:00
idToDataMap . erase ( idToErase ) ;
2025-12-07 17:35:27 +03:00
set_positions_for_object_info_vector < T > ( data , indexToErase ) ;
2025-12-10 10:24:57 +03:00
}
2025-12-11 16:05:41 +03:00
virtual uint32_t erase_by_ptr ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const NetObjTemporaryPtr < T > & p ) override {
2025-12-10 10:24:57 +03:00
if ( data . empty ( ) )
return std : : numeric_limits < uint32_t > : : max ( ) ;
auto it = idToDataMap . find ( p . get_net_id ( ) ) ;
if ( it = = idToDataMap . end ( ) )
return std : : numeric_limits < uint32_t > : : max ( ) ;
uint32_t indexToErase = it - > second - > pos ;
data . erase ( data . begin ( ) + indexToErase ) ;
idToDataMap . erase ( it ) ;
2025-12-11 16:05:41 +03:00
l . send_server_update_to_all_clients ( RELIABLE_COMMAND_CHANNEL , [ indexToErase ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
2025-12-10 10:24:57 +03:00
a ( ObjPtrOrderedListCommand_StoC : : ERASE_SINGLE , indexToErase ) ;
} ) ;
set_positions_for_object_info_vector < T > ( data , indexToErase ) ;
return indexToErase ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
virtual void write_constructor ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryOutputArchive & a ) override {
2025-12-08 14:28:01 +03:00
a ( static_cast < uint32_t > ( data . size ( ) ) ) ;
for ( size_t i = 0 ; i < data . size ( ) ; i + + )
data [ i ] - > obj . write_create_message ( a ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 22:41:53 +03:00
virtual void read_constructor ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & c ) override {
2025-12-08 14:28:01 +03:00
uint32_t constructedSize ;
a ( constructedSize ) ;
data . clear ( ) ;
2025-12-10 13:06:45 +03:00
idToDataMap . clear ( ) ;
for ( uint32_t i = 0 ; i < constructedSize ; i + + ) {
2025-12-11 22:41:53 +03:00
data . emplace_back ( std : : make_shared < NetObjOrderedListObjectInfo < T > > ( l . get_obj_man ( ) - > template read_create_message < T > ( a , c ) , static_cast < uint32_t > ( data . size ( ) ) ) ) ;
2025-12-10 13:06:45 +03:00
idToDataMap . emplace ( data . back ( ) - > obj . get_net_id ( ) , data . back ( ) ) ;
}
2025-12-08 14:28:01 +03:00
// Dont send the object data to all clients in the constructor, as the function that called read_create_message is also the one that will decide where to send the data of the constructed object
// Example: the INSERT_SINGLE command in read_update, if it was inserting another NetObjOrderedList, would first construct the list using read_create_message, then it will call insert() to send it to clients
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
virtual void read_update ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & c ) override {
2025-12-07 17:35:27 +03:00
ObjPtrOrderedListCommand_CtoS command ;
a ( command ) ;
switch ( command ) {
case ObjPtrOrderedListCommand_CtoS : : INSERT_SINGLE :
uint32_t newPos ;
a ( newPos ) ;
2025-12-11 16:05:41 +03:00
insert ( l , c , newPos , l . get_obj_man ( ) - > template read_create_message < T > ( a , c ) ) ;
2025-12-07 17:35:27 +03:00
break ;
case ObjPtrOrderedListCommand_CtoS : : ERASE_SINGLE :
NetObjID idToErase ;
a ( idToErase ) ;
2025-12-09 13:00:38 +03:00
auto it = idToDataMap . find ( idToErase ) ;
if ( it ! = idToDataMap . end ( ) )
erase_by_index ( l , it - > second - > pos ) ;
2025-12-07 17:35:27 +03:00
break ;
}
}
private :
std : : vector < NetObjOrderedListObjectInfoPtr < T > > data ;
2025-12-09 13:00:38 +03:00
std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > idToDataMap ;
2025-12-07 17:35:27 +03:00
} ;
template < typename T > class NetObjOrderedListClient : public NetObjOrderedList < T > {
public :
2025-12-08 20:51:11 +03:00
NetObjOrderedListClient ( ) { }
2025-12-11 16:05:41 +03:00
virtual bool contains ( const NetObjTemporaryPtr < T > & p ) const override {
2025-12-10 13:06:45 +03:00
return clientIdToDataMap . contains ( p . get_net_id ( ) ) ;
}
2025-12-07 17:35:27 +03:00
virtual uint32_t size ( ) const override {
return clientData . size ( ) ;
}
2025-12-11 16:05:41 +03:00
virtual const NetObjOwnerPtr < T > & at ( uint32_t index ) const override {
2025-12-09 19:29:58 +03:00
return clientData [ index ] - > obj ;
}
virtual bool empty ( ) const override {
return clientData . empty ( ) ;
}
2025-12-07 17:35:27 +03:00
protected :
2025-12-11 16:05:41 +03:00
virtual void insert ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & , uint32_t posToInsertAt , NetObjOwnerPtr < T > newObj ) {
posToInsertAt = std : : min < uint32_t > ( posToInsertAt , clientData . size ( ) ) ;
auto newObjInfoPtr = std : : make_shared < NetObjOrderedListObjectInfo < T > > ( std : : move ( newObj ) , 0 ) ;
clientData . insert ( clientData . begin ( ) + posToInsertAt , newObjInfoPtr ) ;
clientIdToDataMap . emplace ( newObjInfoPtr - > obj . get_net_id ( ) , newObjInfoPtr ) ;
clientJustInsertedSyncIgnore . emplace ( newObjInfoPtr - > obj . get_net_id ( ) , newObjInfoPtr ) ;
l . send_client_update ( RELIABLE_COMMAND_CHANNEL , [ & newObjInfoPtr , posToInsertAt ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
2025-12-09 13:00:38 +03:00
a ( ObjPtrOrderedListCommand_CtoS : : INSERT_SINGLE , posToInsertAt ) ; // Don't put actual pos to insert at, since the server will check for duplicates and might shift the index on its own
2025-12-08 14:28:01 +03:00
newObjInfoPtr - > obj . write_create_message ( a ) ;
} ) ;
2025-12-11 16:05:41 +03:00
set_positions_for_object_info_vector < T > ( clientData , posToInsertAt ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
virtual void erase_by_index ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , uint32_t indexToErase ) override {
2025-12-09 13:00:38 +03:00
if ( clientData . empty ( ) )
2025-12-11 16:05:41 +03:00
return ;
2025-12-09 13:00:38 +03:00
indexToErase = std : : min < uint32_t > ( indexToErase , clientData . size ( ) - 1 ) ;
2025-12-10 10:24:57 +03:00
auto p = clientData [ indexToErase ] ;
2025-12-11 16:05:41 +03:00
l . send_client_update ( RELIABLE_COMMAND_CHANNEL , [ & p ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
2025-12-07 23:09:17 +03:00
a ( ObjPtrOrderedListCommand_CtoS : : ERASE_SINGLE , p - > obj . get_net_id ( ) ) ;
} ) ;
uint32_t iToErase = p - > pos ;
2025-12-09 13:00:38 +03:00
clientIdToDataMap . erase ( p - > obj . get_net_id ( ) ) ;
2025-12-07 23:09:17 +03:00
clientData . erase ( clientData . begin ( ) + iToErase ) ;
set_positions_for_object_info_vector < T > ( clientData , iToErase ) ;
2025-12-10 10:24:57 +03:00
}
2025-12-11 16:05:41 +03:00
virtual uint32_t erase_by_ptr ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const NetObjTemporaryPtr < T > & p ) override {
2025-12-10 10:24:57 +03:00
if ( clientData . empty ( ) )
return std : : numeric_limits < uint32_t > : : max ( ) ;
2025-12-11 16:05:41 +03:00
l . send_client_update ( RELIABLE_COMMAND_CHANNEL , [ & p ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
2025-12-10 10:24:57 +03:00
a ( ObjPtrOrderedListCommand_CtoS : : ERASE_SINGLE , p . get_net_id ( ) ) ;
} ) ;
2025-12-11 16:05:41 +03:00
auto it = clientIdToDataMap . find ( p . get_net_id ( ) ) ;
2025-12-10 10:24:57 +03:00
uint32_t iToErase = it - > second - > pos ;
auto toRet = clientData [ iToErase ] ;
clientIdToDataMap . erase ( it ) ;
clientData . erase ( clientData . begin ( ) + iToErase ) ;
set_positions_for_object_info_vector < T > ( clientData , iToErase ) ;
return iToErase ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
virtual void write_constructor ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryOutputArchive & a ) override {
2025-12-08 14:28:01 +03:00
a ( static_cast < uint32_t > ( clientData . size ( ) ) ) ;
for ( size_t i = 0 ; i < clientData . size ( ) ; i + + )
clientData [ i ] - > obj . write_create_message ( a ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-11 22:41:53 +03:00
virtual void read_constructor ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & ) override {
2025-12-08 14:28:01 +03:00
uint32_t constructedSize ;
a ( constructedSize ) ;
clientData . clear ( ) ;
serverData . clear ( ) ;
2025-12-10 13:06:45 +03:00
clientIdToDataMap . clear ( ) ;
for ( uint32_t i = 0 ; i < constructedSize ; i + + ) {
2025-12-11 22:41:53 +03:00
clientData . emplace_back ( std : : make_shared < NetObjOrderedListObjectInfo < T > > ( l . get_obj_man ( ) - > template read_create_message < T > ( a , nullptr ) , static_cast < uint32_t > ( serverData . size ( ) ) ) ) ;
clientIdToDataMap . emplace ( clientData . back ( ) - > obj . get_net_id ( ) , clientData . back ( ) ) ;
2025-12-11 16:05:41 +03:00
serverData . emplace_back ( clientData . back ( ) - > obj . get_net_id ( ) ) ;
2025-12-10 13:06:45 +03:00
}
2025-12-07 17:35:27 +03:00
}
2025-12-11 16:05:41 +03:00
virtual void read_update ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , cereal : : PortableBinaryInputArchive & a , const std : : shared_ptr < NetServer : : ClientData > & ) override {
2025-12-07 17:35:27 +03:00
ObjPtrOrderedListCommand_StoC c ;
a ( c ) ;
switch ( c ) {
2025-12-11 16:05:41 +03:00
case ObjPtrOrderedListCommand_StoC : : INSERT_SINGLE_REFERENCE : {
NetObjID newObjID ;
uint32_t newServerPos ;
a ( newServerPos , newObjID ) ;
serverData . insert ( serverData . begin ( ) + newServerPos , newObjID ) ;
clientJustInsertedSyncIgnore . erase ( newObjID ) ;
2025-12-11 22:41:53 +03:00
sync ( std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > ( ) ) ;
2025-12-11 16:05:41 +03:00
break ;
}
case ObjPtrOrderedListCommand_StoC : : INSERT_SINGLE_CONSTRUCT : {
2025-12-09 17:20:27 +03:00
uint32_t newServerPos ;
a ( newServerPos ) ;
2025-12-11 16:05:41 +03:00
auto objInfoToInsert = std : : make_shared < NetObjOrderedListObjectInfo < T > > ( l . get_obj_man ( ) - > template read_create_message < T > ( a , nullptr ) , 0 ) ;
serverData . insert ( serverData . begin ( ) + newServerPos , objInfoToInsert - > obj . get_net_id ( ) ) ;
clientJustInsertedSyncIgnore . erase ( objInfoToInsert - > obj . get_net_id ( ) ) ;
2025-12-11 22:41:53 +03:00
std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > serverNewObjects ;
serverNewObjects . emplace ( objInfoToInsert - > obj . get_net_id ( ) , objInfoToInsert ) ;
sync ( serverNewObjects ) ;
2025-12-07 17:35:27 +03:00
break ;
2025-12-09 13:00:38 +03:00
}
case ObjPtrOrderedListCommand_StoC : : ERASE_SINGLE : {
2025-12-09 17:20:27 +03:00
uint32_t serverPosToErase ;
a ( serverPosToErase ) ;
2025-12-11 16:05:41 +03:00
NetObjID objID = serverData [ serverPosToErase ] ;
2025-12-09 17:20:27 +03:00
serverData . erase ( serverData . begin ( ) + serverPosToErase ) ;
2025-12-11 16:05:41 +03:00
auto it = clientIdToDataMap . find ( objID ) ;
if ( it ! = clientIdToDataMap . end ( ) ) {
uint32_t clientPosToErase = it - > second - > pos ;
clientIdToDataMap . erase ( it ) ;
clientJustInsertedSyncIgnore . erase ( objID ) ;
clientData . erase ( clientData . begin ( ) + clientPosToErase ) ;
set_positions_for_object_info_vector < T > ( clientData , clientPosToErase ) ;
}
2025-12-07 17:35:27 +03:00
break ;
2025-12-09 13:00:38 +03:00
}
2025-12-07 17:35:27 +03:00
}
}
private :
2025-12-11 16:05:41 +03:00
void sync ( const std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > & newServerObjects ) {
std : : map < uint32_t , NetObjOrderedListObjectInfoPtr < T > > ignoredToReinsert ;
for ( auto & [ netID , objInfoPtr ] : clientJustInsertedSyncIgnore )
ignoredToReinsert . emplace ( objInfoPtr - > pos , objInfoPtr ) ;
2025-12-09 13:00:38 +03:00
2025-12-11 16:05:41 +03:00
clientData . clear ( ) ;
for ( const NetObjID & id : serverData ) {
auto itFoundInClient = clientIdToDataMap . find ( id ) ;
if ( itFoundInClient ! = clientIdToDataMap . end ( ) )
clientData . emplace_back ( itFoundInClient - > second ) ;
else {
auto itFoundInServer = newServerObjects . find ( id ) ;
if ( itFoundInServer ! = newServerObjects . end ( ) ) {
clientData . emplace_back ( itFoundInServer - > second ) ;
clientIdToDataMap . emplace ( itFoundInServer - > first , itFoundInServer - > second ) ;
}
2025-12-09 13:00:38 +03:00
}
2025-12-11 16:05:41 +03:00
}
for ( auto & [ pos , objInfoPtr ] : ignoredToReinsert ) {
if ( pos > clientData . size ( ) )
clientData . emplace_back ( objInfoPtr ) ;
2025-12-09 13:00:38 +03:00
else
2025-12-11 16:05:41 +03:00
clientData . insert ( clientData . begin ( ) + pos , objInfoPtr ) ;
2025-12-09 13:00:38 +03:00
}
2025-12-11 16:05:41 +03:00
2025-12-09 13:00:38 +03:00
set_positions_for_object_info_vector < T > ( clientData ) ;
}
2025-12-11 16:05:41 +03:00
std : : vector < NetObjID > serverData ;
2025-12-07 17:35:27 +03:00
std : : vector < NetObjOrderedListObjectInfoPtr < T > > clientData ;
2025-12-09 13:00:38 +03:00
std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > clientIdToDataMap ;
2025-12-11 16:05:41 +03:00
std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > clientJustInsertedSyncIgnore ;
2025-12-07 17:35:27 +03:00
} ;
template < typename S > void register_ordered_list_class ( NetObjManagerTypeList & t ) {
2025-12-08 20:51:11 +03:00
t . register_class < NetObjOrderedList < S > , NetObjOrderedList < S > , NetObjOrderedListClient < S > , NetObjOrderedListServer < S > > ( {
2025-12-07 17:35:27 +03:00
. writeConstructorFuncClient = NetObjOrderedList < S > : : write_constructor_func ,
. readConstructorFuncClient = NetObjOrderedList < S > : : read_constructor_func ,
. readUpdateFuncClient = NetObjOrderedList < S > : : read_update_func ,
. writeConstructorFuncServer = NetObjOrderedList < S > : : write_constructor_func ,
. readConstructorFuncServer = NetObjOrderedList < S > : : read_constructor_func ,
. readUpdateFuncServer = NetObjOrderedList < S > : : read_update_func ,
} ) ;
}
}