1import AppKit
2
3// Headless pipeline test: sequencer --selftest <mediafile>
4if CommandLine.arguments.count >= 3, CommandLine.arguments[1] == "--selftest" {
5 runSelftest(path: CommandLine.arguments[2])
6 exit(0)
7}
8
9// Headless cache-budget test: sequencer --cachetest <file.sq> [capGB]
10if CommandLine.arguments.count >= 3, CommandLine.arguments[1] == "--cachetest" {
11 let cap = CommandLine.arguments.count >= 4 ? Int(CommandLine.arguments[3]) ?? 0 : 0
12 runCacheTest(path: CommandLine.arguments[2], capGB: cap)
13 exit(0)
14}
15
16if CommandLine.arguments.contains("--uitest") {
17 _ = NSApplication.shared // AppKit needs an app instance for views/windows
18 MainActor.assumeIsolated { runUITest() }
19}
20
21// Diagnostic: bare AVPlayerLayer window on a stitched composition, using the
22// app's own bundle/signing — isolates layer rendering from the app machinery.
23if CommandLine.arguments.count >= 3, CommandLine.arguments[1] == "--layertest" {
24 let app = NSApplication.shared
25 app.setActivationPolicy(.regular)
26 MainActor.assumeIsolated {
27 runLayerTest(specs: Array(CommandLine.arguments.dropFirst(2)))
28 }
29 app.run()
30}
31
32if CommandLine.arguments.count >= 3, CommandLine.arguments[1] == "--perftest" {
33 _ = NSApplication.shared
34 MainActor.assumeIsolated { runPerfTest(path: CommandLine.arguments[2]) }
35}
36
37// pkill/SIGTERM (run.sh does one per rebuild) must also take the ffmpeg
38// children down — the default handler kills only this process, minting the
39// orphan encoders that exhaust VideoToolbox and black out the next launch.
40// A background queue, NOT main: a wedged main thread must not make the app
41// unkillable (pkill looked ignored while main was frozen).
42signal(SIGTERM, SIG_IGN)
43signal(SIGINT, SIG_IGN)
44let signalQueue = DispatchQueue(label: "sequencer.signals", qos: .userInteractive)
45let termSource = DispatchSource.makeSignalSource(signal: SIGTERM, queue: signalQueue)
46let intSource = DispatchSource.makeSignalSource(signal: SIGINT, queue: signalQueue)
47for src in [termSource, intSource] {
48 src.setEventHandler {
49 MediaPipeline.terminateChildren()
50 exit(0)
51 }
52 src.resume()
53}
54
55HangMonitor.start()
56// SEQ_HANGTEST=1: deliberately stall the main thread once, to verify the
57// watchdog end-to-end (a [hang] line with this frame should hit the log).
58if ProcessInfo.processInfo.environment["SEQ_HANGTEST"] != nil {
59 DispatchQueue.main.asyncAfter(deadline: .now() + 2) { hangTestStall() }
60}
61
62let app = SeqApplication.shared
63let delegate = AppDelegate()
64app.delegate = delegate
65// Instantiate our controller before anything opens a document: the first
66// NSDocumentController created becomes the shared instance. Retained here so it
67// stays the shared controller for the app's lifetime.
68let documentController = ProjectDocumentController()
69app.setActivationPolicy(.regular)
70app.run()