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-13 17:56:07 +03:00
# include "NetObjWeakPtr.hpp"
2025-12-08 14:28:01 +03:00
# include "NetObjID.hpp"
2025-12-13 17:56:07 +03:00
# include <cereal/archives/portable_binary.hpp>
# include <cereal/types/unordered_set.hpp>
# include <cereal/types/vector.hpp>
2025-12-07 17:35:27 +03:00
# include "NetObjManagerTypeList.hpp"
2025-12-13 17:56:07 +03:00
# include <limits>
2025-12-07 17:35:27 +03:00
namespace NetworkingObjects {
enum class ObjPtrOrderedListCommand_StoC : uint8_t {
2025-12-11 16:05:41 +03:00
INSERT_SINGLE_CONSTRUCT ,
INSERT_SINGLE_REFERENCE ,
2025-12-13 17:56:07 +03:00
INSERT_MANY_CONSTRUCT ,
INSERT_MANY_REFERENCE ,
ERASE_SINGLE ,
ERASE_MANY
2025-12-07 17:35:27 +03:00
} ;
enum class ObjPtrOrderedListCommand_CtoS : uint8_t {
INSERT_SINGLE ,
2025-12-13 17:56:07 +03:00
INSERT_MANY ,
ERASE_SINGLE ,
ERASE_MANY
2025-12-07 17:35:27 +03:00
} ;
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-13 21:41:32 +03:00
template < typename . . . Args > NetObjOrderedListObjectInfoPtr < T > emplace_back_direct ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , Args & & . . . items ) {
2025-12-11 16:05:41 +03:00
NetObjOwnerPtr < T > newObj = l . get_obj_man ( ) - > template make_obj_direct < T > ( items . . . ) ;
2025-12-13 13:03:27 +03:00
return l - > insert ( l , nullptr , l - > size ( ) , std : : move ( newObj ) ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-13 21:41:32 +03:00
static NetObjOrderedListObjectInfoPtr < T > push_back_and_send_create ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , T * newObj ) {
2025-12-15 15:36:42 +03:00
NetObjOwnerPtr < T > newObjOwner = l . get_obj_man ( ) - > template make_obj_from_ptr < T > ( newObj ) ;
2025-12-13 13:03:27 +03:00
return l - > insert ( l , nullptr , l - > size ( ) , std : : move ( newObjOwner ) ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-13 21:41:32 +03:00
static NetObjOrderedListObjectInfoPtr < T > insert_and_send_create ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , uint32_t posToInsertAt , T * newObj ) {
2025-12-15 15:36:42 +03:00
NetObjOwnerPtr < T > newObjOwner = l . get_obj_man ( ) - > template make_obj_from_ptr < T > ( newObj ) ;
2025-12-13 13:03:27 +03:00
return l - > insert ( l , nullptr , posToInsertAt , std : : move ( newObjOwner ) ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-13 21:41:32 +03:00
static std : : vector < NetObjOrderedListObjectInfoPtr < T > > insert_ordered_list_and_send_create ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : vector < std : : pair < uint32_t , T * > > & newObjs ) {
2025-12-13 17:56:07 +03:00
if ( newObjs . empty ( ) )
return { } ;
std : : vector < std : : pair < uint32_t , NetObjOwnerPtr < T > > > ownerPtrOrderedList ;
for ( uint32_t i = 0 ; i < static_cast < uint32_t > ( newObjs . size ( ) ) ; i + + )
2025-12-15 15:36:42 +03:00
ownerPtrOrderedList . emplace_back ( newObjs [ i ] . first , std : : move ( l . get_obj_man ( ) - > template make_obj_from_ptr < T > ( newObjs [ i ] . second ) ) ) ;
2025-12-13 17:56:07 +03:00
return l - > insert_ordered_list ( l , nullptr , ownerPtrOrderedList ) ;
}
static void erase_unordered_set ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : unordered_set < NetObjID > & ids ) {
l - > erase_by_unordered_set_ids ( l , ids ) ;
}
2025-12-11 16:05:41 +03:00
static void erase ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , uint32_t indexToErase ) {
2025-12-13 13:03:27 +03:00
l - > erase_by_index ( l , indexToErase ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-13 17:56:07 +03:00
static uint32_t erase ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const NetObjID & id ) {
return l - > erase_by_id ( l , id ) ;
2025-12-07 17:35:27 +03:00
}
2025-12-13 21:41:32 +03:00
typedef std : : function < void ( const NetObjOrderedListObjectInfoPtr < T > & objInfo ) > InsertCallback ;
typedef std : : function < void ( const NetObjOrderedListObjectInfoPtr < T > & objInfo ) > EraseCallback ;
typedef std : : function < void ( const NetObjOrderedListObjectInfoPtr < T > & objInfo , uint32_t oldPos ) > MoveCallback ;
2025-12-13 21:43:30 +03:00
typedef std : : function < void ( ) > PostSyncCallback ;
2025-12-13 21:41:32 +03:00
void set_insert_callback ( const InsertCallback & func ) {
insertCallback = func ;
}
void set_erase_callback ( const EraseCallback & func ) {
eraseCallback = func ;
}
void set_move_callback ( const MoveCallback & func ) {
moveCallback = func ;
}
2025-12-13 21:43:30 +03:00
void set_post_sync_callback ( const PostSyncCallback & func ) {
postSyncCallback = func ;
}
2025-12-13 21:41:32 +03:00
2025-12-13 17:56:07 +03:00
virtual bool contains ( const NetObjID & p ) const = 0 ;
2025-12-14 18:57:40 +03:00
virtual const std : : vector < NetObjOrderedListObjectInfoPtr < T > > & get_data ( ) const = 0 ;
2025-12-07 17:35:27 +03:00
virtual uint32_t size ( ) const = 0 ;
2025-12-13 13:03:27 +03:00
virtual const NetObjOrderedListObjectInfoPtr < T > & at ( uint32_t index ) const = 0 ;
2025-12-21 17:40:58 +03:00
virtual NetObjOrderedListObjectInfoPtr < T > get ( const NetObjID & id ) 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-13 21:41:32 +03:00
virtual NetObjOrderedListObjectInfoPtr < T > insert ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & clientInserting , uint32_t posToInsertAt , NetObjOwnerPtr < T > newObj ) = 0 ;
virtual std : : vector < NetObjOrderedListObjectInfoPtr < T > > insert_ordered_list ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & clientInserting , std : : vector < std : : pair < uint32_t , NetObjOwnerPtr < T > > > & newObj ) = 0 ;
2025-12-11 16:05:41 +03:00
virtual void erase_by_index ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , uint32_t indexToErase ) = 0 ;
2025-12-13 17:56:07 +03:00
virtual uint32_t erase_by_id ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const NetObjID & id ) = 0 ;
virtual void erase_by_unordered_set_ids ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , std : : unordered_set < NetObjID > ids ) = 0 ;
2025-12-11 16:05:41 +03:00
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-13 21:41:32 +03:00
// Call after inserting
void call_insert_callback ( const NetObjOrderedListObjectInfoPtr < T > & objInfo ) {
if ( insertCallback )
insertCallback ( objInfo ) ;
}
void call_insert_callback_list ( const std : : vector < NetObjOrderedListObjectInfoPtr < T > > & objInfos ) {
if ( insertCallback ) {
for ( auto objInfo : objInfos )
insertCallback ( objInfo ) ;
}
}
// Call before erasing
void call_erase_callback ( const NetObjOrderedListObjectInfoPtr < T > & objInfo ) {
if ( eraseCallback )
eraseCallback ( objInfo ) ;
}
void call_move_callback ( const NetObjOrderedListObjectInfoPtr < T > & objInfo , uint32_t oldPos ) {
if ( moveCallback )
moveCallback ( objInfo , oldPos ) ;
}
void call_post_sync_callback ( ) {
2025-12-13 21:43:30 +03:00
if ( postSyncCallback )
postSyncCallback ( ) ;
2025-12-13 21:41:32 +03:00
}
2025-12-07 17:35:27 +03:00
private :
2025-12-13 21:41:32 +03:00
InsertCallback insertCallback ;
EraseCallback eraseCallback ;
MoveCallback moveCallback ;
2025-12-13 21:43:30 +03:00
PostSyncCallback postSyncCallback ;
2025-12-13 13:03:27 +03:00
template < typename S > friend void register_ordered_list_class ( NetObjManager & 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-13 17:56:07 +03:00
virtual bool contains ( const NetObjID & id ) const override {
return idToDataMap . contains ( id ) ;
2025-12-10 13:06:45 +03:00
}
2025-12-14 18:57:40 +03:00
virtual const std : : vector < NetObjOrderedListObjectInfoPtr < T > > & get_data ( ) const override {
return data ;
}
2025-12-07 17:35:27 +03:00
virtual uint32_t size ( ) const override {
return data . size ( ) ;
}
2025-12-13 13:03:27 +03:00
virtual const NetObjOrderedListObjectInfoPtr < T > & at ( uint32_t index ) const override {
return data [ index ] ;
2025-12-09 19:29:58 +03:00
}
2025-12-21 17:40:58 +03:00
virtual NetObjOrderedListObjectInfoPtr < T > get ( const NetObjID & id ) const override {
auto it = idToDataMap . find ( id ) ;
if ( it = = idToDataMap . end ( ) )
return nullptr ;
return it - > second ;
}
2025-12-09 19:29:58 +03:00
virtual bool empty ( ) const override {
return data . empty ( ) ;
}
2025-12-07 17:35:27 +03:00
protected :
2025-12-13 21:41:32 +03:00
virtual NetObjOrderedListObjectInfoPtr < T > insert ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & clientInserting , uint32_t posToInsertAt , NetObjOwnerPtr < T > newObj ) override {
2025-12-11 16:05:41 +03:00
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-13 21:41:32 +03:00
this - > call_insert_callback ( data [ posToInsertAt ] ) ;
2025-12-13 13:03:27 +03:00
return data [ posToInsertAt ] ;
2025-12-07 17:35:27 +03:00
}
2025-12-13 21:41:32 +03:00
virtual std : : vector < NetObjOrderedListObjectInfoPtr < T > > insert_ordered_list ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & clientInserting , std : : vector < std : : pair < uint32_t , NetObjOwnerPtr < T > > > & newObjs ) override {
std : : vector < NetObjOrderedListObjectInfoPtr < T > > toRet ;
2025-12-13 17:56:07 +03:00
for ( auto & [ pos , newObj ] : newObjs ) {
uint32_t posToInsertAt = std : : min < uint32_t > ( pos , 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 ) ;
2025-12-13 21:41:32 +03:00
toRet . emplace_back ( data [ posToInsertAt ] ) ;
2025-12-13 17:56:07 +03:00
}
l . send_server_update_to_all_clients_except ( clientInserting , RELIABLE_COMMAND_CHANNEL , [ & toRet ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
a ( ObjPtrOrderedListCommand_StoC : : INSERT_MANY_CONSTRUCT , static_cast < uint32_t > ( toRet . size ( ) ) ) ;
2025-12-13 21:41:32 +03:00
for ( const NetObjOrderedListObjectInfoPtr < T > & objInfo : toRet ) {
a ( objInfo - > pos ) ;
objInfo - > obj . write_create_message ( a ) ;
2025-12-13 17:56:07 +03:00
}
} ) ;
l . send_server_update_to_client ( clientInserting , RELIABLE_COMMAND_CHANNEL , [ & toRet ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
a ( ObjPtrOrderedListCommand_StoC : : INSERT_MANY_REFERENCE , static_cast < uint32_t > ( toRet . size ( ) ) ) ;
2025-12-13 21:41:32 +03:00
for ( const NetObjOrderedListObjectInfoPtr < T > & objInfo : toRet )
a ( objInfo - > pos , objInfo - > obj . get_net_id ( ) ) ;
2025-12-13 17:56:07 +03:00
} ) ;
set_positions_for_object_info_vector < T > ( data , newObjs [ 0 ] . first ) ;
2025-12-13 21:41:32 +03:00
this - > call_insert_callback_list ( toRet ) ;
2025-12-13 17:56:07 +03:00
return toRet ;
}
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-13 21:41:32 +03:00
this - > call_erase_callback ( data [ indexToErase ] ) ;
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-13 17:56:07 +03:00
virtual uint32_t erase_by_id ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const NetObjID & id ) override {
2025-12-10 10:24:57 +03:00
if ( data . empty ( ) )
return std : : numeric_limits < uint32_t > : : max ( ) ;
2025-12-13 17:56:07 +03:00
auto it = idToDataMap . find ( id ) ;
2025-12-10 10:24:57 +03:00
if ( it = = idToDataMap . end ( ) )
return std : : numeric_limits < uint32_t > : : max ( ) ;
uint32_t indexToErase = it - > second - > pos ;
2025-12-13 21:41:32 +03:00
this - > call_erase_callback ( data [ indexToErase ] ) ;
2025-12-10 10:24:57 +03:00
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-13 17:56:07 +03:00
virtual void erase_by_unordered_set_ids ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , std : : unordered_set < NetObjID > ids ) {
std : : vector < uint32_t > indicesToErase ;
std : : erase_if ( ids , [ & ] ( const NetObjID & id ) {
auto it = idToDataMap . find ( id ) ;
if ( it = = idToDataMap . end ( ) )
return true ;
indicesToErase . emplace_back ( it - > second - > pos ) ;
idToDataMap . erase ( it ) ; // Erase here since we already have the iterator
return false ;
} ) ;
if ( ids . empty ( ) )
return ;
std : : sort ( indicesToErase . begin ( ) , indicesToErase . end ( ) ) ;
2025-12-13 21:41:32 +03:00
for ( uint32_t indexToErase : indicesToErase | std : : views : : reverse ) {
this - > call_erase_callback ( data [ indexToErase ] ) ;
2025-12-13 17:56:07 +03:00
data . erase ( data . begin ( ) + indexToErase ) ;
2025-12-13 21:41:32 +03:00
}
2025-12-13 17:56:07 +03:00
l . send_server_update_to_all_clients ( RELIABLE_COMMAND_CHANNEL , [ & indicesToErase ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
a ( ObjPtrOrderedListCommand_StoC : : ERASE_MANY , indicesToErase ) ;
} ) ;
set_positions_for_object_info_vector < T > ( data , indicesToErase . front ( ) ) ;
}
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 ) {
2025-12-13 17:56:07 +03:00
case ObjPtrOrderedListCommand_CtoS : : INSERT_SINGLE : {
2025-12-07 17:35:27 +03:00
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 ;
2025-12-13 17:56:07 +03:00
}
case ObjPtrOrderedListCommand_CtoS : : INSERT_MANY : {
std : : vector < std : : pair < uint32_t , NetObjOwnerPtr < T > > > newObjs ;
uint32_t newObjsSize ;
a ( newObjsSize ) ;
for ( uint32_t i = 0 ; i < newObjsSize ; i + + ) {
uint32_t pos ;
a ( pos ) ;
newObjs . emplace_back ( pos , l . get_obj_man ( ) - > template read_create_message < T > ( a , c ) ) ;
}
insert_ordered_list ( l , c , newObjs ) ;
break ;
}
case ObjPtrOrderedListCommand_CtoS : : ERASE_SINGLE : {
2025-12-07 17:35:27 +03:00
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 ;
2025-12-13 17:56:07 +03:00
}
case ObjPtrOrderedListCommand_CtoS : : ERASE_MANY : {
std : : unordered_set < NetObjID > idsToErase ;
a ( idsToErase ) ;
erase_by_unordered_set_ids ( l , idsToErase ) ;
break ;
}
2025-12-07 17:35:27 +03:00
}
}
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-13 17:56:07 +03:00
virtual bool contains ( const NetObjID & id ) const override {
return clientIdToDataMap . contains ( id ) ;
2025-12-10 13:06:45 +03:00
}
2025-12-14 18:57:40 +03:00
virtual const std : : vector < NetObjOrderedListObjectInfoPtr < T > > & get_data ( ) const override {
return clientData ;
}
2025-12-07 17:35:27 +03:00
virtual uint32_t size ( ) const override {
return clientData . size ( ) ;
}
2025-12-13 13:03:27 +03:00
virtual const NetObjOrderedListObjectInfoPtr < T > & at ( uint32_t index ) const override {
return clientData [ index ] ;
2025-12-09 19:29:58 +03:00
}
2025-12-21 17:40:58 +03:00
virtual NetObjOrderedListObjectInfoPtr < T > get ( const NetObjID & id ) const override {
auto it = clientIdToDataMap . find ( id ) ;
if ( it = = clientIdToDataMap . end ( ) )
return nullptr ;
return it - > second ;
}
2025-12-09 19:29:58 +03:00
virtual bool empty ( ) const override {
return clientData . empty ( ) ;
}
2025-12-07 17:35:27 +03:00
protected :
2025-12-13 21:41:32 +03:00
virtual NetObjOrderedListObjectInfoPtr < T > insert ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & , uint32_t posToInsertAt , NetObjOwnerPtr < T > newObj ) {
2025-12-11 16:05:41 +03:00
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-13 21:41:32 +03:00
this - > call_insert_callback ( clientData [ posToInsertAt ] ) ;
2025-12-13 13:03:27 +03:00
return clientData [ posToInsertAt ] ;
2025-12-07 17:35:27 +03:00
}
2025-12-13 21:41:32 +03:00
virtual std : : vector < NetObjOrderedListObjectInfoPtr < T > > insert_ordered_list ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const std : : shared_ptr < NetServer : : ClientData > & clientInserting , std : : vector < std : : pair < uint32_t , NetObjOwnerPtr < T > > > & newObjs ) override {
std : : vector < NetObjOrderedListObjectInfoPtr < T > > toRet ;
2025-12-13 17:56:07 +03:00
for ( auto & [ pos , newObj ] : newObjs ) {
uint32_t posToInsertAt = std : : min < uint32_t > ( pos , 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 ) ;
2025-12-13 21:41:32 +03:00
toRet . emplace_back ( clientData [ posToInsertAt ] ) ;
2025-12-13 17:56:07 +03:00
}
l . send_client_update ( RELIABLE_COMMAND_CHANNEL , [ & toRet ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
a ( ObjPtrOrderedListCommand_CtoS : : INSERT_MANY , static_cast < uint32_t > ( toRet . size ( ) ) ) ;
2025-12-13 21:41:32 +03:00
for ( const NetObjOrderedListObjectInfoPtr < T > & objInfo : toRet ) {
a ( objInfo - > pos ) ;
objInfo - > obj . write_create_message ( a ) ;
2025-12-13 17:56:07 +03:00
}
} ) ;
set_positions_for_object_info_vector < T > ( clientData , newObjs [ 0 ] . first ) ;
2025-12-13 21:41:32 +03:00
this - > call_insert_callback_list ( toRet ) ;
2025-12-13 17:56:07 +03:00
return toRet ;
}
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-13 21:41:32 +03:00
this - > call_erase_callback ( clientData [ indexToErase ] ) ;
2025-12-09 13:00:38 +03:00
clientIdToDataMap . erase ( p - > obj . get_net_id ( ) ) ;
2025-12-13 17:56:07 +03:00
clientJustInsertedSyncIgnore . 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-13 17:56:07 +03:00
virtual uint32_t erase_by_id ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , const NetObjID & id ) override {
2025-12-10 10:24:57 +03:00
if ( clientData . empty ( ) )
return std : : numeric_limits < uint32_t > : : max ( ) ;
2025-12-13 17:56:07 +03:00
auto it = clientIdToDataMap . find ( id ) ;
if ( it = = clientIdToDataMap . end ( ) )
return std : : numeric_limits < uint32_t > : : max ( ) ;
l . send_client_update ( RELIABLE_COMMAND_CHANNEL , [ & id ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
a ( ObjPtrOrderedListCommand_CtoS : : ERASE_SINGLE , id ) ;
2025-12-10 10:24:57 +03:00
} ) ;
uint32_t iToErase = it - > second - > pos ;
auto toRet = clientData [ iToErase ] ;
2025-12-13 21:41:32 +03:00
this - > call_erase_callback ( clientData [ iToErase ] ) ;
2025-12-10 10:24:57 +03:00
clientIdToDataMap . erase ( it ) ;
2025-12-13 17:56:07 +03:00
clientJustInsertedSyncIgnore . erase ( id ) ;
2025-12-10 10:24:57 +03:00
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-13 17:56:07 +03:00
virtual void erase_by_unordered_set_ids ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & l , std : : unordered_set < NetObjID > ids ) {
std : : vector < uint32_t > indicesToErase ;
std : : erase_if ( ids , [ & ] ( const NetObjID & id ) {
auto it = clientIdToDataMap . find ( id ) ;
if ( it = = clientIdToDataMap . end ( ) )
return true ;
indicesToErase . emplace_back ( it - > second - > pos ) ;
clientIdToDataMap . erase ( it ) ; // Erase here since we already have the iterator
clientJustInsertedSyncIgnore . erase ( id ) ;
return false ;
} ) ;
if ( ids . empty ( ) )
return ;
std : : sort ( indicesToErase . begin ( ) , indicesToErase . end ( ) ) ;
2025-12-13 21:41:32 +03:00
for ( uint32_t indexToErase : indicesToErase | std : : views : : reverse ) {
this - > call_erase_callback ( clientData [ indexToErase ] ) ;
2025-12-13 17:56:07 +03:00
clientData . erase ( clientData . begin ( ) + indexToErase ) ;
2025-12-13 21:41:32 +03:00
}
2025-12-15 18:14:12 +03:00
l . send_client_update ( RELIABLE_COMMAND_CHANNEL , [ & ids ] ( const NetObjTemporaryPtr < NetObjOrderedList < T > > & , cereal : : PortableBinaryOutputArchive & a ) {
2025-12-13 17:56:07 +03:00
a ( ObjPtrOrderedListCommand_CtoS : : ERASE_MANY , ids ) ;
} ) ;
set_positions_for_object_info_vector < T > ( clientData , indicesToErase . front ( ) ) ;
}
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-13 17:56:07 +03:00
case ObjPtrOrderedListCommand_StoC : : INSERT_SINGLE_CONSTRUCT : {
uint32_t newServerPos ;
a ( newServerPos ) ;
2025-12-13 21:41:32 +03:00
auto objInfoToInsert = std : : make_shared < NetObjOrderedListObjectInfo < T > > ( l . get_obj_man ( ) - > template read_create_message < T > ( a , nullptr ) , std : : numeric_limits < uint32_t > : : max ( ) ) ;
2025-12-13 17:56:07 +03:00
serverData . insert ( serverData . begin ( ) + newServerPos , objInfoToInsert - > obj . get_net_id ( ) ) ;
clientJustInsertedSyncIgnore . erase ( objInfoToInsert - > obj . get_net_id ( ) ) ;
std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > serverNewObjects ;
serverNewObjects . emplace ( objInfoToInsert - > obj . get_net_id ( ) , objInfoToInsert ) ;
sync ( serverNewObjects ) ;
break ;
}
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 ;
}
2025-12-13 17:56:07 +03:00
case ObjPtrOrderedListCommand_StoC : : INSERT_MANY_CONSTRUCT : {
2025-12-11 22:41:53 +03:00
std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > serverNewObjects ;
2025-12-13 17:56:07 +03:00
uint32_t newObjsSize ;
a ( newObjsSize ) ;
for ( uint32_t i = 0 ; i < newObjsSize ; i + + ) {
uint32_t newServerPos ;
a ( newServerPos ) ;
2025-12-13 21:41:32 +03:00
auto objInfoToInsert = std : : make_shared < NetObjOrderedListObjectInfo < T > > ( l . get_obj_man ( ) - > template read_create_message < T > ( a , nullptr ) , std : : numeric_limits < uint32_t > : : max ( ) ) ;
2025-12-13 17:56:07 +03:00
serverData . insert ( serverData . begin ( ) + newServerPos , objInfoToInsert - > obj . get_net_id ( ) ) ;
clientJustInsertedSyncIgnore . erase ( objInfoToInsert - > obj . get_net_id ( ) ) ;
serverNewObjects . emplace ( objInfoToInsert - > obj . get_net_id ( ) , objInfoToInsert ) ;
}
2025-12-11 22:41:53 +03:00
sync ( serverNewObjects ) ;
2025-12-07 17:35:27 +03:00
break ;
2025-12-09 13:00:38 +03:00
}
2025-12-13 17:56:07 +03:00
case ObjPtrOrderedListCommand_StoC : : INSERT_MANY_REFERENCE : {
uint32_t newObjsSize ;
a ( newObjsSize ) ;
for ( uint32_t i = 0 ; i < newObjsSize ; i + + ) {
NetObjID newObjID ;
uint32_t newServerPos ;
a ( newServerPos , newObjID ) ;
serverData . insert ( serverData . begin ( ) + newServerPos , newObjID ) ;
clientJustInsertedSyncIgnore . erase ( newObjID ) ;
}
sync ( std : : unordered_map < NetObjID , NetObjOrderedListObjectInfoPtr < T > > ( ) ) ;
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 ;
2025-12-13 21:41:32 +03:00
this - > call_erase_callback ( clientData [ clientPosToErase ] ) ;
2025-12-11 16:05:41 +03:00
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-13 17:56:07 +03:00
case ObjPtrOrderedListCommand_StoC : : ERASE_MANY : {
std : : vector < uint32_t > serverPositionsToErase ;
a ( serverPositionsToErase ) ;
std : : vector < uint32_t > clientIndicesToErase ;
for ( uint32_t serverPosToErase : serverPositionsToErase | std : : views : : reverse ) {
NetObjID objID = serverData [ serverPosToErase ] ;
serverData . erase ( serverData . begin ( ) + serverPosToErase ) ;
auto it = clientIdToDataMap . find ( objID ) ;
if ( it ! = clientIdToDataMap . end ( ) ) {
clientIdToDataMap . erase ( it ) ;
clientJustInsertedSyncIgnore . erase ( objID ) ;
clientIndicesToErase . emplace_back ( it - > second - > pos ) ;
}
}
std : : sort ( clientIndicesToErase . begin ( ) , clientIndicesToErase . end ( ) ) ;
if ( clientIndicesToErase . empty ( ) )
break ;
2025-12-13 21:41:32 +03:00
for ( uint32_t indexToErase : clientIndicesToErase | std : : views : : reverse ) {
this - > call_erase_callback ( clientData [ indexToErase ] ) ;
2025-12-13 17:56:07 +03:00
clientData . erase ( clientData . begin ( ) + indexToErase ) ;
2025-12-13 21:41:32 +03:00
}
2025-12-13 17:56:07 +03:00
set_positions_for_object_info_vector < T > ( clientData , clientIndicesToErase . front ( ) ) ;
break ;
}
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-13 21:41:32 +03:00
// Code that tries to not call post_sync_callback, which refreshes the entire cache.
//uint32_t bumpFromServerInsert = 0;
//for(uint32_t i = 0; i < clientData.size(); i++) {
// if(clientData[i]->pos == std::numeric_limits<uint32_t>::max()) {
// clientData[i]->pos = i;
// this->call_insert_callback(clientData[i]);
// bumpFromServerInsert++;
// }
// else if(clientData[i]->pos != (i + bumpFromServerInsert)) {
// uint32_t oldPos = clientData[i]->pos;
// clientData[i]->pos = i;
// this->call_move_callback(clientData[i], oldPos);
// }
// clientData[i]->pos = i;
//}
// Code that calls post_sync_callback
2025-12-15 16:49:51 +03:00
set_positions_for_object_info_vector < T > ( clientData ) ;
2025-12-13 21:41:32 +03:00
for ( auto & [ id , objInfo ] : newServerObjects )
this - > call_insert_callback ( objInfo ) ;
this - > call_post_sync_callback ( ) ;
2025-12-09 13:00:38 +03:00
}
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
} ;
2025-12-13 13:03:27 +03:00
template < typename S > void register_ordered_list_class ( NetObjManager & objMan ) {
objMan . 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 ,
} ) ;
}
}