Created
March 1, 2018 15:31
-
-
Save NotAdam/2119162b1188d9d8294a90cacc7373a7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef SAPPHIRE_SPAWNINDEXALLOCATOR_H | |
| #define SAPPHIRE_SPAWNINDEXALLOCATOR_H | |
| #include <queue> | |
| #include <unordered_map> | |
| #include <type_traits> | |
| namespace Core | |
| { | |
| namespace Util | |
| { | |
| template< typename T, typename ActorIdType = uint32_t > | |
| class SpawnIndexAllocator | |
| { | |
| public: | |
| static_assert( std::is_same< T, uint8_t >::value || std::is_same< T, uint16_t >::value || | |
| std::is_same< T, uint32_t >::value || std::is_same< T, uint64_t >::value, | |
| "T must be uint8_t, uint16_t, uint32_t, uint64_t" ); | |
| SpawnIndexAllocator() = default; | |
| void init( T maxSlotId, bool reserveFirstSlot = false ) | |
| { | |
| setupQueue(); | |
| m_maxSlotId = maxSlotId; | |
| m_reserveFirstSlot = reserveFirstSlot; | |
| // todo: reserve max slot id in map to prevent any runtime reshashing | |
| } | |
| T freeUsedSpawnIndex( ActorIdType actorId ) | |
| { | |
| assert( m_maxSlotId != 0 ); | |
| auto it = m_actorIdToAllocatedMap.find( actorId ); | |
| if( it == m_actorIdToAllocatedMap.end() ) | |
| return 0; | |
| auto index = it->second; | |
| m_availableIds.push( index ); | |
| m_actorIdToAllocatedMap.erase( it ); | |
| return index; | |
| } | |
| T getNextFreeSpawnIndex( ActorIdType actorId ) | |
| { | |
| assert( m_maxSlotId != 0 ); | |
| if( m_availableIds.empty() ) | |
| return getAllocFailId(); | |
| auto nextId = m_availableIds.front(); | |
| m_availableIds.pop(); | |
| m_actorIdToAllocatedMap[actorId] = nextId; | |
| return nextId; | |
| } | |
| void freeAllSpawnIndexes() | |
| { | |
| setupQueue(); | |
| m_actorIdToAllocatedMap.clear(); | |
| } | |
| bool isSpawnIndexValid( T spawnIndex ) | |
| { | |
| return spawnIndex != getAllocFailId(); | |
| } | |
| constexpr T getAllocFailId() | |
| { | |
| return static_cast< T >( -1 ); | |
| } | |
| protected: | |
| void setupQueue() | |
| { | |
| while( !m_availableIds.empty() ) | |
| m_availableIds.pop(); | |
| uint32_t start = 0; | |
| // slot 0 is reserved when used for spawning actors/players otherwise the local player actor spawnIndex | |
| // will be used by another actor and despawn the local player | |
| if( m_reserveFirstSlot ) | |
| start = 1; | |
| for( uint32_t i = start; i < m_maxSlotId; i++ ) | |
| m_availableIds.push( i ); | |
| } | |
| std::queue< T > m_availableIds; | |
| std::unordered_map< ActorIdType, T > m_actorIdToAllocatedMap; | |
| T m_maxSlotId = 0; | |
| bool m_reserveFirstSlot = false; | |
| }; | |
| } | |
| } | |
| #endif //SAPPHIRE_SPAWNINDEXALLOCATOR_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment