ISettings2.h#

Fully qualified name: carb/settings/detail/ISettings2.h

File members: carb/settings/detail/ISettings2.h

// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.

#pragma once

#ifndef carb_settings_ISettings_latest
#    error Must include via ../ISettings.h
#endif

#if !CARB_VERSION_ATLEAST(carb_settings_ISettings, 2, 0)
#    error Version too low to be included
#endif

#include "../../../omni/String.h"
#include "../../cpp/Optional.h"
#include "../../cpp/Span.h"

namespace carb::settings
{

#ifndef DOXYGEN_BUILD
inline namespace v2
{
#endif

class ISettings
{
public:
    CARB_PLUGIN_INTERFACE_EX("carb::settings::ISettings", carb_settings_ISettings_latest, carb_settings_ISettings)

    virtual dictionary::ItemType getItemType(cpp::string_view path) const = 0;

    virtual bool isAccessibleAs(dictionary::ItemType itemType, cpp::string_view path) const = 0;

    virtual void setDictionary(cpp::string_view path) const = 0;

    virtual int64_t getAsInt64(cpp::string_view path) const = 0;

    virtual void setInt64(cpp::string_view path, int64_t value) const = 0;

    int32_t getAsInt(cpp::string_view path) const;

    void setInt(cpp::string_view path, int32_t value) const;

    virtual double getAsFloat64(cpp::string_view path) const = 0;

    virtual void setFloat64(cpp::string_view path, double value) const = 0;

    float getAsFloat(cpp::string_view path) const;

    void setFloat(cpp::string_view path, float value) const;

    virtual bool getAsBool(cpp::string_view path) const = 0;

    virtual void setBool(cpp::string_view path, bool value) const = 0;

    virtual cpp::optional<omni::string> createStringFromItemValue(cpp::string_view path) const = 0;

    virtual cpp::optional<cpp::zstring_view> getStringView(cpp::string_view path) const = 0;

    virtual void setString(cpp::string_view path, cpp::string_view value) const = 0;

    template <typename T>
    T get(cpp::string_view path) const = delete;

    template <typename T>
    cpp::optional<T> getOpt(cpp::string_view path) const = delete;

    template <typename T, std::enable_if_t<!cpp::is_std_string_view_like_v<T>, bool> = true>
    void set(cpp::string_view path, T value) const = delete;

    void set(cpp::string_view path, cpp::string_view value) const;

    virtual bool isAccessibleAsArray(cpp::string_view path) const = 0;

    virtual bool isAccessibleAsArrayOf(dictionary::ItemType itemType, cpp::string_view path) const = 0;

    virtual size_t getArrayLength(cpp::string_view path) const = 0;

    virtual dictionary::ItemType getPreferredArrayType(cpp::string_view path) const = 0;

    virtual int64_t getAsInt64At(cpp::string_view path, size_t index) const = 0;

    virtual void setInt64At(cpp::string_view path, size_t index, int64_t value) const = 0;

    int32_t getAsIntAt(cpp::string_view path, size_t index) const;

    void setIntAt(cpp::string_view path, size_t index, int32_t value) const;

    virtual void getAsInt64Array(cpp::string_view path, int64_t* arrayOut, size_t arrayBufferLength) const = 0;

    virtual void setInt64Array(cpp::string_view path, const cpp::span<const int64_t> array) const = 0;

    virtual void getAsIntArray(cpp::string_view path, int32_t* arrayOut, size_t arrayBufferLength) const = 0;

    virtual void setIntArray(cpp::string_view path, const cpp::span<const int32_t> array) const = 0;

    virtual double getAsFloat64At(cpp::string_view path, size_t index) const = 0;

    virtual void setFloat64At(cpp::string_view path, size_t index, double value) const = 0;

    float getAsFloatAt(cpp::string_view path, size_t index) const;

    void setFloatAt(cpp::string_view path, size_t index, float value) const;

    virtual void getAsFloat64Array(cpp::string_view path, double* arrayOut, size_t arrayBufferLength) const = 0;

    virtual void setFloat64Array(cpp::string_view path, const cpp::span<const double> array) const = 0;

    virtual void getAsFloatArray(cpp::string_view path, float* arrayOut, size_t arrayBufferLength) const = 0;

    virtual void setFloatArray(cpp::string_view path, const cpp::span<const float> array) const = 0;

    virtual bool getAsBoolAt(cpp::string_view path, size_t index) const = 0;

    virtual void setBoolAt(cpp::string_view path, size_t index, bool value) const = 0;

    virtual void getAsBoolArray(cpp::string_view path, bool* arrayOut, size_t arrayBufferLength) const = 0;

    virtual void setBoolArray(cpp::string_view path, const cpp::span<const bool> array) const = 0;

    virtual cpp::optional<omni::string> createStringFromItemValueAt(cpp::string_view path, size_t index) const = 0;

    virtual cpp::optional<cpp::zstring_view> getStringViewAt(cpp::string_view path, size_t index) const = 0;

    virtual void setStringAt(cpp::string_view path, size_t index, cpp::string_view value) const = 0;

    virtual size_t getStringArray(cpp::string_view path, cpp::string_view* arrayOut, size_t arrayBufferLength) const = 0;

    virtual void setStringArray(cpp::string_view path, const cpp::span<const cpp::string_view> array) const = 0;

    template <typename SettingArrayType>
    void setArray(cpp::string_view path, const cpp::span<const SettingArrayType> array) const = delete;

    virtual Transaction* createTransaction() const = 0;

    virtual void destroyTransaction(Transaction* transaction) const = 0;

    virtual void commitTransaction(Transaction* transaction) const = 0;

    virtual void setInt64Async(Transaction* transaction, cpp::string_view path, int64_t value) const = 0;
    virtual void setFloat64Async(Transaction* transaction, cpp::string_view path, double value) const = 0;
    virtual void setBoolAsync(Transaction* transaction, cpp::string_view path, bool value) const = 0;
    virtual void setStringAsync(Transaction* transaction, cpp::string_view path, cpp::string_view value) const = 0;

    virtual dictionary::SubscriptionId* subscribeToNodeChangeEvents(cpp::string_view path,
                                                                    dictionary::OnNodeChangeEventFn onChangeEventFn,
                                                                    void* userData) const = 0;

    virtual dictionary::SubscriptionId* subscribeToTreeChangeEvents(cpp::string_view path,
                                                                    dictionary::OnTreeChangeEventFn onChangeEventFn,
                                                                    void* userData) const = 0;

    virtual void unsubscribeFromChangeEvents(dictionary::SubscriptionId* subscriptionId) const = 0;

    virtual void update(cpp::string_view path,
                        const dictionary::Item* dictionary,
                        cpp::string_view dictionaryPath,
                        dictionary::OnUpdateItemFn onUpdateItemFn,
                        void* userData) const = 0;

    virtual const dictionary::Item* getSettingsDictionary(cpp::string_view path) const = 0;

    virtual dictionary::Item* createDictionaryFromSettings(cpp::string_view path) const = 0;

    virtual void destroyItem(cpp::string_view path) const = 0;

    virtual void initializeFromDictionary(const dictionary::Item* dictionary) const = 0;

    void setDefaultInt64(cpp::string_view path, int64_t value) const;
    void setDefaultInt(cpp::string_view path, int32_t value) const;
    void setDefaultFloat64(cpp::string_view path, double value) const;
    void setDefaultFloat(cpp::string_view path, float value) const;
    void setDefaultBool(cpp::string_view path, bool value) const;
    void setDefaultString(cpp::string_view path, cpp::string_view value) const;

    template <typename SettingType, std::enable_if_t<!cpp::is_std_string_view_like_v<SettingType>, bool> = true>
    void setDefault(cpp::string_view path, SettingType value) const;

    void setDefault(cpp::string_view path, cpp::string_view value) const;

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

    void setDefaultInt64Array(cpp::string_view path, const cpp::span<const int64_t> array) const;
    void setDefaultIntArray(cpp::string_view path, const cpp::span<const int32_t> array) const;
    void setDefaultFloat64Array(cpp::string_view path, const cpp::span<const double> array) const;
    void setDefaultFloatArray(cpp::string_view path, const cpp::span<const float> array) const;
    void setDefaultBoolArray(cpp::string_view path, const cpp::span<const bool> array) const;
    void setDefaultStringArray(cpp::string_view path, const cpp::span<const cpp::string_view> array) const;

    template <typename SettingArrayType>
    void setDefaultArray(cpp::string_view path, const cpp::span<const SettingArrayType> array) const;
};

#include "ISettingsCommon.h"

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

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

inline float ISettings::getAsFloat(cpp::string_view path) const
{
    return (float)getAsFloat64(path);
}

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

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

inline float ISettings::getAsFloatAt(cpp::string_view path, size_t index) const
{
    return (float)getAsFloat64At(path, index);
}

inline void ISettings::setFloatAt(cpp::string_view path, size_t index, float value) const
{
    setFloat64At(path, index, (double)value);
}

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

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

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

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

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

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

#ifndef DOXYGEN_BUILD
template <>
inline bool ISettings::get<bool>(cpp::string_view path) const
{
    return getAsBool(path);
}

template <>
inline int32_t ISettings::get<int>(cpp::string_view path) const
{
    return getAsInt(path);
}

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

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

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

template <>
inline cpp::zstring_view ISettings::get<cpp::zstring_view>(cpp::string_view path) const
{
    return getStringView(path).value_or("");
}

template <>
inline std::string ISettings::get<std::string>(cpp::string_view path) const
{
    ScopedRead read(this);
    return std::string(getStringView(path).value_or(""));
}

template <>
inline omni::string ISettings::get<omni::string>(cpp::string_view path) const
{
    ScopedRead read(this);
    return omni::string(getStringView(path).value_or(""));
}

template <>
inline cpp::optional<bool> ISettings::getOpt<bool>(cpp::string_view path) const
{
    ScopedRead lock(this, getCachedInterface<dictionary::IDictionary>());
    if (getItemType(path) == dictionary::ItemType::eCount)
        return cpp::nullopt;
    return getAsBool(path);
}

template <>
inline cpp::optional<int32_t> ISettings::getOpt<int>(cpp::string_view path) const
{
    ScopedRead lock(this, getCachedInterface<dictionary::IDictionary>());
    if (getItemType(path) == dictionary::ItemType::eCount)
        return cpp::nullopt;
    return getAsInt(path);
}

template <>
inline cpp::optional<int64_t> ISettings::getOpt<int64_t>(cpp::string_view path) const
{
    ScopedRead lock(this, getCachedInterface<dictionary::IDictionary>());
    if (getItemType(path) == dictionary::ItemType::eCount)
        return cpp::nullopt;
    return getAsInt64(path);
}

template <>
inline cpp::optional<float> ISettings::getOpt<float>(cpp::string_view path) const
{
    ScopedRead lock(this, getCachedInterface<dictionary::IDictionary>());
    if (getItemType(path) == dictionary::ItemType::eCount)
        return cpp::nullopt;
    return getAsFloat(path);
}

template <>
inline cpp::optional<double> ISettings::getOpt<double>(cpp::string_view path) const
{
    ScopedRead lock(this, getCachedInterface<dictionary::IDictionary>());
    if (getItemType(path) == dictionary::ItemType::eCount)
        return cpp::nullopt;
    return getAsFloat64(path);
}

template <>
inline cpp::optional<cpp::zstring_view> ISettings::getOpt<cpp::zstring_view>(cpp::string_view path) const
{
    ScopedRead lock(this, getCachedInterface<dictionary::IDictionary>());
    if (auto val = getStringView(path))
        return *val;
    return cpp::nullopt;
}

template <>
inline cpp::optional<std::string> ISettings::getOpt<std::string>(cpp::string_view path) const
{
    ScopedRead lock(this);
    if (auto val = getStringView(path))
        return std::string(*val);
    return cpp::nullopt;
}

template <>
inline cpp::optional<omni::string> ISettings::getOpt<omni::string>(cpp::string_view path) const
{
    ScopedRead lock(this);
    if (auto val = getStringView(path))
        return omni::string(*val);
    return cpp::nullopt;
}

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

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

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

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

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

inline void ISettings::set(cpp::string_view path, cpp::string_view value) const
{
    setString(path, value);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const bool> array) const
{
    setBoolArray(path, array);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const int32_t> array) const
{
    setIntArray(path, array);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const int64_t> array) const
{
    setInt64Array(path, array);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const float> array) const
{
    setFloatArray(path, array);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const double> array) const
{
    setFloat64Array(path, array);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const cpp::string_view> array) const
{
    setStringArray(path, array);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const cpp::zstring_view> array) const
{
    static_assert(sizeof(cpp::zstring_view) == sizeof(cpp::string_view));
    setStringArray(path, *cpp::bit_cast<const cpp::span<const cpp::string_view>*>(&array));
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const std::string> array) const
{
    auto views = CARB_STACK_ALLOC(cpp::string_view, array.size());
    for (size_t i = 0; i != array.size(); ++i)
        new (&views[i]) cpp::string_view(array[i]);
    setStringArray(path, cpp::span<const cpp::string_view>(views, array.size()));
}

template <>
inline void ISettings::setArray(cpp::string_view path, const cpp::span<const omni::string> array) const
{
    auto views = CARB_STACK_ALLOC(cpp::string_view, array.size());
    for (size_t i = 0; i != array.size(); ++i)
        new (&views[i]) cpp::string_view(array[i]);
    setStringArray(path, cpp::span<const cpp::string_view>(views, array.size()));
}

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

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

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

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

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

inline void ISettings::setDefault(cpp::string_view path, cpp::string_view value) const
{
    setDefaultString(path, value);
}

template <typename SettingArrayType>
inline void ISettings::setDefaultArray(cpp::string_view settingsPath, const cpp::span<const SettingArrayType> array) const
{
    ScopedWrite writeLock;
    auto itemType = getItemType(settingsPath);
    if (itemType != dictionary::ItemType::eCount)
        return;
    if constexpr (std::is_same_v<SettingArrayType, bool>)
        setBoolArray(settingsPath, array);
    else if constexpr (std::is_same_v<SettingArrayType, int32_t>)
        setIntArray(settingsPath, array);
    else if constexpr (std::is_same_v<SettingArrayType, int64_t>)
        setInt64Array(settingsPath, array);
    else if constexpr (std::is_same_v<SettingArrayType, float>)
        setFloatArray(settingsPath, array);
    else if constexpr (std::is_same_v<SettingArrayType, double>)
        setFloat64Array(settingsPath, array);
    else if constexpr (std::is_same_v<SettingArrayType, cpp::string_view>)
        setStringArray(settingsPath, array);
    else if constexpr (std::is_convertible_v<SettingArrayType, cpp::string_view>)
    {
        auto val = CARB_STACK_ALLOC(cpp::string_view, array.size());
        for (size_t i = 0; i != array.size(); ++i)
            val[i] = cpp::string_view(array[i]);
        setStringArray(settingsPath, cpp::span<cpp::string_view>(val, array.size()));
    }
    else
    {
        static_assert(sizeof(SettingArrayType) == 0, "Unsupported type for setDefaultArray");
    }
}

template <>
inline void ISettings::setDefaultArray(cpp::string_view settingsPath, const cpp::span<const int32_t> array) const
{
    setDefaultIntArray(settingsPath, array);
}

template <>
inline void ISettings::setDefaultArray(cpp::string_view settingsPath, const cpp::span<const int64_t> array) const
{
    setDefaultInt64Array(settingsPath, array);
}

template <>
inline void ISettings::setDefaultArray(cpp::string_view settingsPath, const cpp::span<const float> array) const
{
    setDefaultFloatArray(settingsPath, array);
}

template <>
inline void ISettings::setDefaultArray(cpp::string_view settingsPath, const cpp::span<const double> array) const
{
    setDefaultFloat64Array(settingsPath, array);
}

template <>
inline void ISettings::setDefaultArray(cpp::string_view settingsPath, const cpp::span<const cpp::string_view> array) const
{
    setDefaultStringArray(settingsPath, array);
}
#endif

#ifndef DOXYGEN_BUILD
} // namespace v2
#endif

} // namespace carb::settings