WPILibC++  2020.3.2-60-g3011ebe
UnlimitedHandleResource.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2008-2019 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #pragma once
9 
10 #include <stdint.h>
11 
12 #include <memory>
13 #include <utility>
14 #include <vector>
15 
16 #include <wpi/mutex.h>
17 
18 #include "hal/Types.h"
19 #include "hal/handles/HandlesInternal.h"
20 
21 namespace hal {
22 
37 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
39  friend class UnlimitedHandleResourceTest;
40 
41  public:
42  UnlimitedHandleResource() = default;
44  UnlimitedHandleResource& operator=(const UnlimitedHandleResource&) = delete;
45 
46  THandle Allocate(std::shared_ptr<TStruct> structure);
47  std::shared_ptr<TStruct> Get(THandle handle);
48  /* Returns structure previously at that handle (or nullptr if none) */
49  std::shared_ptr<TStruct> Free(THandle handle);
50  void ResetHandles() override;
51 
52  /* Calls func(THandle, TStruct*) for each handle. Note this holds the
53  * global lock for the entirety of execution.
54  */
55  template <typename Functor>
56  void ForEach(Functor func);
57 
58  private:
59  std::vector<std::shared_ptr<TStruct>> m_structures;
60  wpi::mutex m_handleMutex;
61 };
62 
63 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
65  std::shared_ptr<TStruct> structure) {
66  std::scoped_lock lock(m_handleMutex);
67  size_t i;
68  for (i = 0; i < m_structures.size(); i++) {
69  if (m_structures[i] == nullptr) {
70  m_structures[i] = structure;
71  return static_cast<THandle>(createHandle(i, enumValue, m_version));
72  }
73  }
74  if (i >= INT16_MAX) return HAL_kInvalidHandle;
75 
76  m_structures.push_back(structure);
77  return static_cast<THandle>(
78  createHandle(static_cast<int16_t>(i), enumValue, m_version));
79 }
80 
81 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
82 std::shared_ptr<TStruct>
83 UnlimitedHandleResource<THandle, TStruct, enumValue>::Get(THandle handle) {
84  int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
85  std::scoped_lock lock(m_handleMutex);
86  if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
87  return nullptr;
88  return m_structures[index];
89 }
90 
91 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
92 std::shared_ptr<TStruct>
93 UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(THandle handle) {
94  int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
95  std::scoped_lock lock(m_handleMutex);
96  if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
97  return nullptr;
98  return std::move(m_structures[index]);
99 }
100 
101 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
102 void UnlimitedHandleResource<THandle, TStruct, enumValue>::ResetHandles() {
103  {
104  std::scoped_lock lock(m_handleMutex);
105  for (size_t i = 0; i < m_structures.size(); i++) {
106  m_structures[i].reset();
107  }
108  }
109  HandleBase::ResetHandles();
110 }
111 
112 template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
113 template <typename Functor>
114 void UnlimitedHandleResource<THandle, TStruct, enumValue>::ForEach(
115  Functor func) {
116  std::scoped_lock lock(m_handleMutex);
117  size_t i;
118  for (i = 0; i < m_structures.size(); i++) {
119  if (m_structures[i] != nullptr) {
120  func(static_cast<THandle>(createHandle(i, enumValue, m_version)),
121  m_structures[i].get());
122  }
123  }
124 }
125 
126 } // namespace hal
hal
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition: SimDataValue.h:19
hal::UnlimitedHandleResource
The UnlimitedHandleResource class is a way to track handles.
Definition: UnlimitedHandleResource.h:38
hal::getHandleTypedIndex
static int16_t getHandleTypedIndex(HAL_Handle handle, HAL_HandleEnum enumType, int16_t version)
Get if the handle is a correct type and version.
Definition: HandlesInternal.h:131
hal::HandleBase
Base for all HAL Handles.
Definition: HandlesInternal.h:29
hal::createHandle
HAL_Handle createHandle(int16_t index, HAL_HandleEnum handleType, int16_t version)
Create a handle for a specific index, type and version.