#pragma once
#include <stdint.h>
#ifdef __cplusplus
#include <initializer_list>
#include <span>
#include <string>
#endif
#include "hal/Types.h"
#include "hal/Value.h"
HAL_ENUM(HAL_SimValueDirection) {
HAL_SimValueInput = 0,
HAL_SimValueOutput,
HAL_SimValueBidir
};
#ifdef __cplusplus
extern "C" {
#endif
HAL_SimDeviceHandle HAL_CreateSimDevice(const char* name);
void HAL_FreeSimDevice(HAL_SimDeviceHandle handle);
const char* HAL_GetSimDeviceName(HAL_SimDeviceHandle handle);
HAL_SimValueHandle HAL_CreateSimValue(HAL_SimDeviceHandle device,
const char* name, int32_t direction,
const struct HAL_Value* initialValue);
#ifdef __cplusplus
extern "C++" {
inline HAL_SimValueHandle HAL_CreateSimValue(HAL_SimDeviceHandle device,
const char* name,
int32_t direction,
const HAL_Value& initialValue) {
return HAL_CreateSimValue(device, name, direction, &initialValue);
}
} #endif
inline HAL_SimValueHandle HAL_CreateSimValueInt(HAL_SimDeviceHandle device,
const char* name,
int32_t direction,
int32_t initialValue) {
struct HAL_Value v = HAL_MakeInt(initialValue);
return HAL_CreateSimValue(device, name, direction, &v);
}
inline HAL_SimValueHandle HAL_CreateSimValueLong(HAL_SimDeviceHandle device,
const char* name,
int32_t direction,
int64_t initialValue) {
struct HAL_Value v = HAL_MakeLong(initialValue);
return HAL_CreateSimValue(device, name, direction, &v);
}
inline HAL_SimValueHandle HAL_CreateSimValueDouble(HAL_SimDeviceHandle device,
const char* name,
int32_t direction,
double initialValue) {
struct HAL_Value v = HAL_MakeDouble(initialValue);
return HAL_CreateSimValue(device, name, direction, &v);
}
HAL_SimValueHandle HAL_CreateSimValueEnum(HAL_SimDeviceHandle device,
const char* name, int32_t direction,
int32_t numOptions,
const char** options,
int32_t initialValue);
HAL_SimValueHandle HAL_CreateSimValueEnumDouble(
HAL_SimDeviceHandle device, const char* name, int32_t direction,
int32_t numOptions, const char** options, const double* optionValues,
int32_t initialValue);
inline HAL_SimValueHandle HAL_CreateSimValueBoolean(HAL_SimDeviceHandle device,
const char* name,
int32_t direction,
HAL_Bool initialValue) {
struct HAL_Value v = HAL_MakeBoolean(initialValue);
return HAL_CreateSimValue(device, name, direction, &v);
}
void HAL_GetSimValue(HAL_SimValueHandle handle, struct HAL_Value* value);
#ifdef __cplusplus
extern "C++" {
inline HAL_Value HAL_GetSimValue(HAL_SimValueHandle handle) {
HAL_Value v;
HAL_GetSimValue(handle, &v);
return v;
}
} #endif
inline int32_t HAL_GetSimValueInt(HAL_SimValueHandle handle) {
struct HAL_Value v;
HAL_GetSimValue(handle, &v);
return v.type == HAL_INT ? v.data.v_int : 0;
}
inline int64_t HAL_GetSimValueLong(HAL_SimValueHandle handle) {
struct HAL_Value v;
HAL_GetSimValue(handle, &v);
return v.type == HAL_LONG ? v.data.v_long : 0;
}
inline double HAL_GetSimValueDouble(HAL_SimValueHandle handle) {
struct HAL_Value v;
HAL_GetSimValue(handle, &v);
return v.type == HAL_DOUBLE ? v.data.v_double : 0.0;
}
inline int32_t HAL_GetSimValueEnum(HAL_SimValueHandle handle) {
struct HAL_Value v;
HAL_GetSimValue(handle, &v);
return v.type == HAL_ENUM ? v.data.v_enum : 0;
}
inline HAL_Bool HAL_GetSimValueBoolean(HAL_SimValueHandle handle) {
struct HAL_Value v;
HAL_GetSimValue(handle, &v);
return v.type == HAL_BOOLEAN ? v.data.v_boolean : 0;
}
void HAL_SetSimValue(HAL_SimValueHandle handle, const struct HAL_Value* value);
#ifdef __cplusplus
extern "C++" {
inline void HAL_SetSimValue(HAL_SimValueHandle handle, const HAL_Value& value) {
HAL_SetSimValue(handle, &value);
}
} #endif
inline void HAL_SetSimValueInt(HAL_SimValueHandle handle, int value) {
struct HAL_Value v = HAL_MakeInt(value);
HAL_SetSimValue(handle, &v);
}
inline void HAL_SetSimValueLong(HAL_SimValueHandle handle, int64_t value) {
struct HAL_Value v = HAL_MakeLong(value);
HAL_SetSimValue(handle, &v);
}
inline void HAL_SetSimValueDouble(HAL_SimValueHandle handle, double value) {
struct HAL_Value v = HAL_MakeDouble(value);
HAL_SetSimValue(handle, &v);
}
inline void HAL_SetSimValueEnum(HAL_SimValueHandle handle, int32_t value) {
struct HAL_Value v = HAL_MakeEnum(value);
HAL_SetSimValue(handle, &v);
}
inline void HAL_SetSimValueBoolean(HAL_SimValueHandle handle, HAL_Bool value) {
struct HAL_Value v = HAL_MakeBoolean(value);
HAL_SetSimValue(handle, &v);
}
void HAL_ResetSimValue(HAL_SimValueHandle handle);
#ifdef __cplusplus
} #endif
#ifdef __cplusplus
namespace hal {
class SimValue {
public:
SimValue() = default;
SimValue(HAL_SimValueHandle val) : m_handle(val) {}
explicit operator bool() const { return m_handle != HAL_kInvalidHandle; }
operator HAL_SimValueHandle() const { return m_handle; }
HAL_Value GetValue() const { return HAL_GetSimValue(m_handle); }
void SetValue(const HAL_Value& value) { HAL_SetSimValue(m_handle, value); }
protected:
HAL_SimValueHandle m_handle = HAL_kInvalidHandle;
};
class SimInt : public SimValue {
public:
SimInt() = default;
SimInt(HAL_SimValueHandle val) : SimValue(val) {}
int32_t Get() const { return HAL_GetSimValueInt(m_handle); }
void Set(int32_t value) { HAL_SetSimValueInt(m_handle, value); }
void Reset() { HAL_ResetSimValue(m_handle); }
};
class SimLong : public SimValue {
public:
SimLong() = default;
SimLong(HAL_SimValueHandle val) : SimValue(val) {}
int64_t Get() const { return HAL_GetSimValueLong(m_handle); }
void Set(int64_t value) { HAL_SetSimValueLong(m_handle, value); }
void Reset() { HAL_ResetSimValue(m_handle); }
};
class SimDouble : public SimValue {
public:
SimDouble() = default;
SimDouble(HAL_SimValueHandle val) : SimValue(val) {}
double Get() const { return HAL_GetSimValueDouble(m_handle); }
void Set(double value) { HAL_SetSimValueDouble(m_handle, value); }
void Reset() { HAL_ResetSimValue(m_handle); }
};
class SimEnum : public SimValue {
public:
SimEnum() = default;
SimEnum(HAL_SimValueHandle val) : SimValue(val) {}
int32_t Get() const { return HAL_GetSimValueEnum(m_handle); }
void Set(int32_t value) { HAL_SetSimValueEnum(m_handle, value); }
};
class SimBoolean : public SimValue {
public:
SimBoolean() = default;
SimBoolean(HAL_SimValueHandle val) : SimValue(val) {}
bool Get() const { return HAL_GetSimValueBoolean(m_handle); }
void Set(bool value) { HAL_SetSimValueBoolean(m_handle, value); }
};
class SimDevice {
public:
enum Direction {
kInput = HAL_SimValueInput,
kOutput = HAL_SimValueOutput,
kBidir = HAL_SimValueBidir
};
SimDevice() = default;
explicit SimDevice(const char* name) : m_handle(HAL_CreateSimDevice(name)) {}
SimDevice(const char* name, int index);
SimDevice(const char* name, int index, int channel);
~SimDevice() {
if (m_handle != HAL_kInvalidHandle) {
HAL_FreeSimDevice(m_handle);
}
}
SimDevice(const SimDevice&) = delete;
SimDevice& operator=(const SimDevice&) = delete;
SimDevice(SimDevice&& rhs) : m_handle(rhs.m_handle) {
rhs.m_handle = HAL_kInvalidHandle;
}
SimDevice& operator=(SimDevice&& rhs) {
m_handle = rhs.m_handle;
rhs.m_handle = HAL_kInvalidHandle;
return *this;
}
explicit operator bool() const { return m_handle != HAL_kInvalidHandle; }
operator HAL_SimDeviceHandle() const { return m_handle; }
std::string GetName() const {
return std::string(HAL_GetSimDeviceName(m_handle));
}
SimValue CreateValue(const char* name, int32_t direction,
const HAL_Value& initialValue) {
return HAL_CreateSimValue(m_handle, name, direction, &initialValue);
}
SimInt CreateInt(const char* name, int32_t direction, int32_t initialValue) {
return HAL_CreateSimValueInt(m_handle, name, direction, initialValue);
}
SimLong CreateLong(const char* name, int32_t direction,
int64_t initialValue) {
return HAL_CreateSimValueLong(m_handle, name, direction, initialValue);
}
SimDouble CreateDouble(const char* name, int32_t direction,
double initialValue) {
return HAL_CreateSimValueDouble(m_handle, name, direction, initialValue);
}
SimEnum CreateEnum(const char* name, int32_t direction,
std::initializer_list<const char*> options,
int32_t initialValue) {
return HAL_CreateSimValueEnum(m_handle, name, direction, options.size(),
const_cast<const char**>(options.begin()),
initialValue);
}
SimEnum CreateEnum(const char* name, int32_t direction,
std::span<const char* const> options,
int32_t initialValue) {
return HAL_CreateSimValueEnum(m_handle, name, direction, options.size(),
const_cast<const char**>(options.data()),
initialValue);
}
SimEnum CreateEnumDouble(const char* name, int32_t direction,
std::initializer_list<const char*> options,
std::initializer_list<double> optionValues,
int32_t initialValue) {
if (options.size() != optionValues.size()) {
return {};
}
return HAL_CreateSimValueEnumDouble(
m_handle, name, direction, options.size(),
const_cast<const char**>(options.begin()), optionValues.begin(),
initialValue);
}
SimEnum CreateEnumDouble(const char* name, int32_t direction,
std::span<const char* const> options,
std::span<const double> optionValues,
int32_t initialValue) {
if (options.size() != optionValues.size()) {
return {};
}
return HAL_CreateSimValueEnumDouble(
m_handle, name, direction, options.size(),
const_cast<const char**>(options.data()), optionValues.data(),
initialValue);
}
SimBoolean CreateBoolean(const char* name, int32_t direction,
bool initialValue) {
return HAL_CreateSimValueBoolean(m_handle, name, direction, initialValue);
}
protected:
HAL_SimDeviceHandle m_handle = HAL_kInvalidHandle;
};
} #endif