progrium / darwinkit

Native Mac APIs for Go. Previously known as MacDriver
MIT License
5.02k stars 160 forks source link

darwinkit: Handle functions #151

Open tmc opened 1 year ago

tmc commented 1 year ago

Our code generator doesn't currently handle functions, and Core Graphics in particular has many exposed that we can't get at until we make the code generator more capable.

programmingkidx commented 1 year ago

I have been thinking about this for a while. If we could use Go functions as Objective-C callbacks that would make things very interesting. I want to use NSControl's SetAction() method to be able to accept a Go function.

One way I thought on how we could do this is to use a hash table to store Go functions. When a function like SetAction() is called with a Go function, the Go function is stored in the hash table on the Go side. A new Objective-C class instance is made that connects to the Objective-C side. The class will have a method called doAction: and an instance variable called goFuncName. doAction will be called when an action like a button being pushed happens. goFuncName will store the value of the Go function's name as a string. When the Objective-C system calls doAction:, it will call a Go function called goCallFunc(goFuncName). goCallFunc() will turn goFuncName into a hash value and get the Go function. Then the Go function will be called.

This might work but there might be issues. Where do we keep track of the Objective-C class instance? When do we release it?

Another idea I had involved trying to find a Go function in the mach-o file format. Rather than keeping track of methods in a hash table we try to find the Go method in the binary by somehow parsing the mach-o format. I do know symbols like functions are kept in the binary. I don't know if something like this could work.

tmc commented 1 year ago

That all sounds well and good, I was moreso wanting to call this from go: https://developer.apple.com/documentation/coregraphics/1455691-cgdisplaycreateimage?language=objc

programmingkidx commented 1 year ago

I see now. I missed what you wanted. You wanted to call C functions from CoreGraphics. Doesn't sound hard to do. I am guessing the mapType() function in gen/lookup.go would have to be made to handle C functions. But then again is a C function a data type? I'm thinking a new system that wraps C function needs to be made.

programmingkidx commented 1 year ago

I guess we should decide how to start. Do we use MacSchema to download a schema for Core Graphics? If so we need to enhance MacSchema to handle this case - C functions as oppose to Objective-C methods. Are you able to download a json file for Core Graphics without using MacSchema?

After we have a json file for Core Graphics we need to have the generation system generate a new package for Core Graphics. My guess is we would need to change how gen/cmd/loader.go loads this json file. The generatePackage() function is what we would probably have to change.

tmc commented 1 year ago

I have a bit of a start at https://github.com/progrium/macschema/pull/20 but it needs to be rebased.

tmc commented 1 year ago

There's some prior art https://github.com/hsiafan/cocoa/blob/v0.17.2/coregraphics/display.go#L87

progrium commented 1 year ago

I mentioned in Discord maybe we should use FFI, but we could instead model functions after that example where we would generate functions that call cgo functions defined in Objective-C that as far as I can tell are needed to cast raw pointers to typed pointers. We'd generate a functions.gen.go and a functions.gen.m.

progrium commented 1 year ago

It would be helpful if somebody could look at the functions in that coregraphics code (display and window) with the docs for each function to start putting together some rules for types. Then I could pretty quickly get generation in for functions.