Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I work with a UnsafeMutablePointer<UnsafeMutablePointer<Void>> reference from Swift?

I'm building a test app using the SceneKit's SCNParticleSystem. It has a callback which lets you modify the particles' properties on each frame. The signature of this callback is

typealias SCNParticleModifierBlock = (UnsafeMutablePointer<UnsafeMutablePointer<Void>>, UnsafeMutablePointer<Int>, Int, Int, Float) -> Void

Reference from apple developer site - SCNParticleSystem_Class

I don't know how to access and modify this reference from Swift. If this was C it would be a ** that I could dereference like an array.

After some futzing I've gotten as far as this:

..... 
           particleSystem?.addModifierForProperties([SCNParticlePropertySize], atStage: SCNParticleModifierStage.PostDynamics, withBlock: doit2)
}

struct Foos {
    var size:float_t
}
func doit2(data:UnsafeMutablePointer<UnsafeMutablePointer<Void>>, dataStride: UnsafeMutablePointer<Int>, start:Int, end:Int, deltaTime:Float) -> Void {
    let myptr = UnsafeMutablePointer<UnsafeMutablePointer<Foos>>(data)
    print("indexes",start,end)
    for i in 0 ..< end {
        print(i,myptr[i].memory.size)
    }
}¸

This works for the first particle but crashes on the second. The first time the function is called there are 0 particles, so it skips the loop. The second time there are three particles, so it tries to print them out. The first size value is 0.9 which seams reasonable. The second size value is clearly bogus, and then it crashes and I drop into the debugger.

indexes 0 0
indexes 0 3
0 0.929816
1 1.51296e-39
(lldb)

As near as I can tell no one on the internet uses this function. The only references I find are Apple's docs which provide only ObjC examples for it, not Swift.

Help me!

like image 476
Josh Marinacci Avatar asked Oct 21 '15 00:10

Josh Marinacci


1 Answers

for examle:

var data = [[0.1, 0.2],[0.3, 0.4],[0.5, 0.6]]
let pData = UnsafeMutablePointer<UnsafeMutablePointer<Void>>(data)
// how to reconstruct the original data ??

// we need to know how much data we have
let count = data.count
// we need to know what type of data we have
let p2 = UnsafeMutablePointer<Array<Double>>(pData)
// access the data
for i in 0..<count {
    print((p2 + i).memory)
}
// [0.1, 0.2]
// [0.3, 0.4]
// [0.5, 0.6]

i think that in your code, the declaration of myptr is wrong

let myptr = UnsafeMutablePointer<UnsafeMutablePointer<Foos>>(data)

dataStride.count in your example should be 1 (number of properties) and value of its element should be size of float (size of the property).

also be careful! your loop should be something like

for i in start..<end {
...
}

are you sure the start is 0 ???

like image 99
user3441734 Avatar answered Nov 15 '22 14:11

user3441734