aboutsummaryrefslogtreecommitdiffstats
path: root/minilibx_beta/mlx_init.swift
blob: de6edf255502f07bf4de9c89313a9ce6d723bc5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

import Cocoa
import Metal
import mlx_window
import mlx_image


func _mlx_bridge<T : AnyObject>(obj : T) -> UnsafeMutableRawPointer? {
    return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
}

func _mlx_bridge<T : AnyObject>(ptr : UnsafeRawPointer) -> T {
    return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
}



public class MlxMain {

      public var winList = [MlxWin]()
      public var imgList = [MlxImg]()
      var myMlxApp:NSApplication?
      public var device:MTLDevice!
      var loopHook:UnsafeMutableRawPointer?
      var loopParam:UnsafeMutableRawPointer
      var loopHookTimer:CFRunLoopTimer?
      public var inLoop = false

      public init(_ flag:Int = 0)
      {
	/// make app with top menubar
        myMlxApp = NSApplication.shared
	if (flag == 1)
	{
		NSApp.setActivationPolicy(NSApplication.ActivationPolicy.prohibited)   /// for non clickable win, no top menu
	}
	else
	{
		NSApp.setActivationPolicy(NSApplication.ActivationPolicy.regular)
	}

	device = MTLCreateSystemDefaultDevice()!
	loopParam = UnsafeMutableRawPointer(&inLoop)  /// dummy addr init

	/// Add observer anyway to flush pixels every loop. If loop_hook exists, call it.
        var ocontext = CFRunLoopObserverContext(version:0, info:_mlx_bridge(obj:self), retain:nil, release:nil, copyDescription:nil)
	let observer = CFRunLoopObserverCreate(kCFAllocatorDefault, CFRunLoopActivity.beforeWaiting.rawValue, true, 0, createOCallback(), &ocontext)
	CFRunLoopAddObserver(CFRunLoopGetMain(), observer, CFRunLoopMode.commonModes)

      }

      public func addWinToList(_ win:MlxWin)
      { winList.append(win) }
      public func addImgToList(_ img:MlxImg)
      { imgList.append(img) }


    func doCallLoopHook()
    {
///	if (loopHook != nil)
///	{
	   _ = (unsafeBitCast(loopHook!,to:(@convention(c)(UnsafeRawPointer)->Void).self))(loopParam)
///	}
    }

    func createOCallback() -> CFRunLoopObserverCallBack
    {
        return { (cfRunloopObserver, cfrunloopactivity, info) -> Void in
	    let mlx:MlxMain = _mlx_bridge(ptr:info!)
	    mlx.winList.forEach { $0.flushImages() }
///         mlx.doCallLoopHook()
        }
    }

    func createTCallback() -> CFRunLoopTimerCallBack
    {
        return { (cfRunloopTimer, info) -> Void in
	    let mlx:MlxMain = _mlx_bridge(ptr:info!)
            mlx.doCallLoopHook()
        }
    }

    public func addLoopHook(_ f:UnsafeMutableRawPointer?, _ p:UnsafeMutableRawPointer)
      {
        var tcontext = CFRunLoopTimerContext(version:0, info:_mlx_bridge(obj:self), retain:nil, release:nil, copyDescription:nil)
	if (loopHook != nil)
	{
		CFRunLoopTimerInvalidate(loopHookTimer)
	}

	loopHook = f
	loopParam = p
	if (loopHook != nil)
	{
	   loopHookTimer = CFRunLoopTimerCreate(kCFAllocatorDefault, 0.0, 0.0001, 0, 0, createTCallback(), &tcontext)
	   CFRunLoopAddTimer(CFRunLoopGetMain(), loopHookTimer, CFRunLoopMode.commonModes)
	}
      }

}