WPILibC++  unspecified
Handle.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2016-2017 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 #ifndef CSCORE_HANDLE_H_
9 #define CSCORE_HANDLE_H_
10 
11 #include <atomic>
12 #include <memory>
13 #include <utility>
14 
15 #include <llvm/StringRef.h>
16 
17 #include "UnlimitedHandleResource.h"
18 #include "cscore_c.h"
19 
20 namespace cs {
21 
22 class SinkImpl;
23 class SourceImpl;
24 
25 // Handle data layout:
26 // Bits 0-15: Handle index
27 // Bits 16-23: Parent index (property only)
28 // Bits 24-30: Type
29 
30 class Handle {
31  public:
32  enum Type { kUndefined = 0, kProperty = 0x40, kSource, kSink, kListener };
33  enum { kIndexMax = 0xffff };
34 
35  Handle(CS_Handle handle) : m_handle(handle) {} // NOLINT
36  operator CS_Handle() const { return m_handle; }
37 
38  Handle(int index, Type type) {
39  if (index < 0) {
40  m_handle = 0;
41  return;
42  }
43  m_handle = ((static_cast<int>(type) & 0x7f) << 24) | (index & 0xffff);
44  }
45  Handle(int index, int property, Type type) {
46  if (index < 0 || property < 0) {
47  m_handle = 0;
48  return;
49  }
50  m_handle = ((static_cast<int>(type) & 0x7f) << 24) |
51  ((index & 0xff) << 16) | (property & 0xffff);
52  }
53 
54  int GetIndex() const { return static_cast<int>(m_handle) & 0xffff; }
55  Type GetType() const {
56  return static_cast<Type>((static_cast<int>(m_handle) >> 24) & 0xff);
57  }
58  bool IsType(Type type) const { return type == GetType(); }
59  int GetTypedIndex(Type type) const { return IsType(type) ? GetIndex() : -1; }
60  int GetParentIndex() const {
61  return IsType(Handle::kProperty) ? (static_cast<int>(m_handle) >> 16) & 0xff
62  : -1;
63  }
64 
65  private:
66  CS_Handle m_handle;
67 };
68 
69 struct SourceData {
70  SourceData(CS_SourceKind kind_, std::shared_ptr<SourceImpl> source_)
71  : kind{kind_}, refCount{0}, source{source_} {}
72 
73  CS_SourceKind kind;
74  std::atomic_int refCount;
75  std::shared_ptr<SourceImpl> source;
76 };
77 
78 class Sources
79  : public UnlimitedHandleResource<Handle, SourceData, Handle::kSource> {
80  public:
81  static Sources& GetInstance() {
82  ATOMIC_STATIC(Sources, instance);
83  return instance;
84  }
85 
86  std::pair<CS_Source, std::shared_ptr<SourceData>> Find(
87  const SourceImpl& source) {
88  return FindIf(
89  [&](const SourceData& data) { return data.source.get() == &source; });
90  }
91 
92  private:
93  Sources() = default;
94 
95  ATOMIC_STATIC_DECL(Sources)
96 };
97 
98 struct SinkData {
99  explicit SinkData(CS_SinkKind kind_, std::shared_ptr<SinkImpl> sink_)
100  : kind{kind_}, refCount{0}, sourceHandle{0}, sink{sink_} {}
101 
102  CS_SinkKind kind;
103  std::atomic_int refCount;
104  std::atomic<CS_Source> sourceHandle;
105  std::shared_ptr<SinkImpl> sink;
106 };
107 
108 class Sinks : public UnlimitedHandleResource<Handle, SinkData, Handle::kSink> {
109  public:
110  static Sinks& GetInstance() {
111  ATOMIC_STATIC(Sinks, instance);
112  return instance;
113  }
114 
115  std::pair<CS_Sink, std::shared_ptr<SinkData>> Find(const SinkImpl& sink) {
116  return FindIf(
117  [&](const SinkData& data) { return data.sink.get() == &sink; });
118  }
119 
120  private:
121  Sinks() = default;
122 
123  ATOMIC_STATIC_DECL(Sinks)
124 };
125 
126 } // namespace cs
127 
128 #endif // CSCORE_HANDLE_H_
Definition: SinkImpl.h:19
Definition: SinkImpl.h:23
Definition: Handle.h:30
Definition: SourceImpl.h:30
Definition: Handle.h:108
Definition: Handle.h:69
Definition: Handle.h:98
Definition: UnlimitedHandleResource.h:42
Definition: Handle.h:78