/*----------------------------------------------------------------------------*/ /* Copyright (c) FIRST 2008-2017. All Rights Reserved. */ /* Open Source Software - may be modified and shared by FRC teams. The code */ /* must be accompanied by the FIRST BSD license file in the root directory of */ /* the project. */ /*----------------------------------------------------------------------------*/ #pragma once #include #include #include #include "HAL/Types.h" #include "HAL/cpp/priority_mutex.h" #include "HAL/handles/HandlesInternal.h" namespace hal { /** * The UnlimitedHandleResource class is a way to track handles. This version * allows an unlimted number of handles that are allocated sequentially. When * possible, indices are reused to save memory usage and keep the array length * down. * However, automatic array management has not been implemented, but might be in * the future. * Because we have to loop through the allocator, we must use a global mutex. * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle) * @tparam TStruct The struct type held by this resource * @tparam enumValue The type value stored in the handle * */ template class UnlimitedHandleResource { friend class UnlimitedHandleResourceTest; public: UnlimitedHandleResource() = default; UnlimitedHandleResource(const UnlimitedHandleResource&) = delete; UnlimitedHandleResource& operator=(const UnlimitedHandleResource&) = delete; THandle Allocate(std::shared_ptr structure); std::shared_ptr Get(THandle handle); void Free(THandle handle); private: std::vector> m_structures; priority_mutex m_handleMutex; }; template THandle UnlimitedHandleResource::Allocate( std::shared_ptr structure) { std::lock_guard sync(m_handleMutex); size_t i; for (i = 0; i < m_structures.size(); i++) { if (m_structures[i] == nullptr) { m_structures[i] = structure; return static_cast(createHandle(i, enumValue)); } } if (i >= INT16_MAX) return HAL_kInvalidHandle; m_structures.push_back(structure); return static_cast(createHandle(static_cast(i), enumValue)); } template std::shared_ptr UnlimitedHandleResource::Get(THandle handle) { int16_t index = getHandleTypedIndex(handle, enumValue); std::lock_guard sync(m_handleMutex); if (index < 0 || index >= static_cast(m_structures.size())) return nullptr; return m_structures[index]; } template void UnlimitedHandleResource::Free( THandle handle) { int16_t index = getHandleTypedIndex(handle, enumValue); std::lock_guard sync(m_handleMutex); if (index < 0 || index >= static_cast(m_structures.size())) return; m_structures[index].reset(); } } // namespace hal