From 36ec636fa5b86ca8c270d5b6a3c1a057bcfe1fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Fazekas?= Date: Tue, 23 Dec 2025 16:20:19 +0100 Subject: [PATCH] feat: add properties enumeration to ViewModel and ViewModelInstance Adds `properties` array to both ViewModel and ViewModelInstance for runtime introspection of available properties with their names and types. New types: - ViewModelPropertyType: union of all property types - ViewModelPropertyInfo: { name, type } metadata Includes PropertyInspector example for debugging. --- .../com/margelo/nitro/rive/HybridViewModel.kt | 26 ++++ .../nitro/rive/HybridViewModelInstance.kt | 4 + example/src/pages/PropertyInspector.tsx | 128 ++++++++++++++++++ example/src/pages/index.ts | 1 + ios/HybridViewModel.swift | 40 +++++- ios/HybridViewModelInstance.swift | 12 +- .../c++/JHybridViewModelInstanceSpec.cpp | 23 ++++ .../c++/JHybridViewModelInstanceSpec.hpp | 1 + .../android/c++/JHybridViewModelSpec.cpp | 23 ++++ .../android/c++/JHybridViewModelSpec.hpp | 1 + .../android/c++/JViewModelPropertyInfo.hpp | 63 +++++++++ .../android/c++/JViewModelPropertyType.hpp | 98 ++++++++++++++ .../nitro/rive/HybridViewModelInstanceSpec.kt | 4 + .../margelo/nitro/rive/HybridViewModelSpec.kt | 4 + .../nitro/rive/ViewModelPropertyInfo.kt | 41 ++++++ .../nitro/rive/ViewModelPropertyType.kt | 34 +++++ .../generated/ios/RNRive-Swift-Cxx-Bridge.hpp | 18 +++ .../ios/RNRive-Swift-Cxx-Umbrella.hpp | 7 + .../c++/HybridViewModelInstanceSpecSwift.hpp | 11 ++ .../ios/c++/HybridViewModelSpecSwift.hpp | 11 ++ .../swift/HybridViewModelInstanceSpec.swift | 1 + .../HybridViewModelInstanceSpec_cxx.swift | 13 ++ .../ios/swift/HybridViewModelSpec.swift | 1 + .../ios/swift/HybridViewModelSpec_cxx.swift | 13 ++ .../ios/swift/ViewModelPropertyInfo.swift | 47 +++++++ .../ios/swift/ViewModelPropertyType.swift | 92 +++++++++++++ .../c++/HybridViewModelInstanceSpec.cpp | 1 + .../c++/HybridViewModelInstanceSpec.hpp | 5 + .../shared/c++/HybridViewModelSpec.cpp | 1 + .../shared/c++/HybridViewModelSpec.hpp | 5 + .../shared/c++/ViewModelPropertyInfo.hpp | 81 +++++++++++ .../shared/c++/ViewModelPropertyType.hpp | 128 ++++++++++++++++++ src/index.tsx | 2 + src/specs/ViewModel.nitro.ts | 35 +++++ 34 files changed, 971 insertions(+), 4 deletions(-) create mode 100644 example/src/pages/PropertyInspector.tsx create mode 100644 nitrogen/generated/android/c++/JViewModelPropertyInfo.hpp create mode 100644 nitrogen/generated/android/c++/JViewModelPropertyType.hpp create mode 100644 nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ViewModelPropertyInfo.kt create mode 100644 nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ViewModelPropertyType.kt create mode 100644 nitrogen/generated/ios/swift/ViewModelPropertyInfo.swift create mode 100644 nitrogen/generated/ios/swift/ViewModelPropertyType.swift create mode 100644 nitrogen/generated/shared/c++/ViewModelPropertyInfo.hpp create mode 100644 nitrogen/generated/shared/c++/ViewModelPropertyType.hpp diff --git a/android/src/main/java/com/margelo/nitro/rive/HybridViewModel.kt b/android/src/main/java/com/margelo/nitro/rive/HybridViewModel.kt index a085233f..015a0b11 100644 --- a/android/src/main/java/com/margelo/nitro/rive/HybridViewModel.kt +++ b/android/src/main/java/com/margelo/nitro/rive/HybridViewModel.kt @@ -15,6 +15,14 @@ class HybridViewModel(private val viewModel: ViewModel) : HybridViewModelSpec() override val modelName: String get() = viewModel.name + override val properties: Array + get() { + val mapped = viewModel.properties.map { prop -> + ViewModelPropertyInfo(name = prop.name, type = mapPropertyType(prop.type)) + } + return mapped.toTypedArray() + } + override fun createInstanceByIndex(index: Double): HybridViewModelInstanceSpec? { try { val vmi = viewModel.createInstanceFromIndex(index.toInt()) @@ -50,4 +58,22 @@ class HybridViewModel(private val viewModel: ViewModel) : HybridViewModelSpec() return null } } + + companion object { + fun mapPropertyType(type: ViewModel.PropertyDataType): ViewModelPropertyType = when (type) { + ViewModel.PropertyDataType.NONE -> ViewModelPropertyType.NONE + ViewModel.PropertyDataType.STRING -> ViewModelPropertyType.STRING + ViewModel.PropertyDataType.NUMBER -> ViewModelPropertyType.NUMBER + ViewModel.PropertyDataType.BOOLEAN -> ViewModelPropertyType.BOOLEAN + ViewModel.PropertyDataType.COLOR -> ViewModelPropertyType.COLOR + ViewModel.PropertyDataType.LIST -> ViewModelPropertyType.LIST + ViewModel.PropertyDataType.ENUM -> ViewModelPropertyType.ENUM + ViewModel.PropertyDataType.TRIGGER -> ViewModelPropertyType.TRIGGER + ViewModel.PropertyDataType.VIEW_MODEL -> ViewModelPropertyType.VIEWMODEL + ViewModel.PropertyDataType.INTEGER -> ViewModelPropertyType.INTEGER + ViewModel.PropertyDataType.SYMBOL_LIST_INDEX -> ViewModelPropertyType.SYMBOLLISTINDEX + ViewModel.PropertyDataType.ASSET_IMAGE -> ViewModelPropertyType.ASSETIMAGE + ViewModel.PropertyDataType.ARTBOARD -> ViewModelPropertyType.ARTBOARD + } + } } diff --git a/android/src/main/java/com/margelo/nitro/rive/HybridViewModelInstance.kt b/android/src/main/java/com/margelo/nitro/rive/HybridViewModelInstance.kt index 0ba683c7..8ac014d3 100644 --- a/android/src/main/java/com/margelo/nitro/rive/HybridViewModelInstance.kt +++ b/android/src/main/java/com/margelo/nitro/rive/HybridViewModelInstance.kt @@ -11,6 +11,10 @@ class HybridViewModelInstance(val viewModelInstance: ViewModelInstance) : Hybrid override val instanceName: String get() = viewModelInstance.name + // Note: Android SDK doesn't expose ViewModelInstance.properties publicly + override val properties: Array + get() = emptyArray() + // Returns null if ViewModelException is thrown for iOS parity // (iOS SDK returns nil when property not found, Android SDK throws) private inline fun getPropertyOrNull(block: () -> T): T? { diff --git a/example/src/pages/PropertyInspector.tsx b/example/src/pages/PropertyInspector.tsx new file mode 100644 index 00000000..979a3de3 --- /dev/null +++ b/example/src/pages/PropertyInspector.tsx @@ -0,0 +1,128 @@ +import { View, Text, StyleSheet, ScrollView } from 'react-native'; +import { + useRiveFile, + useViewModelInstance, + type ViewModelPropertyInfo, + type ViewModel, +} from '@rive-app/react-native'; +import { useMemo } from 'react'; +import type { Metadata } from '../helpers/metadata'; + +function PropertyList({ properties }: { properties: ViewModelPropertyInfo[] }) { + if (properties.length === 0) { + return No properties found; + } + return ( + + {properties.map((prop, index) => ( + + {prop.name} + {prop.type} + + ))} + + ); +} + +export default function PropertyInspector() { + const { riveFile } = useRiveFile( + require('../../assets/rive/quick_start.riv') + ); + + const viewModel: ViewModel | undefined = useMemo( + () => riveFile?.defaultArtboardViewModel(), + [riveFile] + ); + const viewModelInstance = useViewModelInstance(riveFile); + + return ( + + ViewModel Inspector + + + ViewModel Info + Name: {viewModel?.modelName ?? 'N/A'} + + Property Count: {viewModel?.propertyCount ?? 0} + + + Instance Count: {viewModel?.instanceCount ?? 0} + + + + + ViewModel Properties + + + + + + Instance Properties ({viewModelInstance?.instanceName}) + + + + + ); +} + +PropertyInspector.metadata = { + name: 'Property Inspector', + description: + 'Debug tool to inspect ViewModel and ViewModelInstance properties', +} satisfies Metadata; + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#1a1a2e', + }, + title: { + fontSize: 24, + fontWeight: 'bold', + color: '#fff', + textAlign: 'center', + marginVertical: 20, + }, + section: { + backgroundColor: '#16213e', + margin: 10, + padding: 15, + borderRadius: 10, + }, + sectionTitle: { + fontSize: 18, + fontWeight: 'bold', + color: '#e94560', + marginBottom: 10, + }, + info: { + fontSize: 14, + color: '#fff', + marginBottom: 5, + }, + propertyList: { + marginTop: 5, + }, + propertyRow: { + flexDirection: 'row', + justifyContent: 'space-between', + paddingVertical: 8, + borderBottomWidth: 1, + borderBottomColor: '#0f3460', + }, + propertyName: { + fontSize: 14, + color: '#fff', + fontWeight: '500', + }, + propertyType: { + fontSize: 14, + color: '#e94560', + fontFamily: 'monospace', + }, + emptyText: { + fontSize: 14, + color: '#666', + fontStyle: 'italic', + }, +}); diff --git a/example/src/pages/index.ts b/example/src/pages/index.ts index e5906d76..e5c0925c 100644 --- a/example/src/pages/index.ts +++ b/example/src/pages/index.ts @@ -11,3 +11,4 @@ export { default as ManyViewModels } from './ManyViewModels'; export { default as ResponsiveLayouts } from './ResponsiveLayouts'; export { default as SharedValueListenerExample } from './SharedValueListenerExample'; export { default as MenuListExample } from './MenuListExample'; +export { default as PropertyInspector } from './PropertyInspector'; diff --git a/ios/HybridViewModel.swift b/ios/HybridViewModel.swift index 6b0a0ad2..51f4e03c 100644 --- a/ios/HybridViewModel.swift +++ b/ios/HybridViewModel.swift @@ -1,17 +1,51 @@ import RiveRuntime +extension ViewModelPropertyType { + init(from type: RiveDataBindingViewModel.Instance.Property.Data.DataType) { + switch type { + case .none: self = .none + case .string: self = .string + case .number: self = .number + case .boolean: self = .boolean + case .color: self = .color + case .list: self = .list + case .enum: self = .enum + case .trigger: self = .trigger + case .viewModel: self = .viewmodel + case .integer: self = .integer + case .symbolListIndex: self = .symbollistindex + case .assetImage: self = .assetimage + case .artboard: self = .artboard + case .input: self = .input + case .any: self = .any + @unknown default: self = .none + } + } +} + class HybridViewModel: HybridViewModelSpec { let viewModel: RiveDataBindingViewModel? - + init(viewModel: RiveDataBindingViewModel) { self.viewModel = viewModel } var propertyCount: Double { Double(viewModel?.propertyCount ?? 0) } - + var instanceCount: Double { Double(viewModel?.instanceCount ?? 0) } - + var modelName: String { viewModel?.name ?? "" } + + var properties: [ViewModelPropertyInfo] { + guard let vm = viewModel else { return [] } + return vm.properties.map { prop in + ViewModelPropertyInfo( + name: prop.name, + type: ViewModelPropertyType(from: prop.type) + ) + } + } + func createInstanceByIndex(index: Double) throws -> (any HybridViewModelInstanceSpec)? { guard let viewModel = viewModel, diff --git a/ios/HybridViewModelInstance.swift b/ios/HybridViewModelInstance.swift index 001657b3..33b440e2 100644 --- a/ios/HybridViewModelInstance.swift +++ b/ios/HybridViewModelInstance.swift @@ -2,12 +2,22 @@ import RiveRuntime class HybridViewModelInstance: HybridViewModelInstanceSpec { let viewModelInstance: RiveDataBindingViewModel.Instance? - + init(viewModelInstance: RiveDataBindingViewModel.Instance) { self.viewModelInstance = viewModelInstance } var instanceName: String { viewModelInstance?.name ?? "" } + + var properties: [ViewModelPropertyInfo] { + guard let instance = viewModelInstance else { return [] } + return instance.properties.map { prop in + ViewModelPropertyInfo( + name: prop.name, + type: ViewModelPropertyType(from: prop.type) + ) + } + } func numberProperty(path: String) throws -> (any HybridViewModelNumberPropertySpec)? { guard let property = viewModelInstance?.numberProperty(fromPath: path) else { return nil } diff --git a/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.cpp b/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.cpp index 741cb4a2..080860aa 100644 --- a/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.cpp +++ b/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.cpp @@ -7,6 +7,10 @@ #include "JHybridViewModelInstanceSpec.hpp" +// Forward declaration of `ViewModelPropertyInfo` to properly resolve imports. +namespace margelo::nitro::rive { struct ViewModelPropertyInfo; } +// Forward declaration of `ViewModelPropertyType` to properly resolve imports. +namespace margelo::nitro::rive { enum class ViewModelPropertyType; } // Forward declaration of `HybridViewModelNumberPropertySpec` to properly resolve imports. namespace margelo::nitro::rive { class HybridViewModelNumberPropertySpec; } // Forward declaration of `HybridViewModelStringPropertySpec` to properly resolve imports. @@ -25,6 +29,11 @@ namespace margelo::nitro::rive { class HybridViewModelImagePropertySpec; } namespace margelo::nitro::rive { class HybridViewModelListPropertySpec; } #include +#include "ViewModelPropertyInfo.hpp" +#include +#include "JViewModelPropertyInfo.hpp" +#include "ViewModelPropertyType.hpp" +#include "JViewModelPropertyType.hpp" #include #include "HybridViewModelNumberPropertySpec.hpp" #include @@ -78,6 +87,20 @@ namespace margelo::nitro::rive { auto __result = method(_javaPart); return __result->toStdString(); } + std::vector JHybridViewModelInstanceSpec::getProperties() { + static const auto method = javaClassStatic()->getMethod>()>("getProperties"); + auto __result = method(_javaPart); + return [&]() { + size_t __size = __result->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __result->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(); + } // Methods std::optional> JHybridViewModelInstanceSpec::numberProperty(const std::string& path) { diff --git a/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.hpp b/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.hpp index 8f5f8c2c..8ff0fdce 100644 --- a/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.hpp +++ b/nitrogen/generated/android/c++/JHybridViewModelInstanceSpec.hpp @@ -51,6 +51,7 @@ namespace margelo::nitro::rive { public: // Properties std::string getInstanceName() override; + std::vector getProperties() override; public: // Methods diff --git a/nitrogen/generated/android/c++/JHybridViewModelSpec.cpp b/nitrogen/generated/android/c++/JHybridViewModelSpec.cpp index 4693d29e..8df79eba 100644 --- a/nitrogen/generated/android/c++/JHybridViewModelSpec.cpp +++ b/nitrogen/generated/android/c++/JHybridViewModelSpec.cpp @@ -7,10 +7,19 @@ #include "JHybridViewModelSpec.hpp" +// Forward declaration of `ViewModelPropertyInfo` to properly resolve imports. +namespace margelo::nitro::rive { struct ViewModelPropertyInfo; } +// Forward declaration of `ViewModelPropertyType` to properly resolve imports. +namespace margelo::nitro::rive { enum class ViewModelPropertyType; } // Forward declaration of `HybridViewModelInstanceSpec` to properly resolve imports. namespace margelo::nitro::rive { class HybridViewModelInstanceSpec; } #include +#include "ViewModelPropertyInfo.hpp" +#include +#include "JViewModelPropertyInfo.hpp" +#include "ViewModelPropertyType.hpp" +#include "JViewModelPropertyType.hpp" #include #include "HybridViewModelInstanceSpec.hpp" #include @@ -60,6 +69,20 @@ namespace margelo::nitro::rive { auto __result = method(_javaPart); return __result->toStdString(); } + std::vector JHybridViewModelSpec::getProperties() { + static const auto method = javaClassStatic()->getMethod>()>("getProperties"); + auto __result = method(_javaPart); + return [&]() { + size_t __size = __result->size(); + std::vector __vector; + __vector.reserve(__size); + for (size_t __i = 0; __i < __size; __i++) { + auto __element = __result->getElement(__i); + __vector.push_back(__element->toCpp()); + } + return __vector; + }(); + } // Methods std::optional> JHybridViewModelSpec::createInstanceByIndex(double index) { diff --git a/nitrogen/generated/android/c++/JHybridViewModelSpec.hpp b/nitrogen/generated/android/c++/JHybridViewModelSpec.hpp index 47a361cb..ae0da877 100644 --- a/nitrogen/generated/android/c++/JHybridViewModelSpec.hpp +++ b/nitrogen/generated/android/c++/JHybridViewModelSpec.hpp @@ -53,6 +53,7 @@ namespace margelo::nitro::rive { double getPropertyCount() override; double getInstanceCount() override; std::string getModelName() override; + std::vector getProperties() override; public: // Methods diff --git a/nitrogen/generated/android/c++/JViewModelPropertyInfo.hpp b/nitrogen/generated/android/c++/JViewModelPropertyInfo.hpp new file mode 100644 index 00000000..5b165fe5 --- /dev/null +++ b/nitrogen/generated/android/c++/JViewModelPropertyInfo.hpp @@ -0,0 +1,63 @@ +/// +/// JViewModelPropertyInfo.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "ViewModelPropertyInfo.hpp" + +#include "JViewModelPropertyType.hpp" +#include "ViewModelPropertyType.hpp" +#include + +namespace margelo::nitro::rive { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ struct "ViewModelPropertyInfo" and the the Kotlin data class "ViewModelPropertyInfo". + */ + struct JViewModelPropertyInfo final: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/rive/ViewModelPropertyInfo;"; + + public: + /** + * Convert this Java/Kotlin-based struct to the C++ struct ViewModelPropertyInfo by copying all values to C++. + */ + [[maybe_unused]] + [[nodiscard]] + ViewModelPropertyInfo toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldName = clazz->getField("name"); + jni::local_ref name = this->getFieldValue(fieldName); + static const auto fieldType = clazz->getField("type"); + jni::local_ref type = this->getFieldValue(fieldType); + return ViewModelPropertyInfo( + name->toStdString(), + type->toCpp() + ); + } + + public: + /** + * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java. + */ + [[maybe_unused]] + static jni::local_ref fromCpp(const ViewModelPropertyInfo& value) { + using JSignature = JViewModelPropertyInfo(jni::alias_ref, jni::alias_ref); + static const auto clazz = javaClassStatic(); + static const auto create = clazz->getStaticMethod("fromCpp"); + return create( + clazz, + jni::make_jstring(value.name), + JViewModelPropertyType::fromCpp(value.type) + ); + } + }; + +} // namespace margelo::nitro::rive diff --git a/nitrogen/generated/android/c++/JViewModelPropertyType.hpp b/nitrogen/generated/android/c++/JViewModelPropertyType.hpp new file mode 100644 index 00000000..f56e9cc8 --- /dev/null +++ b/nitrogen/generated/android/c++/JViewModelPropertyType.hpp @@ -0,0 +1,98 @@ +/// +/// JViewModelPropertyType.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#include +#include "ViewModelPropertyType.hpp" + +namespace margelo::nitro::rive { + + using namespace facebook; + + /** + * The C++ JNI bridge between the C++ enum "ViewModelPropertyType" and the the Kotlin enum "ViewModelPropertyType". + */ + struct JViewModelPropertyType final: public jni::JavaClass { + public: + static auto constexpr kJavaDescriptor = "Lcom/margelo/nitro/rive/ViewModelPropertyType;"; + + public: + /** + * Convert this Java/Kotlin-based enum to the C++ enum ViewModelPropertyType. + */ + [[maybe_unused]] + [[nodiscard]] + ViewModelPropertyType toCpp() const { + static const auto clazz = javaClassStatic(); + static const auto fieldOrdinal = clazz->getField("value"); + int ordinal = this->getFieldValue(fieldOrdinal); + return static_cast(ordinal); + } + + public: + /** + * Create a Java/Kotlin-based enum with the given C++ enum's value. + */ + [[maybe_unused]] + static jni::alias_ref fromCpp(ViewModelPropertyType value) { + static const auto clazz = javaClassStatic(); + static const auto fieldSTRING = clazz->getStaticField("STRING"); + static const auto fieldNUMBER = clazz->getStaticField("NUMBER"); + static const auto fieldBOOLEAN = clazz->getStaticField("BOOLEAN"); + static const auto fieldNONE = clazz->getStaticField("NONE"); + static const auto fieldCOLOR = clazz->getStaticField("COLOR"); + static const auto fieldLIST = clazz->getStaticField("LIST"); + static const auto fieldENUM = clazz->getStaticField("ENUM"); + static const auto fieldTRIGGER = clazz->getStaticField("TRIGGER"); + static const auto fieldVIEWMODEL = clazz->getStaticField("VIEWMODEL"); + static const auto fieldINTEGER = clazz->getStaticField("INTEGER"); + static const auto fieldSYMBOLLISTINDEX = clazz->getStaticField("SYMBOLLISTINDEX"); + static const auto fieldASSETIMAGE = clazz->getStaticField("ASSETIMAGE"); + static const auto fieldARTBOARD = clazz->getStaticField("ARTBOARD"); + static const auto fieldINPUT = clazz->getStaticField("INPUT"); + static const auto fieldANY = clazz->getStaticField("ANY"); + + switch (value) { + case ViewModelPropertyType::STRING: + return clazz->getStaticFieldValue(fieldSTRING); + case ViewModelPropertyType::NUMBER: + return clazz->getStaticFieldValue(fieldNUMBER); + case ViewModelPropertyType::BOOLEAN: + return clazz->getStaticFieldValue(fieldBOOLEAN); + case ViewModelPropertyType::NONE: + return clazz->getStaticFieldValue(fieldNONE); + case ViewModelPropertyType::COLOR: + return clazz->getStaticFieldValue(fieldCOLOR); + case ViewModelPropertyType::LIST: + return clazz->getStaticFieldValue(fieldLIST); + case ViewModelPropertyType::ENUM: + return clazz->getStaticFieldValue(fieldENUM); + case ViewModelPropertyType::TRIGGER: + return clazz->getStaticFieldValue(fieldTRIGGER); + case ViewModelPropertyType::VIEWMODEL: + return clazz->getStaticFieldValue(fieldVIEWMODEL); + case ViewModelPropertyType::INTEGER: + return clazz->getStaticFieldValue(fieldINTEGER); + case ViewModelPropertyType::SYMBOLLISTINDEX: + return clazz->getStaticFieldValue(fieldSYMBOLLISTINDEX); + case ViewModelPropertyType::ASSETIMAGE: + return clazz->getStaticFieldValue(fieldASSETIMAGE); + case ViewModelPropertyType::ARTBOARD: + return clazz->getStaticFieldValue(fieldARTBOARD); + case ViewModelPropertyType::INPUT: + return clazz->getStaticFieldValue(fieldINPUT); + case ViewModelPropertyType::ANY: + return clazz->getStaticFieldValue(fieldANY); + default: + std::string stringValue = std::to_string(static_cast(value)); + throw std::invalid_argument("Invalid enum value (" + stringValue + "!"); + } + } + }; + +} // namespace margelo::nitro::rive diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelInstanceSpec.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelInstanceSpec.kt index af6de3f6..361894b9 100644 --- a/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelInstanceSpec.kt +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelInstanceSpec.kt @@ -45,6 +45,10 @@ abstract class HybridViewModelInstanceSpec: HybridObject() { @get:DoNotStrip @get:Keep abstract val instanceName: String + + @get:DoNotStrip + @get:Keep + abstract val properties: Array // Methods @DoNotStrip diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelSpec.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelSpec.kt index 463ad6bd..62a919c0 100644 --- a/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelSpec.kt +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/HybridViewModelSpec.kt @@ -53,6 +53,10 @@ abstract class HybridViewModelSpec: HybridObject() { @get:DoNotStrip @get:Keep abstract val modelName: String + + @get:DoNotStrip + @get:Keep + abstract val properties: Array // Methods @DoNotStrip diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ViewModelPropertyInfo.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ViewModelPropertyInfo.kt new file mode 100644 index 00000000..edf6b1d4 --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ViewModelPropertyInfo.kt @@ -0,0 +1,41 @@ +/// +/// ViewModelPropertyInfo.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.rive + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + + +/** + * Represents the JavaScript object/struct "ViewModelPropertyInfo". + */ +@DoNotStrip +@Keep +data class ViewModelPropertyInfo( + @DoNotStrip + @Keep + val name: String, + @DoNotStrip + @Keep + val type: ViewModelPropertyType +) { + /* primary constructor */ + + private companion object { + /** + * Constructor called from C++ + */ + @DoNotStrip + @Keep + @Suppress("unused") + @JvmStatic + private fun fromCpp(name: String, type: ViewModelPropertyType): ViewModelPropertyInfo { + return ViewModelPropertyInfo(name, type) + } + } +} diff --git a/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ViewModelPropertyType.kt b/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ViewModelPropertyType.kt new file mode 100644 index 00000000..89c47c2a --- /dev/null +++ b/nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ViewModelPropertyType.kt @@ -0,0 +1,34 @@ +/// +/// ViewModelPropertyType.kt +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +package com.margelo.nitro.rive + +import androidx.annotation.Keep +import com.facebook.proguard.annotations.DoNotStrip + +/** + * Represents the JavaScript enum/union "ViewModelPropertyType". + */ +@DoNotStrip +@Keep +enum class ViewModelPropertyType(@DoNotStrip @Keep val value: Int) { + STRING(0), + NUMBER(1), + BOOLEAN(2), + NONE(3), + COLOR(4), + LIST(5), + ENUM(6), + TRIGGER(7), + VIEWMODEL(8), + INTEGER(9), + SYMBOLLISTINDEX(10), + ASSETIMAGE(11), + ARTBOARD(12), + INPUT(13), + ANY(14); +} diff --git a/nitrogen/generated/ios/RNRive-Swift-Cxx-Bridge.hpp b/nitrogen/generated/ios/RNRive-Swift-Cxx-Bridge.hpp index 5ffe2193..cd4543a8 100644 --- a/nitrogen/generated/ios/RNRive-Swift-Cxx-Bridge.hpp +++ b/nitrogen/generated/ios/RNRive-Swift-Cxx-Bridge.hpp @@ -66,6 +66,10 @@ namespace margelo::nitro::rive { struct RiveError; } namespace margelo::nitro::rive { enum class RiveEventType; } // Forward declaration of `UnifiedRiveEvent` to properly resolve imports. namespace margelo::nitro::rive { struct UnifiedRiveEvent; } +// Forward declaration of `ViewModelPropertyInfo` to properly resolve imports. +namespace margelo::nitro::rive { struct ViewModelPropertyInfo; } +// Forward declaration of `ViewModelPropertyType` to properly resolve imports. +namespace margelo::nitro::rive { enum class ViewModelPropertyType; } // Forward declarations of Swift defined types // Forward declaration of `HybridRiveFileFactorySpec_cxx` to properly resolve imports. @@ -133,6 +137,8 @@ namespace RNRive { class HybridViewModelTriggerPropertySpec_cxx; } #include "RiveErrorType.hpp" #include "RiveEventType.hpp" #include "UnifiedRiveEvent.hpp" +#include "ViewModelPropertyInfo.hpp" +#include "ViewModelPropertyType.hpp" #include #include #include @@ -143,6 +149,7 @@ namespace RNRive { class HybridViewModelTriggerPropertySpec_cxx; } #include #include #include +#include /** * Contains specialized versions of C++ templated types so they can be accessed from Swift, @@ -853,6 +860,17 @@ namespace margelo::nitro::rive::bridge::swift { return Result::withError(error); } + // pragma MARK: std::vector + /** + * Specialized version of `std::vector`. + */ + using std__vector_ViewModelPropertyInfo_ = std::vector; + inline std::vector create_std__vector_ViewModelPropertyInfo_(size_t size) noexcept { + std::vector vector; + vector.reserve(size); + return vector; + } + // pragma MARK: std::shared_ptr /** * Specialized version of `std::shared_ptr`. diff --git a/nitrogen/generated/ios/RNRive-Swift-Cxx-Umbrella.hpp b/nitrogen/generated/ios/RNRive-Swift-Cxx-Umbrella.hpp index 945b694a..57909bd7 100644 --- a/nitrogen/generated/ios/RNRive-Swift-Cxx-Umbrella.hpp +++ b/nitrogen/generated/ios/RNRive-Swift-Cxx-Umbrella.hpp @@ -66,6 +66,10 @@ namespace margelo::nitro::rive { struct RiveError; } namespace margelo::nitro::rive { enum class RiveEventType; } // Forward declaration of `UnifiedRiveEvent` to properly resolve imports. namespace margelo::nitro::rive { struct UnifiedRiveEvent; } +// Forward declaration of `ViewModelPropertyInfo` to properly resolve imports. +namespace margelo::nitro::rive { struct ViewModelPropertyInfo; } +// Forward declaration of `ViewModelPropertyType` to properly resolve imports. +namespace margelo::nitro::rive { enum class ViewModelPropertyType; } // Include C++ defined types #include "Alignment.hpp" @@ -97,6 +101,8 @@ namespace margelo::nitro::rive { struct UnifiedRiveEvent; } #include "RiveErrorType.hpp" #include "RiveEventType.hpp" #include "UnifiedRiveEvent.hpp" +#include "ViewModelPropertyInfo.hpp" +#include "ViewModelPropertyType.hpp" #include #include #include @@ -107,6 +113,7 @@ namespace margelo::nitro::rive { struct UnifiedRiveEvent; } #include #include #include +#include // C++ helpers for Swift #include "RNRive-Swift-Cxx-Bridge.hpp" diff --git a/nitrogen/generated/ios/c++/HybridViewModelInstanceSpecSwift.hpp b/nitrogen/generated/ios/c++/HybridViewModelInstanceSpecSwift.hpp index 0ff3bff3..ad0a43f5 100644 --- a/nitrogen/generated/ios/c++/HybridViewModelInstanceSpecSwift.hpp +++ b/nitrogen/generated/ios/c++/HybridViewModelInstanceSpecSwift.hpp @@ -12,6 +12,10 @@ // Forward declaration of `HybridViewModelInstanceSpec_cxx` to properly resolve imports. namespace RNRive { class HybridViewModelInstanceSpec_cxx; } +// Forward declaration of `ViewModelPropertyInfo` to properly resolve imports. +namespace margelo::nitro::rive { struct ViewModelPropertyInfo; } +// Forward declaration of `ViewModelPropertyType` to properly resolve imports. +namespace margelo::nitro::rive { enum class ViewModelPropertyType; } // Forward declaration of `HybridViewModelNumberPropertySpec` to properly resolve imports. namespace margelo::nitro::rive { class HybridViewModelNumberPropertySpec; } // Forward declaration of `HybridViewModelStringPropertySpec` to properly resolve imports. @@ -30,6 +34,9 @@ namespace margelo::nitro::rive { class HybridViewModelImagePropertySpec; } namespace margelo::nitro::rive { class HybridViewModelListPropertySpec; } #include +#include "ViewModelPropertyInfo.hpp" +#include +#include "ViewModelPropertyType.hpp" #include #include "HybridViewModelNumberPropertySpec.hpp" #include @@ -85,6 +92,10 @@ namespace margelo::nitro::rive { auto __result = _swiftPart.getInstanceName(); return __result; } + inline std::vector getProperties() noexcept override { + auto __result = _swiftPart.getProperties(); + return __result; + } public: // Methods diff --git a/nitrogen/generated/ios/c++/HybridViewModelSpecSwift.hpp b/nitrogen/generated/ios/c++/HybridViewModelSpecSwift.hpp index fc5c1a8b..3189450b 100644 --- a/nitrogen/generated/ios/c++/HybridViewModelSpecSwift.hpp +++ b/nitrogen/generated/ios/c++/HybridViewModelSpecSwift.hpp @@ -12,10 +12,17 @@ // Forward declaration of `HybridViewModelSpec_cxx` to properly resolve imports. namespace RNRive { class HybridViewModelSpec_cxx; } +// Forward declaration of `ViewModelPropertyInfo` to properly resolve imports. +namespace margelo::nitro::rive { struct ViewModelPropertyInfo; } +// Forward declaration of `ViewModelPropertyType` to properly resolve imports. +namespace margelo::nitro::rive { enum class ViewModelPropertyType; } // Forward declaration of `HybridViewModelInstanceSpec` to properly resolve imports. namespace margelo::nitro::rive { class HybridViewModelInstanceSpec; } #include +#include "ViewModelPropertyInfo.hpp" +#include +#include "ViewModelPropertyType.hpp" #include #include "HybridViewModelInstanceSpec.hpp" #include @@ -70,6 +77,10 @@ namespace margelo::nitro::rive { auto __result = _swiftPart.getModelName(); return __result; } + inline std::vector getProperties() noexcept override { + auto __result = _swiftPart.getProperties(); + return __result; + } public: // Methods diff --git a/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec.swift b/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec.swift index bbb13b10..8f1196ea 100644 --- a/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec.swift +++ b/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec.swift @@ -12,6 +12,7 @@ import NitroModules public protocol HybridViewModelInstanceSpec_protocol: HybridObject { // Properties var instanceName: String { get } + var properties: [ViewModelPropertyInfo] { get } // Methods func numberProperty(path: String) throws -> (any HybridViewModelNumberPropertySpec)? diff --git a/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec_cxx.swift b/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec_cxx.swift index dc7d1647..5cb0fd21 100644 --- a/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec_cxx.swift +++ b/nitrogen/generated/ios/swift/HybridViewModelInstanceSpec_cxx.swift @@ -120,6 +120,19 @@ open class HybridViewModelInstanceSpec_cxx { return std.string(self.__implementation.instanceName) } } + + public final var properties: bridge.std__vector_ViewModelPropertyInfo_ { + @inline(__always) + get { + return { () -> bridge.std__vector_ViewModelPropertyInfo_ in + var __vector = bridge.create_std__vector_ViewModelPropertyInfo_(self.__implementation.properties.count) + for __item in self.__implementation.properties { + __vector.push_back(__item) + } + return __vector + }() + } + } // Methods @inline(__always) diff --git a/nitrogen/generated/ios/swift/HybridViewModelSpec.swift b/nitrogen/generated/ios/swift/HybridViewModelSpec.swift index 2ed7687b..6cd72573 100644 --- a/nitrogen/generated/ios/swift/HybridViewModelSpec.swift +++ b/nitrogen/generated/ios/swift/HybridViewModelSpec.swift @@ -14,6 +14,7 @@ public protocol HybridViewModelSpec_protocol: HybridObject { var propertyCount: Double { get } var instanceCount: Double { get } var modelName: String { get } + var properties: [ViewModelPropertyInfo] { get } // Methods func createInstanceByIndex(index: Double) throws -> (any HybridViewModelInstanceSpec)? diff --git a/nitrogen/generated/ios/swift/HybridViewModelSpec_cxx.swift b/nitrogen/generated/ios/swift/HybridViewModelSpec_cxx.swift index 44d033f0..dfc38b1c 100644 --- a/nitrogen/generated/ios/swift/HybridViewModelSpec_cxx.swift +++ b/nitrogen/generated/ios/swift/HybridViewModelSpec_cxx.swift @@ -134,6 +134,19 @@ open class HybridViewModelSpec_cxx { return std.string(self.__implementation.modelName) } } + + public final var properties: bridge.std__vector_ViewModelPropertyInfo_ { + @inline(__always) + get { + return { () -> bridge.std__vector_ViewModelPropertyInfo_ in + var __vector = bridge.create_std__vector_ViewModelPropertyInfo_(self.__implementation.properties.count) + for __item in self.__implementation.properties { + __vector.push_back(__item) + } + return __vector + }() + } + } // Methods @inline(__always) diff --git a/nitrogen/generated/ios/swift/ViewModelPropertyInfo.swift b/nitrogen/generated/ios/swift/ViewModelPropertyInfo.swift new file mode 100644 index 00000000..255e4015 --- /dev/null +++ b/nitrogen/generated/ios/swift/ViewModelPropertyInfo.swift @@ -0,0 +1,47 @@ +/// +/// ViewModelPropertyInfo.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +import Foundation +import NitroModules + +/** + * Represents an instance of `ViewModelPropertyInfo`, backed by a C++ struct. + */ +public typealias ViewModelPropertyInfo = margelo.nitro.rive.ViewModelPropertyInfo + +public extension ViewModelPropertyInfo { + private typealias bridge = margelo.nitro.rive.bridge.swift + + /** + * Create a new instance of `ViewModelPropertyInfo`. + */ + init(name: String, type: ViewModelPropertyType) { + self.init(std.string(name), type) + } + + var name: String { + @inline(__always) + get { + return String(self.__name) + } + @inline(__always) + set { + self.__name = std.string(newValue) + } + } + + var type: ViewModelPropertyType { + @inline(__always) + get { + return self.__type + } + @inline(__always) + set { + self.__type = newValue + } + } +} diff --git a/nitrogen/generated/ios/swift/ViewModelPropertyType.swift b/nitrogen/generated/ios/swift/ViewModelPropertyType.swift new file mode 100644 index 00000000..77b6bd9c --- /dev/null +++ b/nitrogen/generated/ios/swift/ViewModelPropertyType.swift @@ -0,0 +1,92 @@ +/// +/// ViewModelPropertyType.swift +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +/** + * Represents the JS union `ViewModelPropertyType`, backed by a C++ enum. + */ +public typealias ViewModelPropertyType = margelo.nitro.rive.ViewModelPropertyType + +public extension ViewModelPropertyType { + /** + * Get a ViewModelPropertyType for the given String value, or + * return `nil` if the given value was invalid/unknown. + */ + init?(fromString string: String) { + switch string { + case "string": + self = .string + case "number": + self = .number + case "boolean": + self = .boolean + case "none": + self = .none + case "color": + self = .color + case "list": + self = .list + case "enum": + self = .enum + case "trigger": + self = .trigger + case "viewModel": + self = .viewmodel + case "integer": + self = .integer + case "symbolListIndex": + self = .symbollistindex + case "assetImage": + self = .assetimage + case "artboard": + self = .artboard + case "input": + self = .input + case "any": + self = .any + default: + return nil + } + } + + /** + * Get the String value this ViewModelPropertyType represents. + */ + var stringValue: String { + switch self { + case .string: + return "string" + case .number: + return "number" + case .boolean: + return "boolean" + case .none: + return "none" + case .color: + return "color" + case .list: + return "list" + case .enum: + return "enum" + case .trigger: + return "trigger" + case .viewmodel: + return "viewModel" + case .integer: + return "integer" + case .symbollistindex: + return "symbolListIndex" + case .assetimage: + return "assetImage" + case .artboard: + return "artboard" + case .input: + return "input" + case .any: + return "any" + } + } +} diff --git a/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.cpp b/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.cpp index 497960e9..f1b1dbdb 100644 --- a/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.cpp +++ b/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.cpp @@ -15,6 +15,7 @@ namespace margelo::nitro::rive { // load custom methods/properties registerHybrids(this, [](Prototype& prototype) { prototype.registerHybridGetter("instanceName", &HybridViewModelInstanceSpec::getInstanceName); + prototype.registerHybridGetter("properties", &HybridViewModelInstanceSpec::getProperties); prototype.registerHybridMethod("numberProperty", &HybridViewModelInstanceSpec::numberProperty); prototype.registerHybridMethod("stringProperty", &HybridViewModelInstanceSpec::stringProperty); prototype.registerHybridMethod("booleanProperty", &HybridViewModelInstanceSpec::booleanProperty); diff --git a/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.hpp b/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.hpp index a709211f..b19c11ea 100644 --- a/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.hpp +++ b/nitrogen/generated/shared/c++/HybridViewModelInstanceSpec.hpp @@ -13,6 +13,8 @@ #error NitroModules cannot be found! Are you sure you installed NitroModules properly? #endif +// Forward declaration of `ViewModelPropertyInfo` to properly resolve imports. +namespace margelo::nitro::rive { struct ViewModelPropertyInfo; } // Forward declaration of `HybridViewModelNumberPropertySpec` to properly resolve imports. namespace margelo::nitro::rive { class HybridViewModelNumberPropertySpec; } // Forward declaration of `HybridViewModelStringPropertySpec` to properly resolve imports. @@ -31,6 +33,8 @@ namespace margelo::nitro::rive { class HybridViewModelImagePropertySpec; } namespace margelo::nitro::rive { class HybridViewModelListPropertySpec; } #include +#include "ViewModelPropertyInfo.hpp" +#include #include #include "HybridViewModelNumberPropertySpec.hpp" #include @@ -70,6 +74,7 @@ namespace margelo::nitro::rive { public: // Properties virtual std::string getInstanceName() = 0; + virtual std::vector getProperties() = 0; public: // Methods diff --git a/nitrogen/generated/shared/c++/HybridViewModelSpec.cpp b/nitrogen/generated/shared/c++/HybridViewModelSpec.cpp index ee79d808..bfb20076 100644 --- a/nitrogen/generated/shared/c++/HybridViewModelSpec.cpp +++ b/nitrogen/generated/shared/c++/HybridViewModelSpec.cpp @@ -17,6 +17,7 @@ namespace margelo::nitro::rive { prototype.registerHybridGetter("propertyCount", &HybridViewModelSpec::getPropertyCount); prototype.registerHybridGetter("instanceCount", &HybridViewModelSpec::getInstanceCount); prototype.registerHybridGetter("modelName", &HybridViewModelSpec::getModelName); + prototype.registerHybridGetter("properties", &HybridViewModelSpec::getProperties); prototype.registerHybridMethod("createInstanceByIndex", &HybridViewModelSpec::createInstanceByIndex); prototype.registerHybridMethod("createInstanceByName", &HybridViewModelSpec::createInstanceByName); prototype.registerHybridMethod("createDefaultInstance", &HybridViewModelSpec::createDefaultInstance); diff --git a/nitrogen/generated/shared/c++/HybridViewModelSpec.hpp b/nitrogen/generated/shared/c++/HybridViewModelSpec.hpp index b15df27c..919ab2b7 100644 --- a/nitrogen/generated/shared/c++/HybridViewModelSpec.hpp +++ b/nitrogen/generated/shared/c++/HybridViewModelSpec.hpp @@ -13,10 +13,14 @@ #error NitroModules cannot be found! Are you sure you installed NitroModules properly? #endif +// Forward declaration of `ViewModelPropertyInfo` to properly resolve imports. +namespace margelo::nitro::rive { struct ViewModelPropertyInfo; } // Forward declaration of `HybridViewModelInstanceSpec` to properly resolve imports. namespace margelo::nitro::rive { class HybridViewModelInstanceSpec; } #include +#include "ViewModelPropertyInfo.hpp" +#include #include #include "HybridViewModelInstanceSpec.hpp" #include @@ -51,6 +55,7 @@ namespace margelo::nitro::rive { virtual double getPropertyCount() = 0; virtual double getInstanceCount() = 0; virtual std::string getModelName() = 0; + virtual std::vector getProperties() = 0; public: // Methods diff --git a/nitrogen/generated/shared/c++/ViewModelPropertyInfo.hpp b/nitrogen/generated/shared/c++/ViewModelPropertyInfo.hpp new file mode 100644 index 00000000..bb93b806 --- /dev/null +++ b/nitrogen/generated/shared/c++/ViewModelPropertyInfo.hpp @@ -0,0 +1,81 @@ +/// +/// ViewModelPropertyInfo.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +// Forward declaration of `ViewModelPropertyType` to properly resolve imports. +namespace margelo::nitro::rive { enum class ViewModelPropertyType; } + +#include +#include "ViewModelPropertyType.hpp" + +namespace margelo::nitro::rive { + + /** + * A struct which can be represented as a JavaScript object (ViewModelPropertyInfo). + */ + struct ViewModelPropertyInfo { + public: + std::string name SWIFT_PRIVATE; + ViewModelPropertyType type SWIFT_PRIVATE; + + public: + ViewModelPropertyInfo() = default; + explicit ViewModelPropertyInfo(std::string name, ViewModelPropertyType type): name(name), type(type) {} + }; + +} // namespace margelo::nitro::rive + +namespace margelo::nitro { + + // C++ ViewModelPropertyInfo <> JS ViewModelPropertyInfo (object) + template <> + struct JSIConverter final { + static inline margelo::nitro::rive::ViewModelPropertyInfo fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + jsi::Object obj = arg.asObject(runtime); + return margelo::nitro::rive::ViewModelPropertyInfo( + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, "name")), + JSIConverter::fromJSI(runtime, obj.getProperty(runtime, "type")) + ); + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::rive::ViewModelPropertyInfo& arg) { + jsi::Object obj(runtime); + obj.setProperty(runtime, "name", JSIConverter::toJSI(runtime, arg.name)); + obj.setProperty(runtime, "type", JSIConverter::toJSI(runtime, arg.type)); + return obj; + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isObject()) { + return false; + } + jsi::Object obj = value.getObject(runtime); + if (!nitro::isPlainObject(runtime, obj)) { + return false; + } + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, "name"))) return false; + if (!JSIConverter::canConvert(runtime, obj.getProperty(runtime, "type"))) return false; + return true; + } + }; + +} // namespace margelo::nitro diff --git a/nitrogen/generated/shared/c++/ViewModelPropertyType.hpp b/nitrogen/generated/shared/c++/ViewModelPropertyType.hpp new file mode 100644 index 00000000..5c4bdd15 --- /dev/null +++ b/nitrogen/generated/shared/c++/ViewModelPropertyType.hpp @@ -0,0 +1,128 @@ +/// +/// ViewModelPropertyType.hpp +/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE. +/// https://github.com/mrousavy/nitro +/// Copyright © 2025 Marc Rousavy @ Margelo +/// + +#pragma once + +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif +#if __has_include() +#include +#else +#error NitroModules cannot be found! Are you sure you installed NitroModules properly? +#endif + +namespace margelo::nitro::rive { + + /** + * An enum which can be represented as a JavaScript union (ViewModelPropertyType). + */ + enum class ViewModelPropertyType { + STRING SWIFT_NAME(string) = 0, + NUMBER SWIFT_NAME(number) = 1, + BOOLEAN SWIFT_NAME(boolean) = 2, + NONE SWIFT_NAME(none) = 3, + COLOR SWIFT_NAME(color) = 4, + LIST SWIFT_NAME(list) = 5, + ENUM SWIFT_NAME(enum) = 6, + TRIGGER SWIFT_NAME(trigger) = 7, + VIEWMODEL SWIFT_NAME(viewmodel) = 8, + INTEGER SWIFT_NAME(integer) = 9, + SYMBOLLISTINDEX SWIFT_NAME(symbollistindex) = 10, + ASSETIMAGE SWIFT_NAME(assetimage) = 11, + ARTBOARD SWIFT_NAME(artboard) = 12, + INPUT SWIFT_NAME(input) = 13, + ANY SWIFT_NAME(any) = 14, + } CLOSED_ENUM; + +} // namespace margelo::nitro::rive + +namespace margelo::nitro { + + // C++ ViewModelPropertyType <> JS ViewModelPropertyType (union) + template <> + struct JSIConverter final { + static inline margelo::nitro::rive::ViewModelPropertyType fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) { + std::string unionValue = JSIConverter::fromJSI(runtime, arg); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("string"): return margelo::nitro::rive::ViewModelPropertyType::STRING; + case hashString("number"): return margelo::nitro::rive::ViewModelPropertyType::NUMBER; + case hashString("boolean"): return margelo::nitro::rive::ViewModelPropertyType::BOOLEAN; + case hashString("none"): return margelo::nitro::rive::ViewModelPropertyType::NONE; + case hashString("color"): return margelo::nitro::rive::ViewModelPropertyType::COLOR; + case hashString("list"): return margelo::nitro::rive::ViewModelPropertyType::LIST; + case hashString("enum"): return margelo::nitro::rive::ViewModelPropertyType::ENUM; + case hashString("trigger"): return margelo::nitro::rive::ViewModelPropertyType::TRIGGER; + case hashString("viewModel"): return margelo::nitro::rive::ViewModelPropertyType::VIEWMODEL; + case hashString("integer"): return margelo::nitro::rive::ViewModelPropertyType::INTEGER; + case hashString("symbolListIndex"): return margelo::nitro::rive::ViewModelPropertyType::SYMBOLLISTINDEX; + case hashString("assetImage"): return margelo::nitro::rive::ViewModelPropertyType::ASSETIMAGE; + case hashString("artboard"): return margelo::nitro::rive::ViewModelPropertyType::ARTBOARD; + case hashString("input"): return margelo::nitro::rive::ViewModelPropertyType::INPUT; + case hashString("any"): return margelo::nitro::rive::ViewModelPropertyType::ANY; + default: [[unlikely]] + throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum ViewModelPropertyType - invalid value!"); + } + } + static inline jsi::Value toJSI(jsi::Runtime& runtime, margelo::nitro::rive::ViewModelPropertyType arg) { + switch (arg) { + case margelo::nitro::rive::ViewModelPropertyType::STRING: return JSIConverter::toJSI(runtime, "string"); + case margelo::nitro::rive::ViewModelPropertyType::NUMBER: return JSIConverter::toJSI(runtime, "number"); + case margelo::nitro::rive::ViewModelPropertyType::BOOLEAN: return JSIConverter::toJSI(runtime, "boolean"); + case margelo::nitro::rive::ViewModelPropertyType::NONE: return JSIConverter::toJSI(runtime, "none"); + case margelo::nitro::rive::ViewModelPropertyType::COLOR: return JSIConverter::toJSI(runtime, "color"); + case margelo::nitro::rive::ViewModelPropertyType::LIST: return JSIConverter::toJSI(runtime, "list"); + case margelo::nitro::rive::ViewModelPropertyType::ENUM: return JSIConverter::toJSI(runtime, "enum"); + case margelo::nitro::rive::ViewModelPropertyType::TRIGGER: return JSIConverter::toJSI(runtime, "trigger"); + case margelo::nitro::rive::ViewModelPropertyType::VIEWMODEL: return JSIConverter::toJSI(runtime, "viewModel"); + case margelo::nitro::rive::ViewModelPropertyType::INTEGER: return JSIConverter::toJSI(runtime, "integer"); + case margelo::nitro::rive::ViewModelPropertyType::SYMBOLLISTINDEX: return JSIConverter::toJSI(runtime, "symbolListIndex"); + case margelo::nitro::rive::ViewModelPropertyType::ASSETIMAGE: return JSIConverter::toJSI(runtime, "assetImage"); + case margelo::nitro::rive::ViewModelPropertyType::ARTBOARD: return JSIConverter::toJSI(runtime, "artboard"); + case margelo::nitro::rive::ViewModelPropertyType::INPUT: return JSIConverter::toJSI(runtime, "input"); + case margelo::nitro::rive::ViewModelPropertyType::ANY: return JSIConverter::toJSI(runtime, "any"); + default: [[unlikely]] + throw std::invalid_argument("Cannot convert ViewModelPropertyType to JS - invalid value: " + + std::to_string(static_cast(arg)) + "!"); + } + } + static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) { + if (!value.isString()) { + return false; + } + std::string unionValue = JSIConverter::fromJSI(runtime, value); + switch (hashString(unionValue.c_str(), unionValue.size())) { + case hashString("string"): + case hashString("number"): + case hashString("boolean"): + case hashString("none"): + case hashString("color"): + case hashString("list"): + case hashString("enum"): + case hashString("trigger"): + case hashString("viewModel"): + case hashString("integer"): + case hashString("symbolListIndex"): + case hashString("assetImage"): + case hashString("artboard"): + case hashString("input"): + case hashString("any"): + return true; + default: + return false; + } + } + }; + +} // namespace margelo::nitro diff --git a/src/index.tsx b/src/index.tsx index 0a5a3a4f..15555441 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -31,6 +31,8 @@ export type { ViewModelTriggerProperty, ViewModelImageProperty, ViewModelListProperty, + ViewModelPropertyType, + ViewModelPropertyInfo, } from './specs/ViewModel.nitro'; export { Fit } from './core/Fit'; export { Alignment } from './core/Alignment'; diff --git a/src/specs/ViewModel.nitro.ts b/src/specs/ViewModel.nitro.ts index 6ee2c327..e5e8e92c 100644 --- a/src/specs/ViewModel.nitro.ts +++ b/src/specs/ViewModel.nitro.ts @@ -1,6 +1,34 @@ import type { HybridObject } from 'react-native-nitro-modules'; import type { RiveImage } from './RiveImage.nitro'; +/** + * Property type enumeration for view model properties. + */ +export type ViewModelPropertyType = + | 'none' + | 'string' + | 'number' + | 'boolean' + | 'color' + | 'list' + | 'enum' + | 'trigger' + | 'viewModel' + | 'integer' + | 'symbolListIndex' + | 'assetImage' + | 'artboard' + | 'input' + | 'any'; + +/** + * Property metadata containing name and type information. + */ +export interface ViewModelPropertyInfo { + readonly name: string; + readonly type: ViewModelPropertyType; +} + /** * A Rive View Model as created in the Rive editor. * @see {@link https://rive.app/docs/runtimes/data-binding Rive Data Binding Documentation} @@ -13,6 +41,8 @@ export interface ViewModel readonly instanceCount: number; /** The name of the view model */ readonly modelName: string; + /** All properties defined on this view model */ + readonly properties: ViewModelPropertyInfo[]; /** Create a new instance of the view model by index */ createInstanceByIndex(index: number): ViewModelInstance | undefined; /** Create a new instance of the view model by name */ @@ -32,6 +62,11 @@ export interface ViewModelInstance extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> { /** The name of the view model instance */ readonly instanceName: string; + /** + * All properties available on this view model instance. + * @platform iOS only. On Android, returns empty array due to SDK limitation. + */ + readonly properties: ViewModelPropertyInfo[]; /** Get a number property from the view model instance at the given path */ numberProperty(path: string): ViewModelNumberProperty | undefined;