From 50e0de3fbeea07f6ed72e4d5e0b91ba02faa8513 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Tue, 17 Dec 2024 15:18:22 +0100 Subject: [PATCH] feat: Implement proper type-erasure inheritance in Swift (#427) * fix: Move `getCxxPart()` into Cxx wrapper itself to make it overridable * Update SwiftHybridObjectBridge.ts * Update SwiftHybridObjectBridge.ts * fix: Move `getCxxWrapper()` into Swift class * fix: Add base types to `HybridObjectType` * feat: Add upcast helper * fix: Use clear name to avoid confusion (`upcast()` -> `upcast_Child_to_Base()`) * Update Testers.ts * fix: Guard check * perf: Cache `getCxxWrapper()` --- .../src/syntax/c++/CppHybridObject.ts | 2 +- packages/nitrogen/src/syntax/createType.ts | 7 ++- .../src/syntax/swift/SwiftCxxBridgedType.ts | 7 +-- .../src/syntax/swift/SwiftCxxTypeHelper.ts | 28 +++++++++ .../src/syntax/swift/SwiftHybridObject.ts | 22 ++++++- .../syntax/swift/SwiftHybridObjectBridge.ts | 47 +++++++++++++- .../swift/SwiftHybridObjectRegistration.ts | 2 +- .../src/syntax/types/HybridObjectType.ts | 33 +++++++++- .../ios/NitroImage-Swift-Cxx-Bridge.cpp | 32 +++++----- .../ios/NitroImage-Swift-Cxx-Bridge.hpp | 15 +++-- .../generated/ios/NitroImageAutolinking.swift | 20 +++--- .../generated/ios/swift/HybridBaseSpec.swift | 15 +++++ .../ios/swift/HybridBaseSpec_cxx.swift | 12 +++- .../generated/ios/swift/HybridChildSpec.swift | 16 ++++- .../ios/swift/HybridChildSpec_cxx.swift | 15 ++++- .../ios/swift/HybridImageFactorySpec.swift | 15 +++++ .../swift/HybridImageFactorySpec_cxx.swift | 32 ++++++---- .../generated/ios/swift/HybridImageSpec.swift | 15 +++++ .../ios/swift/HybridImageSpec_cxx.swift | 12 +++- .../HybridTestObjectSwiftKotlinSpec.swift | 15 +++++ .../HybridTestObjectSwiftKotlinSpec_cxx.swift | 62 +++++++++---------- 21 files changed, 328 insertions(+), 96 deletions(-) diff --git a/packages/nitrogen/src/syntax/c++/CppHybridObject.ts b/packages/nitrogen/src/syntax/c++/CppHybridObject.ts index 669cb0469..2ec72d02e 100644 --- a/packages/nitrogen/src/syntax/c++/CppHybridObject.ts +++ b/packages/nitrogen/src/syntax/c++/CppHybridObject.ts @@ -29,7 +29,7 @@ export function createCppHybridObject(spec: HybridObjectSpec): SourceFile[] { const bases = ['public virtual HybridObject'] for (const base of spec.baseTypes) { - const hybridObject = new HybridObjectType(base.name, spec.language) + const hybridObject = new HybridObjectType(base) bases.push(`public virtual ${getHybridObjectName(base.name).HybridTSpec}`) const imports = hybridObject.getRequiredImports() cppForwardDeclarations.push( diff --git a/packages/nitrogen/src/syntax/createType.ts b/packages/nitrogen/src/syntax/createType.ts index b3894b53c..f4e63a450 100644 --- a/packages/nitrogen/src/syntax/createType.ts +++ b/packages/nitrogen/src/syntax/createType.ts @@ -290,7 +290,12 @@ export function createType( } else if (extendsHybridObject(type, true)) { // It is another HybridObject being referenced! const typename = type.getSymbolOrThrow().getEscapedName() - return new HybridObjectType(typename, language) + const baseTypes = type + .getBaseTypes() + .filter((t) => extendsHybridObject(t, true)) + .map((b) => createType(language, b, false)) + const baseHybrids = baseTypes.filter((b) => b instanceof HybridObjectType) + return new HybridObjectType(typename, language, baseHybrids) } else if (isDirectlyHybridObject(type)) { // It is a HybridObject directly/literally. Base type return new HybridObjectBaseType() diff --git a/packages/nitrogen/src/syntax/swift/SwiftCxxBridgedType.ts b/packages/nitrogen/src/syntax/swift/SwiftCxxBridgedType.ts index d18c9cdc4..df2644730 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftCxxBridgedType.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftCxxBridgedType.ts @@ -583,15 +583,12 @@ case ${i}: } case 'hybrid-object': { const bridge = this.getBridgeOrThrow() - const name = getTypeHybridObjectName(this.type) - const makeFunc = `bridge.${bridge.funcName}` switch (language) { case 'swift': return ` { () -> bridge.${bridge.specializationName} in - let __cxxWrapped = ${name.HybridTSpecCxx}(${swiftParameterName}) - let __pointer = __cxxWrapped.toUnsafe() - return ${makeFunc}(__pointer) + let __cxxWrapped = ${swiftParameterName}.getCxxWrapper() + return __cxxWrapped.getCxxPart() }()`.trim() default: return swiftParameterName diff --git a/packages/nitrogen/src/syntax/swift/SwiftCxxTypeHelper.ts b/packages/nitrogen/src/syntax/swift/SwiftCxxTypeHelper.ts index 57144c055..0bdfa73ee 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftCxxTypeHelper.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftCxxTypeHelper.ts @@ -72,6 +72,11 @@ function createCxxHybridObjectSwiftHelper( const swiftWrappingType = NitroConfig.getCxxNamespace('c++', HybridTSpecSwift) const swiftPartType = `${modulename}::${HybridTSpecCxx}` const name = escapeCppName(actualType) + + const upcastHelpers = type.baseTypes.map((base) => + createCxxUpcastHelper(base, type) + ) + return { cxxType: actualType, funcName: `create_${name}`, @@ -129,6 +134,29 @@ void* _Nonnull get_${name}(${name} cppType) { }, ], }, + dependencies: [...upcastHelpers], + } +} + +function createCxxUpcastHelper( + baseType: HybridObjectType, + childType: HybridObjectType +): SwiftCxxHelper { + const cppBaseType = baseType.getCode('c++') + const cppChildType = childType.getCode('c++') + const funcName = escapeCppName( + `upcast_${childType.hybridObjectName}_to_${baseType.hybridObjectName}` + ) + return { + cxxType: cppBaseType, + funcName: funcName, + specializationName: funcName, + cxxHeader: { + code: ` +inline ${cppBaseType} ${funcName}(${cppChildType} child) { return child; } +`.trim(), + requiredIncludes: [], + }, dependencies: [], } } diff --git a/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts b/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts index d6044d9b0..cbc9e6b57 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftHybridObject.ts @@ -19,10 +19,30 @@ export function createSwiftHybridObject(spec: HybridObjectSpec): SourceFile[] { classBaseClasses.push(`${baseName.HybridTSpec}_base`) } + const hasBaseClass = classBaseClasses.length > 0 const baseMembers: string[] = [] - if (classBaseClasses.length === 0) { + baseMembers.push(`private weak var cxxWrapper: ${name.HybridTSpecCxx}? = nil`) + baseMembers.push( + ` +public ${hasBaseClass ? 'override func' : 'func'} getCxxWrapper() -> ${name.HybridTSpecCxx} { +#if DEBUG + guard self is ${name.HybridTSpec} else { + fatalError("\`self\` is not a \`${name.HybridTSpec}\`! Did you accidentally inherit from \`${name.HybridTSpec}_base\` instead of \`${name.HybridTSpec}\`?") + } +#endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = ${name.HybridTSpecCxx}(self as! ${name.HybridTSpec}) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } +}`.trim() + ) + if (!hasBaseClass) { // It doesn't have a base class - implement hybridContext classBaseClasses.push('HybridObjectSpec') + baseMembers.push(`public var hybridContext = margelo.nitro.HybridContext()`) baseMembers.push(`public var memorySize: Int { return getSizeOf(self) }`) } diff --git a/packages/nitrogen/src/syntax/swift/SwiftHybridObjectBridge.ts b/packages/nitrogen/src/syntax/swift/SwiftHybridObjectBridge.ts index d56f09980..e4946580a 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftHybridObjectBridge.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftHybridObjectBridge.ts @@ -3,13 +3,18 @@ import { SwiftCxxBridgedType } from './SwiftCxxBridgedType.js' import type { Property } from '../Property.js' import { indent } from '../../utils.js' import type { Method } from '../Method.js' -import { createFileMetadataString, isNotDuplicate } from '../helpers.js' +import { + createFileMetadataString, + escapeCppName, + isNotDuplicate, +} from '../helpers.js' import type { SourceFile } from '../SourceFile.js' import { getHybridObjectName } from '../getHybridObjectName.js' import { getForwardDeclaration } from '../c++/getForwardDeclaration.js' import { NitroConfig } from '../../config/NitroConfig.js' import { includeHeader, includeNitroHeader } from '../c++/includeNitroHeader.js' import { getUmbrellaHeaderName } from '../../autolinking/ios/createSwiftUmbrellaHeader.js' +import { HybridObjectType } from '../types/HybridObjectType.js' export function getBridgeNamespace() { return NitroConfig.getCxxNamespace('swift', 'bridge', 'swift') @@ -42,6 +47,34 @@ export function createSwiftHybridObjectCxxBridge( }) const hasBase = baseClasses.length > 0 + const bridgedType = new SwiftCxxBridgedType(new HybridObjectType(spec)) + const bridge = bridgedType.getRequiredBridge() + if (bridge == null) throw new Error(`HybridObject Type should have a bridge!`) + + const baseGetCxxPartOverrides = spec.baseTypes.map((base) => { + const baseHybridObject = new HybridObjectType(base) + const bridgedBase = new SwiftCxxBridgedType(baseHybridObject) + const baseBridge = bridgedBase.getRequiredBridge() + if (baseBridge == null) + throw new Error(`HybridObject ${base.name}'s bridge cannot be null!`) + + const upcastBridge = bridge.dependencies.find( + (b) => + b.funcName.includes(escapeCppName(spec.name)) && + b.funcName.includes(escapeCppName(base.name)) + ) + if (upcastBridge == null) + throw new Error( + `HybridObject ${spec.name}'s upcast-bridge cannot be found! ${JSON.stringify(baseBridge)}` + ) + + return ` +public override func getCxxPart() -> bridge.${baseBridge.specializationName} { + let ownCxxPart = bridge.${bridge.funcName}(self.toUnsafe()) + return bridge.${upcastBridge.funcName}(ownCxxPart) +}`.trim() + }) + const swiftCxxWrapperCode = ` ${createFileMetadataString(`${name.HybridTSpecCxx}.swift`)} @@ -74,7 +107,7 @@ ${hasBase ? `public class ${name.HybridTSpecCxx} : ${baseClasses.join(', ')}` : * Create a new \`${name.HybridTSpecCxx}\` that wraps the given \`${name.HybridTSpec}\`. * All properties and methods bridge to C++ types. */ - public init(_ implementation: some ${name.HybridTSpec}) { + public init(_ implementation: any ${name.HybridTSpec}) { self.__implementation = implementation ${hasBase ? 'super.init(implementation)' : '/* no base class */'} } @@ -104,6 +137,16 @@ ${hasBase ? `public class ${name.HybridTSpecCxx} : ${baseClasses.join(', ')}` : return Unmanaged<${name.HybridTSpecCxx}>.fromOpaque(pointer).takeRetainedValue() } + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a \`${bridge.cxxType}\`. + */ + public func getCxxPart() -> bridge.${bridge.specializationName} { + return bridge.${bridge.funcName}(self.toUnsafe()) + } + + ${indent(baseGetCxxPartOverrides.join('\n'), ' ')} + /** * Contains a (weak) reference to the C++ HybridObject to cache it. */ diff --git a/packages/nitrogen/src/syntax/swift/SwiftHybridObjectRegistration.ts b/packages/nitrogen/src/syntax/swift/SwiftHybridObjectRegistration.ts index abf9943a6..6c3d64d07 100644 --- a/packages/nitrogen/src/syntax/swift/SwiftHybridObjectRegistration.ts +++ b/packages/nitrogen/src/syntax/swift/SwiftHybridObjectRegistration.ts @@ -31,7 +31,7 @@ export function createSwiftHybridObjectRegistration({ const { HybridTSpecCxx, HybridTSpecSwift, HybridTSpec } = getHybridObjectName(hybridObjectName) - const type = new HybridObjectType(hybridObjectName, 'swift') + const type = new HybridObjectType(hybridObjectName, 'swift', []) const bridge = new SwiftCxxBridgedType(type) return { diff --git a/packages/nitrogen/src/syntax/types/HybridObjectType.ts b/packages/nitrogen/src/syntax/types/HybridObjectType.ts index 2718ca187..62753e4c0 100644 --- a/packages/nitrogen/src/syntax/types/HybridObjectType.ts +++ b/packages/nitrogen/src/syntax/types/HybridObjectType.ts @@ -2,16 +2,43 @@ import { NitroConfig } from '../../config/NitroConfig.js' import type { Language } from '../../getPlatformSpecs.js' import { getForwardDeclaration } from '../c++/getForwardDeclaration.js' import { getHybridObjectName } from '../getHybridObjectName.js' +import type { HybridObjectSpec } from '../HybridObjectSpec.js' import type { SourceFile, SourceImport } from '../SourceFile.js' import type { Type, TypeKind } from './Type.js' export class HybridObjectType implements Type { readonly hybridObjectName: string readonly implementationLanguage: Language + readonly baseTypes: HybridObjectType[] - constructor(hybridObjectName: string, implementationLanguage: Language) { - this.hybridObjectName = hybridObjectName - this.implementationLanguage = implementationLanguage + constructor( + hybridObjectName: string, + implementationLanguage: Language, + baseTypes: HybridObjectType[] + ) + constructor(spec: HybridObjectSpec) + constructor( + ...args: + | [ + hybridObjectName: string, + implementationLanguage: Language, + baseTypes: HybridObjectType[], + ] + | [HybridObjectSpec] + ) { + if (args.length === 1) { + const [spec] = args + + this.hybridObjectName = spec.name + this.implementationLanguage = spec.language + this.baseTypes = spec.baseTypes.map((b) => new HybridObjectType(b)) + } else { + const [hybridObjectName, implementationLanguage, baseTypes] = args + + this.hybridObjectName = hybridObjectName + this.implementationLanguage = implementationLanguage + this.baseTypes = baseTypes + } if (this.hybridObjectName.startsWith('__')) { throw new Error( diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.cpp b/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.cpp index 2e19e04a8..555abb711 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.cpp +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.cpp @@ -66,22 +66,6 @@ namespace margelo::nitro::image::bridge::swift { return swiftPart.toUnsafe(); } - // pragma MARK: std::shared_ptr - std::shared_ptr create_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(void* _Nonnull swiftUnsafePointer) { - NitroImage::HybridChildSpec_cxx swiftPart = NitroImage::HybridChildSpec_cxx::fromUnsafe(swiftUnsafePointer); - return HybridContext::getOrCreate(swiftPart); - } - void* _Nonnull get_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(std__shared_ptr_margelo__nitro__image__HybridChildSpec_ cppType) { - std::shared_ptr swiftWrapper = std::dynamic_pointer_cast(cppType); - #ifdef NITRO_DEBUG - if (swiftWrapper == nullptr) [[unlikely]] { - throw std::runtime_error("Class \"HybridChildSpec\" is not implemented in Swift!"); - } - #endif - NitroImage::HybridChildSpec_cxx swiftPart = swiftWrapper->getSwiftPart(); - return swiftPart.toUnsafe(); - } - // pragma MARK: std::shared_ptr std::shared_ptr create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(void* _Nonnull swiftUnsafePointer) { NitroImage::HybridBaseSpec_cxx swiftPart = NitroImage::HybridBaseSpec_cxx::fromUnsafe(swiftUnsafePointer); @@ -97,5 +81,21 @@ namespace margelo::nitro::image::bridge::swift { NitroImage::HybridBaseSpec_cxx swiftPart = swiftWrapper->getSwiftPart(); return swiftPart.toUnsafe(); } + + // pragma MARK: std::shared_ptr + std::shared_ptr create_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(void* _Nonnull swiftUnsafePointer) { + NitroImage::HybridChildSpec_cxx swiftPart = NitroImage::HybridChildSpec_cxx::fromUnsafe(swiftUnsafePointer); + return HybridContext::getOrCreate(swiftPart); + } + void* _Nonnull get_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(std__shared_ptr_margelo__nitro__image__HybridChildSpec_ cppType) { + std::shared_ptr swiftWrapper = std::dynamic_pointer_cast(cppType); + #ifdef NITRO_DEBUG + if (swiftWrapper == nullptr) [[unlikely]] { + throw std::runtime_error("Class \"HybridChildSpec\" is not implemented in Swift!"); + } + #endif + NitroImage::HybridChildSpec_cxx swiftPart = swiftWrapper->getSwiftPart(); + return swiftPart.toUnsafe(); + } } // namespace margelo::nitro::image::bridge::swift diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.hpp b/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.hpp index 71f27a503..6928090d1 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.hpp +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImage-Swift-Cxx-Bridge.hpp @@ -605,6 +605,14 @@ namespace margelo::nitro::image::bridge::swift { return std::make_shared(value); } + // pragma MARK: std::shared_ptr + /** + * Specialized version of `std::shared_ptr`. + */ + using std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ = std::shared_ptr; + std::shared_ptr create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(void* _Nonnull swiftUnsafePointer); + void* _Nonnull get_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ cppType); + // pragma MARK: std::shared_ptr /** * Specialized version of `std::shared_ptr`. @@ -614,11 +622,6 @@ namespace margelo::nitro::image::bridge::swift { void* _Nonnull get_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(std__shared_ptr_margelo__nitro__image__HybridChildSpec_ cppType); // pragma MARK: std::shared_ptr - /** - * Specialized version of `std::shared_ptr`. - */ - using std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ = std::shared_ptr; - std::shared_ptr create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(void* _Nonnull swiftUnsafePointer); - void* _Nonnull get_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ cppType); + inline std::shared_ptr upcast_Child_to_Base(std::shared_ptr child) { return child; } } // namespace margelo::nitro::image::bridge::swift diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImageAutolinking.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImageAutolinking.swift index 18cb02761..2e45ba03e 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImageAutolinking.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/NitroImageAutolinking.swift @@ -18,9 +18,8 @@ public final class NitroImageAutolinking { public static func createImageFactory() -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageFactorySpec_ { let hybridObject = HybridImageFactory() return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageFactorySpec_ in - let __cxxWrapped = HybridImageFactorySpec_cxx(hybridObject) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridImageFactorySpec_(__pointer) + let __cxxWrapped = hybridObject.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } @@ -34,9 +33,8 @@ public final class NitroImageAutolinking { public static func createTestObjectSwiftKotlin() -> bridge.std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_ { let hybridObject = HybridTestObjectSwift() return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_ in - let __cxxWrapped = HybridTestObjectSwiftKotlinSpec_cxx(hybridObject) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_(__pointer) + let __cxxWrapped = hybridObject.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } @@ -50,9 +48,8 @@ public final class NitroImageAutolinking { public static func createBase() -> bridge.std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ { let hybridObject = HybridBase() return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ in - let __cxxWrapped = HybridBaseSpec_cxx(hybridObject) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(__pointer) + let __cxxWrapped = hybridObject.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } @@ -66,9 +63,8 @@ public final class NitroImageAutolinking { public static func createChild() -> bridge.std__shared_ptr_margelo__nitro__image__HybridChildSpec_ { let hybridObject = HybridChild() return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridChildSpec_ in - let __cxxWrapped = HybridChildSpec_cxx(hybridObject) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(__pointer) + let __cxxWrapped = hybridObject.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } } diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridBaseSpec.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridBaseSpec.swift index 9cf884020..88973112e 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridBaseSpec.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridBaseSpec.swift @@ -19,6 +19,21 @@ public protocol HybridBaseSpec_protocol: AnyObject { /// See ``HybridBaseSpec`` public class HybridBaseSpec_base: HybridObjectSpec { + private weak var cxxWrapper: HybridBaseSpec_cxx? = nil + public func getCxxWrapper() -> HybridBaseSpec_cxx { + #if DEBUG + guard self is HybridBaseSpec else { + fatalError("`self` is not a `HybridBaseSpec`! Did you accidentally inherit from `HybridBaseSpec_base` instead of `HybridBaseSpec`?") + } + #endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = HybridBaseSpec_cxx(self as! HybridBaseSpec) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } + } public var hybridContext = margelo.nitro.HybridContext() public var memorySize: Int { return getSizeOf(self) } } diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridBaseSpec_cxx.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridBaseSpec_cxx.swift index 930740185..f37a3089b 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridBaseSpec_cxx.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridBaseSpec_cxx.swift @@ -34,7 +34,7 @@ public class HybridBaseSpec_cxx { * Create a new `HybridBaseSpec_cxx` that wraps the given `HybridBaseSpec`. * All properties and methods bridge to C++ types. */ - public init(_ implementation: some HybridBaseSpec) { + public init(_ implementation: any HybridBaseSpec) { self.__implementation = implementation /* no base class */ } @@ -64,6 +64,16 @@ public class HybridBaseSpec_cxx { return Unmanaged.fromOpaque(pointer).takeRetainedValue() } + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a `std::shared_ptr`. + */ + public func getCxxPart() -> bridge.std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ { + return bridge.create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(self.toUnsafe()) + } + + + /** * Contains a (weak) reference to the C++ HybridObject to cache it. */ diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridChildSpec.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridChildSpec.swift index 8cd83104b..7654118cf 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridChildSpec.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridChildSpec.swift @@ -19,7 +19,21 @@ public protocol HybridChildSpec_protocol: AnyObject, HybridBaseSpec_protocol { /// See ``HybridChildSpec`` public class HybridChildSpec_base: HybridBaseSpec_base { - /* inherited */ + private weak var cxxWrapper: HybridChildSpec_cxx? = nil + public override func getCxxWrapper() -> HybridChildSpec_cxx { + #if DEBUG + guard self is HybridChildSpec else { + fatalError("`self` is not a `HybridChildSpec`! Did you accidentally inherit from `HybridChildSpec_base` instead of `HybridChildSpec`?") + } + #endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = HybridChildSpec_cxx(self as! HybridChildSpec) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } + } } /** diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridChildSpec_cxx.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridChildSpec_cxx.swift index 481aab14e..43cdb2f91 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridChildSpec_cxx.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridChildSpec_cxx.swift @@ -34,7 +34,7 @@ public class HybridChildSpec_cxx : HybridBaseSpec_cxx { * Create a new `HybridChildSpec_cxx` that wraps the given `HybridChildSpec`. * All properties and methods bridge to C++ types. */ - public init(_ implementation: some HybridChildSpec) { + public init(_ implementation: any HybridChildSpec) { self.__implementation = implementation super.init(implementation) } @@ -64,6 +64,19 @@ public class HybridChildSpec_cxx : HybridBaseSpec_cxx { return Unmanaged.fromOpaque(pointer).takeRetainedValue() } + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a `std::shared_ptr`. + */ + public func getCxxPart() -> bridge.std__shared_ptr_margelo__nitro__image__HybridChildSpec_ { + return bridge.create_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(self.toUnsafe()) + } + + public override func getCxxPart() -> bridge.std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ { + let ownCxxPart = bridge.create_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(self.toUnsafe()) + return bridge.upcast_Child_to_Base(ownCxxPart) + } + /** * Contains a (weak) reference to the C++ HybridObject to cache it. */ diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec.swift index 7c99e8e9d..cd71e4d59 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec.swift @@ -22,6 +22,21 @@ public protocol HybridImageFactorySpec_protocol: AnyObject { /// See ``HybridImageFactorySpec`` public class HybridImageFactorySpec_base: HybridObjectSpec { + private weak var cxxWrapper: HybridImageFactorySpec_cxx? = nil + public func getCxxWrapper() -> HybridImageFactorySpec_cxx { + #if DEBUG + guard self is HybridImageFactorySpec else { + fatalError("`self` is not a `HybridImageFactorySpec`! Did you accidentally inherit from `HybridImageFactorySpec_base` instead of `HybridImageFactorySpec`?") + } + #endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = HybridImageFactorySpec_cxx(self as! HybridImageFactorySpec) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } + } public var hybridContext = margelo.nitro.HybridContext() public var memorySize: Int { return getSizeOf(self) } } diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec_cxx.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec_cxx.swift index 80816f112..7e3746128 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec_cxx.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageFactorySpec_cxx.swift @@ -34,7 +34,7 @@ public class HybridImageFactorySpec_cxx { * Create a new `HybridImageFactorySpec_cxx` that wraps the given `HybridImageFactorySpec`. * All properties and methods bridge to C++ types. */ - public init(_ implementation: some HybridImageFactorySpec) { + public init(_ implementation: any HybridImageFactorySpec) { self.__implementation = implementation /* no base class */ } @@ -64,6 +64,16 @@ public class HybridImageFactorySpec_cxx { return Unmanaged.fromOpaque(pointer).takeRetainedValue() } + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a `std::shared_ptr`. + */ + public func getCxxPart() -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageFactorySpec_ { + return bridge.create_std__shared_ptr_margelo__nitro__image__HybridImageFactorySpec_(self.toUnsafe()) + } + + + /** * Contains a (weak) reference to the C++ HybridObject to cache it. */ @@ -96,9 +106,8 @@ public class HybridImageFactorySpec_cxx { do { let __result = try self.__implementation.loadImageFromFile(path: String(path)) return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageSpec_ in - let __cxxWrapped = HybridImageSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridImageSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -111,9 +120,8 @@ public class HybridImageFactorySpec_cxx { do { let __result = try self.__implementation.loadImageFromURL(path: String(path)) return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageSpec_ in - let __cxxWrapped = HybridImageSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridImageSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -126,9 +134,8 @@ public class HybridImageFactorySpec_cxx { do { let __result = try self.__implementation.loadImageFromSystemName(path: String(path)) return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageSpec_ in - let __cxxWrapped = HybridImageSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridImageSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -145,9 +152,8 @@ public class HybridImageFactorySpec_cxx { return __instance.getHybridImageSpec() }()) return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageSpec_ in - let __cxxWrapped = HybridImageSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridImageSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec.swift index 572f88ec6..513f68873 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec.swift @@ -22,6 +22,21 @@ public protocol HybridImageSpec_protocol: AnyObject { /// See ``HybridImageSpec`` public class HybridImageSpec_base: HybridObjectSpec { + private weak var cxxWrapper: HybridImageSpec_cxx? = nil + public func getCxxWrapper() -> HybridImageSpec_cxx { + #if DEBUG + guard self is HybridImageSpec else { + fatalError("`self` is not a `HybridImageSpec`! Did you accidentally inherit from `HybridImageSpec_base` instead of `HybridImageSpec`?") + } + #endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = HybridImageSpec_cxx(self as! HybridImageSpec) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } + } public var hybridContext = margelo.nitro.HybridContext() public var memorySize: Int { return getSizeOf(self) } } diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec_cxx.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec_cxx.swift index 4c5d516bd..f695b7ee5 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec_cxx.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridImageSpec_cxx.swift @@ -34,7 +34,7 @@ public class HybridImageSpec_cxx { * Create a new `HybridImageSpec_cxx` that wraps the given `HybridImageSpec`. * All properties and methods bridge to C++ types. */ - public init(_ implementation: some HybridImageSpec) { + public init(_ implementation: any HybridImageSpec) { self.__implementation = implementation /* no base class */ } @@ -64,6 +64,16 @@ public class HybridImageSpec_cxx { return Unmanaged.fromOpaque(pointer).takeRetainedValue() } + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a `std::shared_ptr`. + */ + public func getCxxPart() -> bridge.std__shared_ptr_margelo__nitro__image__HybridImageSpec_ { + return bridge.create_std__shared_ptr_margelo__nitro__image__HybridImageSpec_(self.toUnsafe()) + } + + + /** * Contains a (weak) reference to the C++ HybridObject to cache it. */ diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift index e60fa6538..91cbec9c1 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec.swift @@ -73,6 +73,21 @@ public protocol HybridTestObjectSwiftKotlinSpec_protocol: AnyObject { /// See ``HybridTestObjectSwiftKotlinSpec`` public class HybridTestObjectSwiftKotlinSpec_base: HybridObjectSpec { + private weak var cxxWrapper: HybridTestObjectSwiftKotlinSpec_cxx? = nil + public func getCxxWrapper() -> HybridTestObjectSwiftKotlinSpec_cxx { + #if DEBUG + guard self is HybridTestObjectSwiftKotlinSpec else { + fatalError("`self` is not a `HybridTestObjectSwiftKotlinSpec`! Did you accidentally inherit from `HybridTestObjectSwiftKotlinSpec_base` instead of `HybridTestObjectSwiftKotlinSpec`?") + } + #endif + if let cxxWrapper = self.cxxWrapper { + return cxxWrapper + } else { + let cxxWrapper = HybridTestObjectSwiftKotlinSpec_cxx(self as! HybridTestObjectSwiftKotlinSpec) + self.cxxWrapper = cxxWrapper + return cxxWrapper + } + } public var hybridContext = margelo.nitro.HybridContext() public var memorySize: Int { return getSizeOf(self) } } diff --git a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift index b60ae64b3..8ec0b49fe 100644 --- a/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift +++ b/packages/react-native-nitro-image/nitrogen/generated/ios/swift/HybridTestObjectSwiftKotlinSpec_cxx.swift @@ -34,7 +34,7 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { * Create a new `HybridTestObjectSwiftKotlinSpec_cxx` that wraps the given `HybridTestObjectSwiftKotlinSpec`. * All properties and methods bridge to C++ types. */ - public init(_ implementation: some HybridTestObjectSwiftKotlinSpec) { + public init(_ implementation: any HybridTestObjectSwiftKotlinSpec) { self.__implementation = implementation /* no base class */ } @@ -64,6 +64,16 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { return Unmanaged.fromOpaque(pointer).takeRetainedValue() } + /** + * Gets (or creates) the C++ part of this Hybrid Object. + * The C++ part is a `std::shared_ptr`. + */ + public func getCxxPart() -> bridge.std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_ { + return bridge.create_std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_(self.toUnsafe()) + } + + + /** * Contains a (weak) reference to the C++ HybridObject to cache it. */ @@ -92,9 +102,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { @inline(__always) get { return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_ in - let __cxxWrapped = HybridTestObjectSwiftKotlinSpec_cxx(self.__implementation.thisObject) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_(__pointer) + let __cxxWrapped = self.__implementation.thisObject.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } } @@ -105,9 +114,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { return { () -> bridge.std__optional_std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec__ in if let __unwrappedValue = self.__implementation.optionalHybrid { return bridge.create_std__optional_std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec__({ () -> bridge.std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_ in - let __cxxWrapped = HybridTestObjectSwiftKotlinSpec_cxx(__unwrappedValue) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_(__pointer) + let __cxxWrapped = __unwrappedValue.getCxxWrapper() + return __cxxWrapped.getCxxPart() }()) } else { return .init() @@ -341,9 +349,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { do { let __result = try self.__implementation.newTestObject() return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_ in - let __cxxWrapped = HybridTestObjectSwiftKotlinSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridTestObjectSwiftKotlinSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -1148,9 +1155,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { do { let __result = try self.__implementation.createChild() return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridChildSpec_ in - let __cxxWrapped = HybridChildSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -1163,9 +1169,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { do { let __result = try self.__implementation.createBase() return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ in - let __cxxWrapped = HybridBaseSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -1178,9 +1183,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { do { let __result = try self.__implementation.createBaseActualChild() return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ in - let __cxxWrapped = HybridBaseSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -1197,9 +1201,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { return __instance.getHybridChildSpec() }()) return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridChildSpec_ in - let __cxxWrapped = HybridChildSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -1216,9 +1219,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { return __instance.getHybridBaseSpec() }()) return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ in - let __cxxWrapped = HybridBaseSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -1235,9 +1237,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { return __instance.getHybridChildSpec() }()) return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridBaseSpec_ in - let __cxxWrapped = HybridBaseSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridBaseSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)" @@ -1254,9 +1255,8 @@ public class HybridTestObjectSwiftKotlinSpec_cxx { return __instance.getHybridBaseSpec() }()) return { () -> bridge.std__shared_ptr_margelo__nitro__image__HybridChildSpec_ in - let __cxxWrapped = HybridChildSpec_cxx(__result) - let __pointer = __cxxWrapped.toUnsafe() - return bridge.create_std__shared_ptr_margelo__nitro__image__HybridChildSpec_(__pointer) + let __cxxWrapped = __result.getCxxWrapper() + return __cxxWrapped.getCxxPart() }() } catch { let __message = "\(error.localizedDescription)"