Files
allwpilib/cscore/src/main/native/cpp/Handle.h

125 lines
3.3 KiB
C
Raw Normal View History

2016-09-05 12:00:04 -07:00
/*----------------------------------------------------------------------------*/
2018-01-02 09:16:20 -08:00
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
2016-09-05 12:00:04 -07:00
/* 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. */
/*----------------------------------------------------------------------------*/
2017-08-25 17:48:06 -07:00
#ifndef CSCORE_HANDLE_H_
#define CSCORE_HANDLE_H_
2016-09-05 12:00:04 -07:00
#include <atomic>
2017-08-25 17:48:06 -07:00
#include <memory>
#include <utility>
2016-09-05 12:00:04 -07:00
#include <wpi/StringRef.h>
2016-09-05 12:00:04 -07:00
#include "UnlimitedHandleResource.h"
2017-08-25 17:48:06 -07:00
#include "cscore_c.h"
2016-09-05 12:00:04 -07:00
namespace cs {
class SinkImpl;
class SourceImpl;
// Handle data layout:
// Bits 0-15: Handle index
// Bits 16-23: Parent index (property only)
2016-09-05 12:00:04 -07:00
// Bits 24-30: Type
class Handle {
public:
2017-08-25 17:48:06 -07:00
enum Type { kUndefined = 0, kProperty = 0x40, kSource, kSink, kListener };
2016-09-05 12:00:04 -07:00
enum { kIndexMax = 0xffff };
2017-08-25 17:48:06 -07:00
Handle(CS_Handle handle) : m_handle(handle) {} // NOLINT
2016-09-05 12:00:04 -07:00
operator CS_Handle() const { return m_handle; }
Handle(int index, Type type) {
if (index < 0) {
m_handle = 0;
return;
}
m_handle = ((static_cast<int>(type) & 0x7f) << 24) | (index & 0xffff);
}
Handle(int index, int property, Type type) {
if (index < 0 || property < 0) {
m_handle = 0;
return;
}
m_handle = ((static_cast<int>(type) & 0x7f) << 24) |
((index & 0xff) << 16) | (property & 0xffff);
2016-09-05 12:00:04 -07:00
}
int GetIndex() const { return static_cast<int>(m_handle) & 0xffff; }
Type GetType() const {
return static_cast<Type>((static_cast<int>(m_handle) >> 24) & 0xff);
}
bool IsType(Type type) const { return type == GetType(); }
int GetTypedIndex(Type type) const { return IsType(type) ? GetIndex() : -1; }
int GetParentIndex() const {
return IsType(Handle::kProperty) ? (static_cast<int>(m_handle) >> 16) & 0xff
: -1;
}
2016-09-05 12:00:04 -07:00
private:
CS_Handle m_handle;
};
struct SourceData {
2016-11-15 23:54:50 -08:00
SourceData(CS_SourceKind kind_, std::shared_ptr<SourceImpl> source_)
: kind{kind_}, refCount{0}, source{source_} {}
2016-09-05 12:00:04 -07:00
2016-11-15 23:54:50 -08:00
CS_SourceKind kind;
2016-09-05 12:00:04 -07:00
std::atomic_int refCount;
std::shared_ptr<SourceImpl> source;
};
class Sources
: public UnlimitedHandleResource<Handle, SourceData, Handle::kSource> {
public:
static Sources& GetInstance() {
static Sources instance;
return instance;
}
std::pair<CS_Source, std::shared_ptr<SourceData>> Find(
const SourceImpl& source) {
return FindIf(
[&](const SourceData& data) { return data.source.get() == &source; });
}
private:
Sources() = default;
};
2016-09-05 12:00:04 -07:00
struct SinkData {
2016-11-15 23:54:50 -08:00
explicit SinkData(CS_SinkKind kind_, std::shared_ptr<SinkImpl> sink_)
: kind{kind_}, refCount{0}, sourceHandle{0}, sink{sink_} {}
2016-09-05 12:00:04 -07:00
2016-11-15 23:54:50 -08:00
CS_SinkKind kind;
2016-09-05 12:00:04 -07:00
std::atomic_int refCount;
std::atomic<CS_Source> sourceHandle;
std::shared_ptr<SinkImpl> sink;
};
class Sinks : public UnlimitedHandleResource<Handle, SinkData, Handle::kSink> {
public:
static Sinks& GetInstance() {
static Sinks instance;
return instance;
}
std::pair<CS_Sink, std::shared_ptr<SinkData>> Find(const SinkImpl& sink) {
return FindIf(
[&](const SinkData& data) { return data.sink.get() == &sink; });
}
private:
Sinks() = default;
};
2016-09-05 12:00:04 -07:00
} // namespace cs
2017-08-25 17:48:06 -07:00
#endif // CSCORE_HANDLE_H_