mac/type: move c<>swift type bridging into a dedicated type helper

This commit is contained in:
der richter 2024-03-18 22:22:11 +01:00
parent 1d8f28cea7
commit 283d0877c4
8 changed files with 109 additions and 90 deletions

View File

@ -1525,6 +1525,7 @@ if features['cocoa'] and features['swift']
'osdep/mac/precise_timer.swift',
'osdep/mac/swift_compat.swift',
'osdep/mac/swift_extensions.swift',
'osdep/mac/type_helper.swift',
'video/out/mac/common.swift',
'video/out/mac/title_bar.swift',
'video/out/mac/view.swift',

View File

@ -50,7 +50,7 @@ class LibmpvHelper {
let pAddress = mpv_opengl_init_params(get_proc_address: getProcAddress,
get_proc_address_ctx: nil)
MPVHelper.withUnsafeMutableRawPointers([pAddress, advanced]) { (pointers: [UnsafeMutableRawPointer?]) in
TypeHelper.withUnsafeMutableRawPointers([pAddress, advanced]) { (pointers: [UnsafeMutableRawPointer?]) in
var params: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_API_TYPE, data: api),
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, data: pointers[0]),
@ -87,7 +87,7 @@ class LibmpvHelper {
if mpvRenderContext == nil {
log.sendWarning("Init mpv render context first.")
} else {
mpv_render_context_set_update_callback(mpvRenderContext, callback, MPVHelper.bridge(obj: object))
mpv_render_context_set_update_callback(mpvRenderContext, callback, TypeHelper.bridge(obj: object))
}
}
@ -95,7 +95,7 @@ class LibmpvHelper {
if mpvRenderContext == nil {
log.sendWarning("Init mpv render context first.")
} else {
mp_render_context_set_control_callback(mpvRenderContext, callback, MPVHelper.bridge(obj: object))
mp_render_context_set_control_callback(mpvRenderContext, callback, TypeHelper.bridge(obj: object))
}
}
@ -132,7 +132,7 @@ class LibmpvHelper {
h: Int32(surface.height),
internal_format: 0)
MPVHelper.withUnsafeMutableRawPointers([data, flip, ditherDepth, skip]) { (pointers: [UnsafeMutableRawPointer?]) in
TypeHelper.withUnsafeMutableRawPointers([data, flip, ditherDepth, skip]) { (pointers: [UnsafeMutableRawPointer?]) in
var params: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: pointers[0]),
mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: pointers[1]),
@ -234,21 +234,4 @@ class LibmpvHelper {
macOptsPtr = nil
mpvHandle = nil
}
// *(char **) MPV_FORMAT_STRING on mpv_event_property
class func mpvStringArrayToString(_ obj: UnsafeMutableRawPointer?) -> String? {
guard let str = obj else { return nil }
let cstr = UnsafeMutablePointer<UnsafeMutablePointer<Int8>>(OpaquePointer(str))
return String(cString: cstr[0])
}
// MPV_FORMAT_FLAG
class func mpvFlagToBool(_ obj: UnsafeMutableRawPointer) -> Bool? {
return UnsafePointer<Bool>(OpaquePointer(obj))?.pointee
}
// MPV_FORMAT_DOUBLE
class func mpvDoubleToDouble(_ obj: UnsafeMutableRawPointer) -> Double? {
return UnsafePointer<Double>(OpaquePointer(obj))?.pointee
}
}

View File

@ -78,44 +78,10 @@ class MPVHelper: NSObject {
}
func setMacOptionCallback(_ callback: swift_wakeup_cb_fn, context object: AnyObject) {
m_config_cache_set_wakeup_cb(macOptsCachePtr, callback, MPVHelper.bridge(obj: object))
m_config_cache_set_wakeup_cb(macOptsCachePtr, callback, TypeHelper.bridge(obj: object))
}
func nextChangedMacOption(property: inout UnsafeMutableRawPointer?) -> Bool {
return m_config_cache_get_next_changed(macOptsCachePtr, &property)
}
// (__bridge void*)
class func bridge<T: AnyObject>(obj: T) -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
}
// (__bridge T*)
class func bridge<T: AnyObject>(ptr: UnsafeRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
}
class func withUnsafeMutableRawPointers(_ arguments: [Any],
pointers: [UnsafeMutableRawPointer?] = [],
closure: (_ pointers: [UnsafeMutableRawPointer?]) -> Void) {
if arguments.count > 0 {
let args = Array(arguments.dropFirst(1))
var newPtrs = pointers
var firstArg = arguments.first
withUnsafeMutableBytes(of: &firstArg) { (ptr: UnsafeMutableRawBufferPointer) in
newPtrs.append(ptr.baseAddress)
withUnsafeMutableRawPointers(args, pointers: newPtrs, closure: closure)
}
return
}
closure(pointers)
}
class func getPointer<T>(_ value: inout T) -> UnsafeMutableRawPointer? {
return withUnsafeMutableBytes(of: &value) { (ptr: UnsafeMutableRawBufferPointer) in
ptr.baseAddress
}
}
}

View File

@ -59,7 +59,7 @@ class PreciseTimer {
init?(common com: Common) {
common = com
pthread_create(&thread, &threadAttr, entryC, MPVHelper.bridge(obj: self))
pthread_create(&thread, &threadAttr, entryC, TypeHelper.bridge(obj: self))
if thread == nil {
common.log.sendWarning("Couldn't create pthread for high precision timer")
return nil
@ -119,7 +119,7 @@ class PreciseTimer {
let threadSignal: @convention(c) (Int32) -> () = { (sig: Int32) in }
let entryC: @convention(c) (UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? = { (ptr: UnsafeMutableRawPointer) in
let ptimer: PreciseTimer = MPVHelper.bridge(ptr: ptr)
let ptimer: PreciseTimer = TypeHelper.bridge(ptr: ptr)
ptimer.entry()
return nil
}

View File

@ -186,24 +186,24 @@ class RemoteCommandCenter: NSObject {
switch String(cString: property.name) {
case "pause" where property.format == MPV_FORMAT_FLAG:
isPaused = LibmpvHelper.mpvFlagToBool(property.data) ?? false
isPaused = TypeHelper.toBool(property.data) ?? false
case "time-pos" where property.format == MPV_FORMAT_DOUBLE:
let newPosition = max(LibmpvHelper.mpvDoubleToDouble(property.data) ?? 0, 0)
let newPosition = max(TypeHelper.toDouble(property.data) ?? 0, 0)
if Int((floor(newPosition) - floor(position)) / rate) != 0 {
position = newPosition
}
case "duration" where property.format == MPV_FORMAT_DOUBLE:
duration = LibmpvHelper.mpvDoubleToDouble(property.data) ?? 0
duration = TypeHelper.toDouble(property.data) ?? 0
case "speed" where property.format == MPV_FORMAT_DOUBLE:
rate = LibmpvHelper.mpvDoubleToDouble(property.data) ?? 1
rate = TypeHelper.toDouble(property.data) ?? 1
case "media-title" where [MPV_FORMAT_STRING, MPV_FORMAT_NONE].contains(property.format):
title = LibmpvHelper.mpvStringArrayToString(property.data) ?? ""
title = TypeHelper.toString(property.data) ?? ""
case "chapter-metadata/title" where [MPV_FORMAT_STRING, MPV_FORMAT_NONE].contains(property.format):
chapter = LibmpvHelper.mpvStringArrayToString(property.data)
chapter = TypeHelper.toString(property.data)
case "metadata/by-key/album" where [MPV_FORMAT_STRING, MPV_FORMAT_NONE].contains(property.format):
album = LibmpvHelper.mpvStringArrayToString(property.data)
album = TypeHelper.toString(property.data)
case "metadata/by-key/artist" where [MPV_FORMAT_STRING, MPV_FORMAT_NONE].contains(property.format):
artist = LibmpvHelper.mpvStringArrayToString(property.data)
artist = TypeHelper.toString(property.data)
default:
break
}

View File

@ -284,16 +284,16 @@ class TouchBar: NSTouchBar, NSTouchBarDelegate {
switch String(cString: property.name) {
case "time-pos" where property.format == MPV_FORMAT_DOUBLE:
let newPosition = max(LibmpvHelper.mpvDoubleToDouble(property.data) ?? 0, 0)
let newPosition = max(TypeHelper.toDouble(property.data) ?? 0, 0)
if Int((floor(newPosition) - floor(position)) / rate) != 0 {
position = newPosition
}
case "duration" where property.format == MPV_FORMAT_DOUBLE:
duration = LibmpvHelper.mpvDoubleToDouble(property.data) ?? 0
duration = TypeHelper.toDouble(property.data) ?? 0
case "pause" where property.format == MPV_FORMAT_FLAG:
isPaused = LibmpvHelper.mpvFlagToBool(property.data) ?? false
isPaused = TypeHelper.toBool(property.data) ?? false
case "speed" where property.format == MPV_FORMAT_DOUBLE:
rate = LibmpvHelper.mpvDoubleToDouble(property.data) ?? 1
rate = TypeHelper.toDouble(property.data) ?? 1
default:
break
}

View File

@ -0,0 +1,69 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
class TypeHelper {
// (__bridge void*)
class func bridge<T: AnyObject>(obj: T) -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
}
// (__bridge T*)
class func bridge<T: AnyObject>(ptr: UnsafeRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
}
class func withUnsafeMutableRawPointers(_ arguments: [Any],
pointers: [UnsafeMutableRawPointer?] = [],
closure: (_ pointers: [UnsafeMutableRawPointer?]) -> Void) {
if arguments.count > 0 {
let args = Array(arguments.dropFirst(1))
var newPtrs = pointers
var firstArg = arguments.first
withUnsafeMutableBytes(of: &firstArg) { (ptr: UnsafeMutableRawBufferPointer) in
newPtrs.append(ptr.baseAddress)
withUnsafeMutableRawPointers(args, pointers: newPtrs, closure: closure)
}
return
}
closure(pointers)
}
class func toPointer<T>(_ value: inout T) -> UnsafeMutableRawPointer? {
return withUnsafeMutableBytes(of: &value) { (ptr: UnsafeMutableRawBufferPointer) in
ptr.baseAddress
}
}
// *(char **) MPV_FORMAT_STRING
class func toString(_ obj: UnsafeMutableRawPointer?) -> String? {
guard let str = obj else { return nil }
let cstr = UnsafeMutablePointer<UnsafeMutablePointer<Int8>>(OpaquePointer(str))
return String(cString: cstr[0])
}
// MPV_FORMAT_FLAG
class func toBool(_ obj: UnsafeMutableRawPointer) -> Bool? {
return UnsafePointer<Bool>(OpaquePointer(obj))?.pointee
}
// MPV_FORMAT_DOUBLE
class func toDouble(_ obj: UnsafeMutableRawPointer) -> Double? {
return UnsafePointer<Double>(OpaquePointer(obj))?.pointee
}
}

View File

@ -303,7 +303,7 @@ class Common: NSObject {
lightSensorIOPort = IONotificationPortCreate(kIOMasterPortDefault)
IONotificationPortSetDispatchQueue(lightSensorIOPort, queue)
var n = io_object_t()
IOServiceAddInterestNotification(lightSensorIOPort, srv, kIOGeneralInterest, lightSensorCallback, MPVHelper.bridge(obj: self), &n)
IOServiceAddInterestNotification(lightSensorIOPort, srv, kIOGeneralInterest, lightSensorCallback, TypeHelper.bridge(obj: self), &n)
let kr = IOServiceOpen(srv, mach_task_self_, 0, &lightSensor)
IOObjectRelease(srv)
@ -311,7 +311,7 @@ class Common: NSObject {
log.sendVerbose("Can't start ambient light sensor connection")
return
}
lightSensorCallback(MPVHelper.bridge(obj: self), 0, 0, nil)
lightSensorCallback(TypeHelper.bridge(obj: self), 0, 0, nil)
}
func uninitLightSensor() {
@ -334,11 +334,11 @@ class Common: NSObject {
}
func addDisplayReconfigureObserver() {
CGDisplayRegisterReconfigurationCallback(reconfigureCallback, MPVHelper.bridge(obj: self))
CGDisplayRegisterReconfigurationCallback(reconfigureCallback, TypeHelper.bridge(obj: self))
}
func removeDisplayReconfigureObserver() {
CGDisplayRemoveReconfigurationCallback(reconfigureCallback, MPVHelper.bridge(obj: self))
CGDisplayRemoveReconfigurationCallback(reconfigureCallback, TypeHelper.bridge(obj: self))
}
func addAppNotifications() {
@ -528,43 +528,43 @@ class Common: NSObject {
var opt: UnsafeMutableRawPointer?
while mpv.nextChangedOption(property: &opt) {
switch opt {
case MPVHelper.getPointer(&mpv.optsPtr.pointee.border):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.border):
DispatchQueue.main.async {
self.window?.border = Bool(mpv.opts.border)
}
case MPVHelper.getPointer(&mpv.optsPtr.pointee.fullscreen):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.fullscreen):
DispatchQueue.main.async {
self.window?.toggleFullScreen(nil)
}
case MPVHelper.getPointer(&mpv.optsPtr.pointee.ontop): fallthrough
case MPVHelper.getPointer(&mpv.optsPtr.pointee.ontop_level):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.ontop): fallthrough
case TypeHelper.toPointer(&mpv.optsPtr.pointee.ontop_level):
DispatchQueue.main.async {
self.window?.setOnTop(Bool(mpv.opts.ontop), Int(mpv.opts.ontop_level))
}
case MPVHelper.getPointer(&mpv.optsPtr.pointee.all_workspaces):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.all_workspaces):
DispatchQueue.main.async {
self.window?.setOnAllWorkspaces(Bool(mpv.opts.all_workspaces))
}
case MPVHelper.getPointer(&mpv.optsPtr.pointee.keepaspect_window):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.keepaspect_window):
DispatchQueue.main.async {
self.window?.keepAspect = Bool(mpv.opts.keepaspect_window)
}
case MPVHelper.getPointer(&mpv.optsPtr.pointee.window_minimized):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.window_minimized):
DispatchQueue.main.async {
self.window?.setMinimized(Bool(mpv.opts.window_minimized))
}
case MPVHelper.getPointer(&mpv.optsPtr.pointee.window_maximized):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.window_maximized):
DispatchQueue.main.async {
self.window?.setMaximized(Bool(mpv.opts.window_maximized))
}
case MPVHelper.getPointer(&mpv.optsPtr.pointee.cursor_passthrough):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.cursor_passthrough):
DispatchQueue.main.async {
self.window?.ignoresMouseEvents = mpv.opts.cursor_passthrough
}
case MPVHelper.getPointer(&mpv.optsPtr.pointee.geometry): fallthrough
case MPVHelper.getPointer(&mpv.optsPtr.pointee.autofit): fallthrough
case MPVHelper.getPointer(&mpv.optsPtr.pointee.autofit_smaller): fallthrough
case MPVHelper.getPointer(&mpv.optsPtr.pointee.autofit_larger):
case TypeHelper.toPointer(&mpv.optsPtr.pointee.geometry): fallthrough
case TypeHelper.toPointer(&mpv.optsPtr.pointee.autofit): fallthrough
case TypeHelper.toPointer(&mpv.optsPtr.pointee.autofit_smaller): fallthrough
case TypeHelper.toPointer(&mpv.optsPtr.pointee.autofit_larger):
DispatchQueue.main.async {
let (_, _, wr) = self.getInitProperties(vo)
self.window?.updateFrame(wr)
@ -700,11 +700,11 @@ class Common: NSObject {
var opt: UnsafeMutableRawPointer?
while mpv.nextChangedMacOption(property: &opt) {
switch opt {
case MPVHelper.getPointer(&mpv.macOptsPtr.pointee.macos_title_bar_appearance):
case TypeHelper.toPointer(&mpv.macOptsPtr.pointee.macos_title_bar_appearance):
titleBar?.set(appearance: Int(mpv.macOpts.macos_title_bar_appearance))
case MPVHelper.getPointer(&mpv.macOptsPtr.pointee.macos_title_bar_material):
case TypeHelper.toPointer(&mpv.macOptsPtr.pointee.macos_title_bar_material):
titleBar?.set(material: Int(mpv.macOpts.macos_title_bar_material))
case MPVHelper.getPointer(&mpv.macOptsPtr.pointee.macos_title_bar_color):
case TypeHelper.toPointer(&mpv.macOptsPtr.pointee.macos_title_bar_color):
titleBar?.set(color: mpv.macOpts.macos_title_bar_color)
default:
break