WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
UnlimitedHandleResource.hpp
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <stdint.h>
8
9#include <memory>
10#include <utility>
11#include <vector>
12
13#include "wpi/hal/Types.h"
15#include "wpi/util/mutex.hpp"
16
17namespace wpi::hal {
18
19/**
20 * The UnlimitedHandleResource class is a way to track handles. This version
21 * allows an unlimited number of handles that are allocated sequentially. When
22 * possible, indices are reused to save memory usage and keep the array length
23 * down.
24 * However, automatic array management has not been implemented, but might be in
25 * the future.
26 * Because we have to loop through the allocator, we must use a global mutex.
27
28 * @tparam THandle The Handle Type (Must be typedefed from HAL_Handle)
29 * @tparam TStruct The struct type held by this resource
30 * @tparam enumValue The type value stored in the handle
31 *
32 */
33template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
36
37 public:
41
42 THandle Allocate(std::shared_ptr<TStruct> structure);
43 int16_t GetIndex(THandle handle) {
44 return getHandleTypedIndex(handle, enumValue, m_version);
45 }
46 std::shared_ptr<TStruct> Get(THandle handle);
47 /* Returns structure previously at that handle (or nullptr if none) */
48 std::shared_ptr<TStruct> Free(THandle handle);
49 void ResetHandles() override;
50
51 /* Calls func(THandle, TStruct*) for each handle. Note this holds the
52 * global lock for the entirety of execution.
53 */
54 template <typename Functor>
55 void ForEach(Functor func);
56
57 private:
58 std::vector<std::shared_ptr<TStruct>> m_structures;
59 wpi::util::mutex m_handleMutex;
60};
61
62template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
64 std::shared_ptr<TStruct> structure) {
65 std::scoped_lock lock(m_handleMutex);
66 size_t i;
67 for (i = 0; i < m_structures.size(); i++) {
68 if (m_structures[i] == nullptr) {
69 m_structures[i] = structure;
70 return static_cast<THandle>(createHandle(i, enumValue, m_version));
71 }
72 }
73 if (i >= INT16_MAX) {
74 return HAL_kInvalidHandle;
75 }
76
77 m_structures.push_back(structure);
78 return static_cast<THandle>(
79 createHandle(static_cast<int16_t>(i), enumValue, m_version));
80}
81
82template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
83std::shared_ptr<TStruct>
85 int16_t index = GetIndex(handle);
86 std::scoped_lock lock(m_handleMutex);
87 if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) {
88 return nullptr;
89 }
90 return m_structures[index];
91}
92
93template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
94std::shared_ptr<TStruct>
96 int16_t index = GetIndex(handle);
97 std::scoped_lock lock(m_handleMutex);
98 if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) {
99 return nullptr;
100 }
101 return std::move(m_structures[index]);
102}
103
104template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
106 {
107 std::scoped_lock lock(m_handleMutex);
108 for (size_t i = 0; i < m_structures.size(); i++) {
109 m_structures[i].reset();
110 }
111 }
113}
114
115template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
116template <typename Functor>
118 Functor func) {
119 std::scoped_lock lock(m_handleMutex);
120 size_t i;
121 for (i = 0; i < m_structures.size(); i++) {
122 if (m_structures[i] != nullptr) {
123 func(static_cast<THandle>(createHandle(i, enumValue, m_version)),
124 m_structures[i].get());
125 }
126 }
127}
128
129} // namespace wpi::hal
constexpr T & get(wpi::util::array< T, N > &arr) noexcept
Definition array.hpp:66
@ index
Definition base.h:690
virtual void ResetHandles()
int16_t m_version
Definition HandlesInternal.hpp:37
void ForEach(Functor func)
Definition UnlimitedHandleResource.hpp:117
int16_t GetIndex(THandle handle)
Definition UnlimitedHandleResource.hpp:43
std::shared_ptr< TStruct > Get(THandle handle)
Definition UnlimitedHandleResource.hpp:84
THandle Allocate(std::shared_ptr< TStruct > structure)
Definition UnlimitedHandleResource.hpp:63
void ResetHandles() override
Definition UnlimitedHandleResource.hpp:105
std::shared_ptr< TStruct > Free(THandle handle)
Definition UnlimitedHandleResource.hpp:95
friend class UnlimitedHandleResourceTest
Definition UnlimitedHandleResource.hpp:35
UnlimitedHandleResource & operator=(const UnlimitedHandleResource &)=delete
UnlimitedHandleResource(const UnlimitedHandleResource &)=delete
#define HAL_kInvalidHandle
Definition Types.h:15
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition Types.hpp:9
int16_t getHandleTypedIndex(HAL_Handle handle, HAL_HandleEnum enumType, int16_t version)
Get if the handle is a correct type and version.
Definition HandlesInternal.hpp:135
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, int16_t version)
Create a handle for a specific index, type and version.
::std::mutex mutex
Definition mutex.hpp:17