Casting swift struct pointers

I want to convert the following Apple's objc code to swift

_materialUniforms = [device newBufferWithLength:sizeof(AAPLMaterialUniforms) options:0];
      
AAPLMaterialUniforms *materialUniforms = (AAPLMaterialUniforms *)[_materialUniforms contents];


I tried the following

self.materialUniforms = device.newBufferWithLength(sizeof(AAPLMaterialUniforms), options: .CPUCacheModeDefaultCache)
let materialUniforms  = UnsafeMutablePointer<AAPLMaterialUniforms>(self.materialUniforms.contents())

but it is reallocating, I tried many other things without success


Thank you in advance

Answered by OOPer in 148234022

C-languages `->` is sort of combined operator of dereferencing pointer (prefix `*`) and accessing field (`.`).

So, line 03 of your Swift code lacks "dereferencing pointer" operation. In Swift, you use `.memory` (this will change in Swift 3) to dereference pointer.

materialUniforms.memory.specularColor = property.float4Value


In most cases (Objective-)C's `->` can be converted to Swift's `.memory.`, if you convert pointer types appropriately.

What do you mean by "reallocating"? Line 02 of your Swift code just converts the Pointee type of `UnsafeMutablePointer` and something "reallocating" does not happen there. What's your problem with your code?

From Apple's objc code

else if ([property.name isEqualToString:@"specularColor"]) {
                if (property.type == MDLMaterialPropertyTypeFloat4) {
                    materialUniforms->specularColor = property.float4Value;
                }

and when I try to write the same in swift

else if (property.name == "specularColor"){
                if (property.type == MDLMaterialPropertyType.Float4) {
                    materialUniforms.specularColor = property.float4Value
                }
            }

I get the following error:

MetalKitEssentialSubmesh.swift:39:21: Value of type 'UnsafeMutablePointer<AAPLMaterialUniforms>' has no member 'specularColor'


here is my definition of the struct


import simd
struct AAPLMaterialUniforms {
    let emissiveColor : float4
    let diffuseColor : float4
    let specularColor : float4
  
    let specularIntensity : Float
    let pad1 : Float
    let pad2 : Float
    let pad3 : Float
}


Thank you for your help so far

Accepted Answer

C-languages `->` is sort of combined operator of dereferencing pointer (prefix `*`) and accessing field (`.`).

So, line 03 of your Swift code lacks "dereferencing pointer" operation. In Swift, you use `.memory` (this will change in Swift 3) to dereference pointer.

materialUniforms.memory.specularColor = property.float4Value


In most cases (Objective-)C's `->` can be converted to Swift's `.memory.`, if you convert pointer types appropriately.

Thank you very much 🙂.

Can you please elaborate how this will change in Swift 3?

The property name `memory` will be renamed to `pointee`, in Swift 3. The migrator can handle this change.

Casting swift struct pointers
 
 
Q