/ fdf / fdf / mlx / mlx_init.swift
mlx_init.swift
  1  
  2  import Cocoa
  3  import Metal
  4  import mlx_window
  5  import mlx_image
  6  
  7  
  8  func _mlx_bridge<T : AnyObject>(obj : T) -> UnsafeMutableRawPointer? {
  9      return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
 10  }
 11  
 12  func _mlx_bridge<T : AnyObject>(ptr : UnsafeRawPointer) -> T {
 13      return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
 14  }
 15  
 16  
 17  
 18  public class MlxMain {
 19  
 20        public var winList = [MlxWin]()
 21        public var imgList = [MlxImg]()
 22        var myMlxApp:NSApplication?
 23        public var device:MTLDevice!
 24        var loopHook:UnsafeMutableRawPointer?
 25        var loopParam:UnsafeMutableRawPointer
 26        var loopHookTimer:CFRunLoopTimer?
 27        public var inLoop = false
 28  
 29        public init(_ flag:Int = 0)
 30        {
 31  	/// make app with top menubar
 32          myMlxApp = NSApplication.shared
 33  	if (flag == 1)
 34  	{
 35  		NSApp.setActivationPolicy(NSApplication.ActivationPolicy.prohibited)   /// for non clickable win, no top menu
 36  	}
 37  	else
 38  	{
 39  		NSApp.setActivationPolicy(NSApplication.ActivationPolicy.regular)
 40  	}
 41  
 42  	device = MTLCreateSystemDefaultDevice()!
 43  	loopParam = UnsafeMutableRawPointer(bitPattern:1)! /// set to 1-1
 44  	loopParam -= 1
 45  
 46  	/// Add observer anyway to flush pixels every loop. If loop_hook exists, call it.
 47          var ocontext = CFRunLoopObserverContext(version:0, info:_mlx_bridge(obj:self), retain:nil, release:nil, copyDescription:nil)
 48  	let observer = CFRunLoopObserverCreate(kCFAllocatorDefault, CFRunLoopActivity.beforeWaiting.rawValue, true, 0, createOCallback(), &ocontext)
 49  	CFRunLoopAddObserver(CFRunLoopGetMain(), observer, CFRunLoopMode.commonModes)
 50  
 51        }
 52  
 53        public func addWinToList(_ win:MlxWin)
 54        { winList.append(win) }
 55        public func addImgToList(_ img:MlxImg)
 56        { imgList.append(img) }
 57  
 58  
 59      func doCallLoopHook()
 60      {
 61  ///	if (loopHook != nil)
 62  ///	{
 63  	   _ = (unsafeBitCast(loopHook!,to:(@convention(c)(UnsafeRawPointer)->Void).self))(loopParam)
 64  ///	}
 65      }
 66  
 67      func createOCallback() -> CFRunLoopObserverCallBack
 68      {
 69          return { (cfRunloopObserver, cfrunloopactivity, info) -> Void in
 70  	    let mlx:MlxMain = _mlx_bridge(ptr:info!)
 71  	    mlx.winList.forEach { $0.flushImages() }
 72  ///         mlx.doCallLoopHook()
 73          }
 74      }
 75  
 76      func createTCallback() -> CFRunLoopTimerCallBack
 77      {
 78          return { (cfRunloopTimer, info) -> Void in
 79  	    let mlx:MlxMain = _mlx_bridge(ptr:info!)
 80              mlx.doCallLoopHook()
 81          }
 82      }
 83  
 84      public func addLoopHook(_ f:UnsafeMutableRawPointer?, _ p:UnsafeMutableRawPointer)
 85        {
 86          var tcontext = CFRunLoopTimerContext(version:0, info:_mlx_bridge(obj:self), retain:nil, release:nil, copyDescription:nil)
 87  	if (loopHook != nil)
 88  	{
 89  		CFRunLoopTimerInvalidate(loopHookTimer)
 90  	}
 91  
 92  	loopHook = f
 93  	loopParam = p
 94  	if (loopHook != nil)
 95  	{
 96  	   loopHookTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, 0.0, 0.0001, 0, 0, createTCallback(), &tcontext)
 97  	   CFRunLoopAddTimer(CFRunLoopGetMain(), loopHookTimer, CFRunLoopMode.commonModes)
 98  	}
 99        }
100  
101  }