ebiten/internal/cocoa/api_cocoa_darwin.go

139 lines
4.5 KiB
Go
Raw Normal View History

// Copyright 2022 The Ebitengine Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cocoa
import (
"reflect"
"unsafe"
"github.com/ebitengine/purego/objc"
)
var (
class_NSInvocation = objc.GetClass("NSInvocation")
class_NSMethodSignature = objc.GetClass("NSMethodSignature")
class_NSAutoreleasePool = objc.GetClass("NSAutoreleasePool")
class_NSString = objc.GetClass("NSString")
)
var (
sel_alloc = objc.RegisterName("alloc")
sel_new = objc.RegisterName("new")
sel_release = objc.RegisterName("release")
sel_invocationWithMethodSignature = objc.RegisterName("invocationWithMethodSignature:")
sel_setSelector = objc.RegisterName("setSelector:")
sel_setTarget = objc.RegisterName("setTarget:")
sel_setArgumentAtIndex = objc.RegisterName("setArgument:atIndex:")
sel_getReturnValue = objc.RegisterName("getReturnValue:")
sel_invoke = objc.RegisterName("invoke")
sel_instanceMethodSignatureForSelector = objc.RegisterName("instanceMethodSignatureForSelector:")
sel_signatureWithObjCTypes = objc.RegisterName("signatureWithObjCTypes:")
sel_initWithUTF8String = objc.RegisterName("initWithUTF8String:")
sel_UTF8String = objc.RegisterName("UTF8String")
sel_length = objc.RegisterName("length")
)
type CGFloat float64
type CGSize struct {
Width, Height CGFloat
}
type NSError struct {
objc.ID
}
// NSInvocation is being used to call functions that can't be called directly with purego.SyscallN.
// See the downsides of that function for what it cannot do.
type NSInvocation struct {
objc.ID
}
func NSInvocation_invocationWithMethodSignature(sig NSMethodSignature) NSInvocation {
return NSInvocation{objc.ID(class_NSInvocation).Send(sel_invocationWithMethodSignature, sig.ID)}
}
func (inv NSInvocation) SetSelector(_cmd objc.SEL) {
inv.Send(sel_setSelector, _cmd)
}
func (inv NSInvocation) SetTarget(target objc.ID) {
inv.Send(sel_setTarget, target)
}
func (inv NSInvocation) SetArgumentAtIndex(arg unsafe.Pointer, idx int) {
inv.Send(sel_setArgumentAtIndex, arg, idx)
}
func (inv NSInvocation) GetReturnValue(ret unsafe.Pointer) {
inv.Send(sel_getReturnValue, ret)
}
func (inv NSInvocation) Invoke() {
inv.Send(sel_invoke)
}
type NSMethodSignature struct {
objc.ID
}
func NSMethodSignature_instanceMethodSignatureForSelector(self objc.ID, _cmd objc.SEL) NSMethodSignature {
return NSMethodSignature{self.Send(sel_instanceMethodSignatureForSelector, _cmd)}
}
// NSMethodSignature_signatureWithObjCTypes takes a string that represents the type signature of a method.
// It follows the encoding specified in the Apple Docs.
//
// [Apple Docs]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html#//apple_ref/doc/uid/TP40008048-CH100
func NSMethodSignature_signatureWithObjCTypes(types string) NSMethodSignature {
return NSMethodSignature{objc.ID(class_NSMethodSignature).Send(sel_signatureWithObjCTypes, types)}
}
type NSAutoreleasePool struct {
objc.ID
}
func NSAutoreleasePool_new() NSAutoreleasePool {
return NSAutoreleasePool{objc.ID(class_NSAutoreleasePool).Send(sel_new)}
}
func (pool NSAutoreleasePool) Release() {
pool.Send(sel_release)
}
type NSString struct {
objc.ID
}
func NSString_alloc() NSString {
return NSString{objc.ID(class_NSString).Send(sel_alloc)}
}
func (s NSString) InitWithUTF8String(utf8 string) NSString {
return NSString{s.Send(sel_initWithUTF8String, utf8)}
}
func (s NSString) String() string {
// this will be nicer with unsafe.Slice once ebitengine requires 1.17
// reflect.SliceHeader is used because it will force Go to copy the string
// into Go memory when casted to a string
var b []byte
header := (*reflect.SliceHeader)(unsafe.Pointer(&b))
header.Data = uintptr(s.Send(sel_UTF8String))
header.Len = int(s.Send(sel_length))
header.Cap = header.Len
return string(b)
}