IDictionary2.h#
Fully qualified name: carb/dictionary/detail/IDictionary2.h
File members: carb/dictionary/detail/IDictionary2.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_dictionary_IDictionary_latest
# error Must include via ../IDictionary.h
#endif
#if !CARB_VERSION_ATLEAST(carb_dictionary_IDictionary, 2, 0)
# error Version too low to be included
#endif
#include "../../../omni/String.h"
#include "../../cpp/Span.h"
namespace carb::dictionary
{
#ifndef DOXYGEN_BUILD
inline namespace v2
{
#endif
class IDictionary
{
public:
CARB_PLUGIN_INTERFACE_EX("carb::dictionary::IDictionary",
carb_dictionary_IDictionary_latest,
carb_dictionary_IDictionary)
virtual const Item* getItem(const Item* baseItem, cpp::string_view path) const = 0;
virtual Item* getItem(Item* baseItem, cpp::string_view path) const = 0;
virtual size_t getItemChildCount(const Item* item) const = 0;
virtual const Item* getItemChildByIndex(const Item* item, size_t childIndex) const = 0;
virtual Item* getItemChildByIndex(Item* item, size_t childIndex) const = 0;
virtual const Item* getItemParent(const Item* item) const = 0;
virtual Item* getItemParent(Item* item) const = 0;
virtual ItemType getItemType(const Item* item) const = 0;
virtual cpp::optional<omni::string> createStringFromItemName(const Item* item) const = 0;
virtual cpp::optional<cpp::zstring_view> getItemName(const Item* item) const = 0;
virtual Item* createItem(Item* baseItem, cpp::string_view path, ItemType itemType) const = 0;
virtual bool isAccessibleAs(ItemType itemType, const Item* item) const = 0;
virtual int64_t getAsInt64(const Item* item) const = 0;
virtual void setInt64(Item* item, int64_t value) const = 0;
virtual double getAsFloat64(const Item* item) const = 0;
virtual void setFloat64(Item* item, double value) const = 0;
virtual bool getAsBool(const Item* item) const = 0;
virtual void setBool(Item* item, bool value) const = 0;
virtual cpp::optional<omni::string> createStringFromItemValue(const Item* item) const = 0;
virtual cpp::optional<cpp::zstring_view> getStringView(const Item* item) const = 0;
virtual cpp::optional<omni::string> getString(const Item* item) const = 0;
virtual void setString(Item* item, cpp::string_view value) const = 0;
virtual bool isAccessibleAsArray(const Item* item) const = 0;
virtual bool isAccessibleAsArrayOf(ItemType itemType, const Item* item) const = 0;
virtual size_t getArrayLength(const Item* item) const = 0;
virtual ItemType getPreferredArrayType(const Item* item) const = 0;
virtual int64_t getAsInt64At(const Item* item, size_t index) const = 0;
virtual void setInt64At(Item* item, size_t index, int64_t value) const = 0;
virtual size_t getAsInt64Array(const Item* item, int64_t* arrayOut, size_t arrayBufferLength) const = 0;
virtual void setInt64Array(Item* item, const cpp::span<const int64_t> array) const = 0;
virtual size_t getAsIntArray(const Item* item, int32_t* arrayOut, size_t arrayBufferLength) const = 0;
virtual void setIntArray(Item* item, const cpp::span<const int32_t> array) const = 0;
virtual double getAsFloat64At(const Item* item, size_t index) const = 0;
virtual void setFloat64At(Item* item, size_t index, double value) const = 0;
virtual size_t getAsFloat64Array(const Item* item, double* arrayOut, size_t arrayBufferLength) const = 0;
virtual void setFloat64Array(Item* item, const cpp::span<const double> array) const = 0;
virtual size_t getAsFloatArray(const Item* item, float* arrayOut, size_t arrayBufferLength) const = 0;
virtual void setFloatArray(Item* item, const cpp::span<const float> array) const = 0;
virtual bool getAsBoolAt(const Item* item, size_t index) const = 0;
virtual void setBoolAt(Item* item, size_t index, bool value) const = 0;
virtual size_t getAsBoolArray(const Item* item, bool* arrayOut, size_t arrayBufferLength) const = 0;
virtual void setBoolArray(Item* item, const cpp::span<const bool> array) const = 0;
virtual cpp::optional<omni::string> createStringFromItemValueAt(const Item* item, size_t index) const = 0;
virtual cpp::optional<cpp::zstring_view> getStringViewAt(const Item* item, size_t index) const = 0;
virtual void setStringAt(Item* item, size_t index, cpp::string_view value) const = 0;
virtual size_t getStringArray(const Item* item, cpp::string_view* arrayOut, size_t arrayBufferLength) const = 0;
virtual void setStringArray(Item* item, const cpp::span<const cpp::string_view> array) const = 0;
virtual const Item* getItemAt(const Item* item, size_t index) const = 0;
virtual Item* getItemAt(Item* item, size_t index) const = 0;
virtual size_t getItemArray(const Item* item, const Item** arrayOut, size_t arrayBufferLength) const = 0;
virtual void update(Item* dstBaseItem,
cpp::string_view dstPath,
const Item* srcBaseItem,
cpp::string_view srcPath,
OnUpdateItemFn onUpdateItemFn,
void* userData) const = 0;
virtual void destroyItem(Item* item) const = 0;
virtual bool getItemFlag(const Item* item, ItemFlag flag) const = 0;
virtual void setItemFlag(Item* item, ItemFlag flag, bool flagValue) const = 0;
virtual SubscriptionId* subscribeToNodeChangeEvents(Item* baseItem,
cpp::string_view path,
OnNodeChangeEventFn onChangeEventFn,
void* userData) const = 0;
virtual SubscriptionId* subscribeToTreeChangeEvents(Item* baseItem,
cpp::string_view path,
OnTreeChangeEventFn onChangeEventFn,
void* userData) const = 0;
virtual void unsubscribeFromChangeEvents(SubscriptionId* subscriptionId) const = 0;
virtual void unsubscribeItemFromNodeChangeEvents(Item* item) const = 0;
virtual void unsubscribeItemFromTreeChangeEvents(Item* item) const = 0;
virtual void readLock(const Item* item) const = 0;
virtual void writeLock(Item* item) const = 0;
virtual void unlock(const Item* item) const = 0;
virtual const extras::hash128_t getHash(const Item* item) const = 0;
virtual int lexicographicalCompare(const Item* itemA, const Item* itemB) const = 0;
// ^ Interface functions
// v Helper functions
int32_t getAsInt(const Item* item) const;
void setInt(Item* item, int32_t value) const;
Item* makeInt64AtPath(Item* baseItem, cpp::string_view path, int64_t value) const;
Item* makeIntAtPath(Item* baseItem, cpp::string_view path, int32_t value) const;
float getAsFloat(const Item* item) const;
void setFloat(Item* item, float value) const;
Item* makeFloat64AtPath(Item* baseItem, cpp::string_view path, double value) const;
Item* makeFloatAtPath(Item* baseItem, cpp::string_view path, float value) const;
Item* makeBoolAtPath(Item* baseItem, cpp::string_view path, bool value) const;
Item* makeStringAtPath(Item* baseItem, cpp::string_view path, cpp::string_view value) const;
Item* makeDictionaryAtPath(Item* parentItem, cpp::string_view path) const;
template <typename T>
T get(const Item* item) const = delete;
template <typename T, typename U = T>
T get(const Item* baseItem, cpp::string_view path, U&& defaultValue = T{}) const;
template <typename T>
cpp::optional<T> getOpt(const Item* baseItem, cpp::string_view path) const;
template <typename T, std::enable_if_t<!carb::cpp::is_std_string_view_like_v<T>, bool> = true>
Item* makeAtPath(Item* baseItem, cpp::string_view path, T value) const;
Item* makeAtPath(Item* baseItem, cpp::string_view path, cpp::string_view value) const;
int32_t getAsIntAt(const Item* item, size_t index) const;
void setIntAt(Item* item, size_t index, int32_t value) const;
float getAsFloatAt(const Item* item, size_t index) const;
void setFloatAt(Item* item, size_t index, float value) const;
template <typename ArrayElementType>
void setArray(Item* item, const cpp::span<const ArrayElementType> array) const = delete;
void deleteChildren(Item* item) const;
void copyItemFlags(Item* dstItem, const Item* srcItem) const;
Item* duplicateItem(const Item* item) const
{
return duplicateItem(item, nullptr, {});
}
virtual Item* duplicateItem(const Item* item, Item* newParent, cpp::string_view newKey) const = 0;
};
#define CARBLOCAL_CONST const
#include "IDictionaryCommon.h"
#undef CARBLOCAL_CONST
inline Item* IDictionary::makeIntAtPath(Item* baseItem, cpp::string_view path, int32_t value) const
{
return makeInt64AtPath(baseItem, path, value);
}
inline Item* IDictionary::makeFloatAtPath(Item* baseItem, cpp::string_view path, float value) const
{
return makeFloat64AtPath(baseItem, path, value);
}
inline Item* IDictionary::makeInt64AtPath(Item* parentItem, cpp::string_view path, int64_t value) const
{
ScopedWrite g(*this, parentItem);
Item* item = getItem(parentItem, path);
if (!item)
{
item = createItem(parentItem, path, ItemType::eInt);
}
setInt64(item, value);
return item;
}
inline Item* IDictionary::makeFloat64AtPath(Item* parentItem, cpp::string_view path, double value) const
{
ScopedWrite g(*this, parentItem);
Item* item = getItem(parentItem, path);
if (!item)
{
item = createItem(parentItem, path, ItemType::eFloat);
}
setFloat64(item, value);
return item;
}
inline Item* IDictionary::makeBoolAtPath(Item* parentItem, cpp::string_view path, bool value) const
{
ScopedWrite g(*this, parentItem);
Item* item = getItem(parentItem, path);
if (!item)
{
item = createItem(parentItem, path, ItemType::eBool);
}
setBool(item, value);
return item;
}
inline Item* IDictionary::makeStringAtPath(Item* parentItem, cpp::string_view path, cpp::string_view value) const
{
ScopedWrite g(*this, parentItem);
Item* item = getItem(parentItem, path);
if (!item)
{
item = createItem(parentItem, path, ItemType::eString);
}
setString(item, value);
return item;
}
inline Item* IDictionary::makeDictionaryAtPath(Item* parentItem, cpp::string_view path) const
{
ScopedWrite g(*this, parentItem);
Item* item = getItem(parentItem, path);
if (!item)
{
item = createItem(parentItem, path, ItemType::eDictionary);
return item;
}
ItemType itemType = getItemType(item);
if (itemType != ItemType::eDictionary)
{
// Bit of a hack to change to a dictionary without deleting the node
setBoolArray(item, {});
CARB_ASSERT(getItemType(item) == ItemType::eDictionary);
}
return item;
}
#ifndef DOXYGEN_BUILD
template <>
inline cpp::optional<cpp::zstring_view> IDictionary::get<cpp::optional<cpp::zstring_view>>(const Item* item) const
{
return getStringView(item);
}
template <>
inline cpp::zstring_view IDictionary::get<cpp::zstring_view>(const Item* item) const
{
return getStringView(item).value_or("");
}
template <>
inline std::string IDictionary::get<std::string>(const Item* item) const
{
ScopedRead read(*this, item);
return std::string(getStringView(item).value_or(""));
}
template <>
inline cpp::optional<std::string> IDictionary::get<cpp::optional<std::string>>(const Item* item) const
{
ScopedRead lock(*this, item);
if (auto buf = getStringView(item))
return std::string(*buf);
return cpp::nullopt;
}
template <>
inline omni::string IDictionary::get<omni::string>(const Item* item) const
{
return getString(item).value_or("");
}
template <>
inline cpp::optional<omni::string> IDictionary::get<cpp::optional<omni::string>>(const Item* item) const
{
return getString(item);
}
template <class T, class U>
inline T IDictionary::get(const Item* baseItem, cpp::string_view path, U&& defaultValue) const
{
ScopedRead read(*this, baseItem);
if (auto item = getItem(baseItem, path))
return get<T>(item);
return T(std::forward<U>(defaultValue));
}
template <class T>
inline cpp::optional<T> IDictionary::getOpt(const Item* baseItem, cpp::string_view path) const
{
ScopedRead read(*this, baseItem);
if (auto item = getItem(baseItem, path))
return get<T>(item);
return cpp::nullopt;
}
template <>
inline Item* IDictionary::makeAtPath<int32_t, true>(Item* baseItem, cpp::string_view path, int32_t value) const
{
return makeIntAtPath(baseItem, path, value);
}
template <>
inline Item* IDictionary::makeAtPath<int64_t, true>(Item* baseItem, cpp::string_view path, int64_t value) const
{
return makeInt64AtPath(baseItem, path, value);
}
template <>
inline Item* IDictionary::makeAtPath<float, true>(Item* baseItem, cpp::string_view path, float value) const
{
return makeFloatAtPath(baseItem, path, value);
}
template <>
inline Item* IDictionary::makeAtPath<double, true>(Item* baseItem, cpp::string_view path, double value) const
{
return makeFloat64AtPath(baseItem, path, value);
}
template <>
inline Item* IDictionary::makeAtPath<bool, true>(Item* baseItem, cpp::string_view path, bool value) const
{
return makeBoolAtPath(baseItem, path, value);
}
template <>
inline Item* IDictionary::makeAtPath<Int2, true>(Item* baseItem, cpp::string_view path, Int2 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const int32_t array[] = { value.x, value.y };
setIntArray(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Int3, true>(Item* baseItem, cpp::string_view path, Int3 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const int32_t array[] = { value.x, value.y, value.z };
setIntArray(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Int4, true>(Item* baseItem, cpp::string_view path, Int4 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const int32_t array[] = { value.x, value.y, value.z, value.w };
setIntArray(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Uint2, true>(Item* baseItem, cpp::string_view path, Uint2 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const int64_t array[] = { value.x, value.y };
setInt64Array(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Uint3, true>(Item* baseItem, cpp::string_view path, Uint3 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const int64_t array[] = { value.x, value.y, value.z };
setInt64Array(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Uint4, true>(Item* baseItem, cpp::string_view path, Uint4 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const int64_t array[] = { value.x, value.y, value.z, value.w };
setInt64Array(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Float2, true>(Item* baseItem, cpp::string_view path, Float2 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const float array[] = { value.x, value.y };
setFloatArray(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Float3, true>(Item* baseItem, cpp::string_view path, Float3 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const float array[] = { value.x, value.y, value.z };
setFloatArray(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Float4, true>(Item* baseItem, cpp::string_view path, Float4 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const float array[] = { value.x, value.y, value.z, value.w };
setFloatArray(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Double2, true>(Item* baseItem, cpp::string_view path, Double2 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const double array[] = { value.x, value.y };
setFloat64Array(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Double3, true>(Item* baseItem, cpp::string_view path, Double3 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const double array[] = { value.x, value.y, value.z };
setFloat64Array(item, cpp::span(array));
return item;
}
template <>
inline Item* IDictionary::makeAtPath<Double4, true>(Item* baseItem, cpp::string_view path, Double4 value) const
{
Item* item = baseItem;
if (!path.empty())
{
item = makeDictionaryAtPath(baseItem, path);
}
const double array[] = { value.x, value.y, value.z, value.w };
setFloat64Array(item, cpp::span(array));
return item;
}
inline Item* IDictionary::makeAtPath(Item* baseItem, cpp::string_view path, cpp::string_view value) const
{
return makeStringAtPath(baseItem, path, value);
}
template <>
inline void IDictionary::setArray(Item* baseItem, const cpp::span<const bool> array) const
{
return setBoolArray(baseItem, array);
}
template <>
inline void IDictionary::setArray(Item* baseItem, const cpp::span<const int32_t> array) const
{
return setIntArray(baseItem, array);
}
template <>
inline void IDictionary::setArray(Item* baseItem, const cpp::span<const int64_t> array) const
{
return setInt64Array(baseItem, array);
}
template <>
inline void IDictionary::setArray(Item* baseItem, const cpp::span<const float> array) const
{
return setFloatArray(baseItem, array);
}
template <>
inline void IDictionary::setArray(Item* baseItem, const cpp::span<const double> array) const
{
return setFloat64Array(baseItem, array);
}
template <>
inline void IDictionary::setArray(Item* baseItem, const cpp::span<const cpp::string_view> array) const
{
setStringArray(baseItem, array);
}
inline void IDictionary::deleteChildren(Item* item) const
{
ScopedWrite g(*this, item);
size_t childCount = getItemChildCount(item);
while (childCount != 0)
destroyItem(getItemChildByIndex(item, --childCount));
}
#endif // DOXYGEN_BUILD
#ifndef DOXYGEN_BUILD
} // namespace v2
#endif
} // namespace carb::dictionary