2016-09-05 12:00:04 -07:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* Copyright (c) FIRST 2016. 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. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
2016-11-05 22:11:55 -07:00
|
|
|
#ifndef CS_HANDLE_H_
|
|
|
|
|
#define CS_HANDLE_H_
|
2016-09-05 12:00:04 -07:00
|
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
|
|
|
|
|
|
#include "llvm/StringRef.h"
|
|
|
|
|
|
2016-11-05 22:11:55 -07:00
|
|
|
#include "cscore_c.h"
|
2016-09-05 12:00:04 -07:00
|
|
|
#include "UnlimitedHandleResource.h"
|
|
|
|
|
|
|
|
|
|
namespace cs {
|
|
|
|
|
|
|
|
|
|
class SinkImpl;
|
|
|
|
|
class SourceImpl;
|
|
|
|
|
|
|
|
|
|
// Handle data layout:
|
|
|
|
|
// Bits 0-15: Handle index
|
2016-09-19 22:03:47 -07:00
|
|
|
// Bits 16-23: Parent index (property only)
|
2016-09-05 12:00:04 -07:00
|
|
|
// Bits 24-30: Type
|
|
|
|
|
|
|
|
|
|
class Handle {
|
|
|
|
|
public:
|
|
|
|
|
enum Type {
|
|
|
|
|
kUndefined = 0,
|
|
|
|
|
kProperty = 0x40,
|
|
|
|
|
kSource,
|
|
|
|
|
kSink,
|
|
|
|
|
kListener
|
|
|
|
|
};
|
|
|
|
|
enum { kIndexMax = 0xffff };
|
|
|
|
|
|
|
|
|
|
Handle(CS_Handle handle) : m_handle(handle) {}
|
|
|
|
|
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) |
|
2016-09-19 22:03:47 -07:00
|
|
|
((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; }
|
2016-09-19 22:03:47 -07:00
|
|
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2016-11-18 07:49:33 -08:00
|
|
|
class Sources
|
|
|
|
|
: public UnlimitedHandleResource<Handle, SourceData, Handle::kSource> {
|
|
|
|
|
public:
|
|
|
|
|
static Sources& GetInstance() {
|
|
|
|
|
ATOMIC_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;
|
|
|
|
|
|
|
|
|
|
ATOMIC_STATIC_DECL(Sources)
|
|
|
|
|
};
|
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;
|
|
|
|
|
};
|
|
|
|
|
|
2016-11-18 07:49:33 -08:00
|
|
|
class Sinks : public UnlimitedHandleResource<Handle, SinkData, Handle::kSink> {
|
|
|
|
|
public:
|
|
|
|
|
static Sinks& GetInstance() {
|
|
|
|
|
ATOMIC_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;
|
|
|
|
|
|
|
|
|
|
ATOMIC_STATIC_DECL(Sinks)
|
|
|
|
|
};
|
2016-09-05 12:00:04 -07:00
|
|
|
|
|
|
|
|
} // namespace cs
|
|
|
|
|
|
2016-11-05 22:11:55 -07:00
|
|
|
#endif // CS_HANDLE_H_
|