carb/settings/ISettings.h

File members: carb/settings/ISettings.h

// Copyright (c) 2019-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//

#pragma once

#include "../Defines.h"

#include "../Types.h"
#include "../InterfaceUtils.h"
#include "../dictionary/IDictionary.h"

#include <cstddef>

namespace carb
{

namespace settings
{

struct Transaction DOXYGEN_EMPTY_CLASS;

struct ISettings
{
    CARB_PLUGIN_INTERFACE("carb::settings::ISettings", 1, 0)

    dictionary::ItemType(CARB_ABI* getItemType)(const char* path);

    bool(CARB_ABI* isAccessibleAs)(dictionary::ItemType itemType, const char* path);

    void(CARB_ABI* setDictionary)(const char* path);

    int64_t(CARB_ABI* getAsInt64)(const char* path);

    void(CARB_ABI* setInt64)(const char* path, int64_t value);

    int32_t getAsInt(const char* path);

    void setInt(const char* path, int32_t value);

    double(CARB_ABI* getAsFloat64)(const char* path);

    void(CARB_ABI* setFloat64)(const char* path, double value);

    float getAsFloat(const char* path);

    void setFloat(const char* path, float value);

    bool(CARB_ABI* getAsBool)(const char* path);

    void(CARB_ABI* setBool)(const char* path, bool value);

    const char*(CARB_ABI* internalCreateStringBufferFromItemValue)(const char* path, size_t* pStringLen);

    const char* createStringBufferFromItemValue(const char* path, size_t* pStringLen = nullptr) const
    {
        return internalCreateStringBufferFromItemValue(path, pStringLen);
    }

    const char*(CARB_ABI* internalGetStringBuffer)(const char* path, size_t* pStringLen);

    const char* getStringBuffer(const char* path, size_t* pStringLen = nullptr) const
    {
        return internalGetStringBuffer(path, pStringLen);
    }

    void(CARB_ABI* internalSetString)(const char* path, const char* value, size_t stringLen);

    void setString(const char* path, const char* value, size_t stringLen = size_t(-1)) const
    {
        internalSetString(path, value, stringLen);
    }

    template <typename T>
    T get(const char* path);

    template <typename T>
    void set(const char* path, T value);

    bool(CARB_ABI* isAccessibleAsArray)(const char* path);

    bool(CARB_ABI* isAccessibleAsArrayOf)(dictionary::ItemType itemType, const char* path);

    size_t(CARB_ABI* getArrayLength)(const char* path);

    dictionary::ItemType(CARB_ABI* getPreferredArrayType)(const char* path);

    int64_t(CARB_ABI* getAsInt64At)(const char* path, size_t index);

    void(CARB_ABI* setInt64At)(const char* path, size_t index, int64_t value);

    int32_t getAsIntAt(const char* path, size_t index);

    void setIntAt(const char* path, size_t index, int32_t value);

    void(CARB_ABI* getAsInt64Array)(const char* path, int64_t* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setInt64Array)(const char* path, const int64_t* array, size_t arrayLength);

    void(CARB_ABI* getAsIntArray)(const char* path, int32_t* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setIntArray)(const char* path, const int32_t* array, size_t arrayLength);

    double(CARB_ABI* getAsFloat64At)(const char* path, size_t index);

    void(CARB_ABI* setFloat64At)(const char* path, size_t index, double value);

    float getAsFloatAt(const char* path, size_t index);

    void setFloatAt(const char* path, size_t index, float value);

    void(CARB_ABI* getAsFloat64Array)(const char* path, double* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setFloat64Array)(const char* path, const double* array, size_t arrayLength);

    void(CARB_ABI* getAsFloatArray)(const char* path, float* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setFloatArray)(const char* path, const float* array, size_t arrayLength);

    bool(CARB_ABI* getAsBoolAt)(const char* path, size_t index);

    void(CARB_ABI* setBoolAt)(const char* path, size_t index, bool value);

    void(CARB_ABI* getAsBoolArray)(const char* path, bool* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setBoolArray)(const char* path, const bool* array, size_t arrayLength);

    const char*(CARB_ABI* internalCreateStringBufferFromItemValueAt)(const char* path, size_t index, size_t* pStringLen);

    const char* createStringBufferFromItemValueAt(const char* path, size_t index, size_t* pStringLen = nullptr) const
    {
        return internalCreateStringBufferFromItemValueAt(path, index, pStringLen);
    }

    const char*(CARB_ABI* internalGetStringBufferAt)(const char* path, size_t index, size_t* pStringLen);

    const char* getStringBufferAt(const char* path, size_t index, size_t* pStringLen = nullptr) const
    {
        return internalGetStringBufferAt(path, index, pStringLen);
    }

    void(CARB_ABI* internalSetStringAt)(const char* path, size_t index, const char* value, size_t stringLen);

    void setStringAt(const char* path, size_t index, const char* value, size_t stringLen = size_t(-1)) const
    {
        internalSetStringAt(path, index, value, stringLen);
    }

    void(CARB_ABI* getStringBufferArray)(const char* path, const char** arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setStringArray)(const char* path, const char* const* array, size_t arrayLength);

    template <typename SettingArrayType>
    void setArray(const char* path, const SettingArrayType* array, size_t arrayLength);

    Transaction*(CARB_ABI* createTransaction)();

    void(CARB_ABI* destroyTransaction)(Transaction* transaction);

    void(CARB_ABI* commitTransaction)(Transaction* transaction);

    void(CARB_ABI* setInt64Async)(Transaction* transaction, const char* path, int64_t value);
    void(CARB_ABI* setFloat64Async)(Transaction* transaction, const char* path, double value);
    void(CARB_ABI* setBoolAsync)(Transaction* transaction, const char* path, bool value);
    void(CARB_ABI* setStringAsync)(Transaction* transaction, const char* path, const char* value);

    dictionary::SubscriptionId*(CARB_ABI* subscribeToNodeChangeEvents)(const char* path,
                                                                       dictionary::OnNodeChangeEventFn onChangeEventFn,
                                                                       void* userData);

    dictionary::SubscriptionId*(CARB_ABI* subscribeToTreeChangeEvents)(const char* path,
                                                                       dictionary::OnTreeChangeEventFn onChangeEventFn,
                                                                       void* userData);

    void(CARB_ABI* unsubscribeToChangeEvents)(dictionary::SubscriptionId* subscriptionId);

    void(CARB_ABI* update)(const char* path,
                           const dictionary::Item* dictionary,
                           const char* dictionaryPath,
                           dictionary::OnUpdateItemFn onUpdateItemFn,
                           void* userData);

    const dictionary::Item*(CARB_ABI* getSettingsDictionary)(const char* path);

    dictionary::Item*(CARB_ABI* createDictionaryFromSettings)(const char* path);

    void(CARB_ABI* destroyItem)(const char* path);

    void(CARB_ABI* destroyStringBuffer)(const char* stringBuffer);

    void(CARB_ABI* initializeFromDictionary)(const dictionary::Item* dictionary);

    void setDefaultInt64(const char* path, int64_t value);
    void setDefaultInt(const char* path, int32_t value);
    void setDefaultFloat64(const char* path, double value);
    void setDefaultFloat(const char* path, float value);
    void setDefaultBool(const char* path, bool value);
    void setDefaultString(const char* path, const char* value);

    template <typename SettingType>
    void setDefault(const char* path, SettingType value);

    void setDefaultsFromDictionary(const char* path, const dictionary::Item* dictionary);

    void setDefaultInt64Array(const char* path, const int64_t* array, size_t arrayLength);
    void setDefaultIntArray(const char* path, const int32_t* array, size_t arrayLength);
    void setDefaultFloat64Array(const char* path, const double* array, size_t arrayLength);
    void setDefaultFloatArray(const char* path, const float* array, size_t arrayLength);
    void setDefaultBoolArray(const char* path, const bool* array, size_t arrayLength);
    void setDefaultStringArray(const char* path, const char* const* array, size_t arrayLength);

    template <typename SettingArrayType>
    void setDefaultArray(const char* path, const SettingArrayType* array, size_t arrayLength);
};

class ScopedWrite : public carb::dictionary::ScopedWrite
{
public:
    ScopedWrite()
        : carb::dictionary::ScopedWrite(
              *carb::getCachedInterface<dictionary::IDictionary>(),
              const_cast<dictionary::Item*>(carb::getCachedInterface<settings::ISettings>()->getSettingsDictionary("/")))
    {
    }
    ~ScopedWrite() = default;
    CARB_PREVENT_COPY_AND_MOVE(ScopedWrite);
};

class ScopedRead : public carb::dictionary::ScopedRead
{
public:
    ScopedRead()
        : carb::dictionary::ScopedRead(*carb::getCachedInterface<dictionary::IDictionary>(),
                                       carb::getCachedInterface<settings::ISettings>()->getSettingsDictionary("/"))
    {
    }
    ~ScopedRead() = default;
    CARB_PREVENT_COPY_AND_MOVE(ScopedRead);
};

inline int32_t ISettings::getAsInt(const char* path)
{
    auto val = getAsInt64(path);
    CARB_ASSERT(val >= INT_MIN && val <= INT_MAX);
    return int32_t(val);
}

inline void ISettings::setInt(const char* path, int32_t value)
{
    setInt64(path, (int64_t)value);
}

inline float ISettings::getAsFloat(const char* path)
{
    return (float)getAsFloat64(path);
}

inline void ISettings::setFloat(const char* path, float value)
{
    setFloat64(path, (double)value);
}

inline int32_t ISettings::getAsIntAt(const char* path, size_t index)
{
    auto val = getAsInt64At(path, index);
    CARB_ASSERT(val >= INT_MIN && val <= INT_MAX);
    return int32_t(val);
}
inline void ISettings::setIntAt(const char* path, size_t index, int32_t value)
{
    setInt64At(path, index, (int64_t)value);
}

inline float ISettings::getAsFloatAt(const char* path, size_t index)
{
    return (float)getAsFloat64At(path, index);
}
inline void ISettings::setFloatAt(const char* path, size_t index, float value)
{
    setFloat64At(path, index, (double)value);
}

inline void ISettings::setDefaultInt64(const char* path, int64_t value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setInt64(path, value);
    }
}
inline void ISettings::setDefaultInt(const char* path, int32_t value)
{
    setDefaultInt64(path, (int64_t)value);
}

inline void ISettings::setDefaultFloat64(const char* path, double value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloat64(path, value);
    }
}
inline void ISettings::setDefaultFloat(const char* path, float value)
{
    setDefaultFloat64(path, (double)value);
}

inline void ISettings::setDefaultBool(const char* path, bool value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setBool(path, value);
    }
}

inline void ISettings::setDefaultString(const char* path, const char* value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setString(path, value);
    }
}

inline void ISettings::setDefaultsFromDictionary(const char* path, const dictionary::Item* dictionary)
{
    if (dictionary)
    {
        update(path, dictionary, nullptr, dictionary::kUpdateItemKeepOriginal, nullptr);
    }
}

inline void ISettings::setDefaultInt64Array(const char* path, const int64_t* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setInt64Array(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultIntArray(const char* path, const int32_t* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setIntArray(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultFloat64Array(const char* path, const double* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloat64Array(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultFloatArray(const char* path, const float* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloatArray(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultBoolArray(const char* path, const bool* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setBoolArray(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultStringArray(const char* path, const char* const* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setStringArray(path, array, arrayLength);
    }
}

#ifndef DOXYGEN_BUILD
template <>
inline int32_t ISettings::get<int>(const char* path)
{
    return getAsInt(path);
}

template <>
inline int64_t ISettings::get<int64_t>(const char* path)
{
    return getAsInt64(path);
}

template <>
inline float ISettings::get<float>(const char* path)
{
    return getAsFloat(path);
}

template <>
inline double ISettings::get<double>(const char* path)
{
    return getAsFloat64(path);
}

template <>
inline bool ISettings::get<bool>(const char* path)
{
    return getAsBool(path);
}

template <>
inline const char* ISettings::get<const char*>(const char* path)
{
    return getStringBuffer(path);
}

template <>
inline void ISettings::set<int32_t>(const char* path, int32_t value)
{
    setInt(path, value);
}

template <>
inline void ISettings::set<int64_t>(const char* path, int64_t value)
{
    setInt64(path, value);
}

template <>
inline void ISettings::set<float>(const char* path, float value)
{
    setFloat(path, value);
}

template <>
inline void ISettings::set<double>(const char* path, double value)
{
    setFloat64(path, value);
}

template <>
inline void ISettings::set<bool>(const char* path, bool value)
{
    setBool(path, value);
}

template <>
inline void ISettings::set<const char*>(const char* path, const char* value)
{
    setString(path, value);
}

template <>
inline void ISettings::setArray(const char* path, const bool* array, size_t arrayLength)
{
    setBoolArray(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const int32_t* array, size_t arrayLength)
{
    setIntArray(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const int64_t* array, size_t arrayLength)
{
    setInt64Array(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const float* array, size_t arrayLength)
{
    setFloatArray(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const double* array, size_t arrayLength)
{
    setFloat64Array(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const char* const* array, size_t arrayLength)
{
    setStringArray(path, array, arrayLength);
}

template <>
inline void ISettings::setDefault(const char* path, bool value)
{
    setDefaultBool(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, int32_t value)
{
    setDefaultInt(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, int64_t value)
{
    setDefaultInt64(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, float value)
{
    setDefaultFloat(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, double value)
{
    setDefaultFloat64(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, const char* value)
{
    setDefaultString(path, value);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const bool* array, size_t arrayLength)
{
    setDefaultBoolArray(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const int32_t* array, size_t arrayLength)
{
    setDefaultIntArray(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const int64_t* array, size_t arrayLength)
{
    setDefaultInt64Array(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const float* array, size_t arrayLength)
{
    setDefaultFloatArray(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const double* array, size_t arrayLength)
{
    setDefaultFloat64Array(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const char* const* array, size_t arrayLength)
{
    setDefaultStringArray(settingsPath, array, arrayLength);
}
#endif

} // namespace settings
} // namespace carb