Skip to content

Commit 5a4309d

Browse files
committed
Merge branch 'pr-62'
2 parents c6a863b + afa2f9d commit 5a4309d

11 files changed

Lines changed: 664 additions & 45 deletions

OpenParsec.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
27E61AAA2929B92200FF6563 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27E61AA92929B92200FF6563 /* MainView.swift */; };
4040
27ED36FF292D4F9800B1BE3D /* NetworkHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27ED36FE292D4F9800B1BE3D /* NetworkHandler.swift */; };
4141
84480EBE2ADC4FDA007DE5F1 /* GameController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84480EBD2ADC4FDA007DE5F1 /* GameController.swift */; };
42+
E76224A12F8C017F00A2F86F /* ParsecBackgroundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E76224A02F8C017700A2F86F /* ParsecBackgroundManager.swift */; };
43+
E762250B2F8D0A0100A2F86F /* PictureInPictureManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E762250A2F8D0A0000A2F86F /* PictureInPictureManager.swift */; };
4244
FC16A7AD29A97BDA00BB70A7 /* Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC16A7AC29A97BDA00BB70A7 /* Shared.swift */; };
4345
/* End PBXBuildFile section */
4446

@@ -92,6 +94,8 @@
9294
27E61AA92929B92200FF6563 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
9395
27ED36FE292D4F9800B1BE3D /* NetworkHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkHandler.swift; sourceTree = "<group>"; };
9496
84480EBD2ADC4FDA007DE5F1 /* GameController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GameController.swift; sourceTree = "<group>"; };
97+
E76224A02F8C017700A2F86F /* ParsecBackgroundManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParsecBackgroundManager.swift; sourceTree = "<group>"; };
98+
E762250A2F8D0A0000A2F86F /* PictureInPictureManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PictureInPictureManager.swift; sourceTree = "<group>"; };
9599
FC16A7AC29A97BDA00BB70A7 /* Shared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shared.swift; sourceTree = "<group>"; };
96100
/* End PBXFileReference section */
97101

@@ -136,6 +140,8 @@
136140
27E61A90292965FC00FF6563 /* OpenParsec */ = {
137141
isa = PBXGroup;
138142
children = (
143+
E76224A02F8C017700A2F86F /* ParsecBackgroundManager.swift */,
144+
E762250A2F8D0A0000A2F86F /* PictureInPictureManager.swift */,
139145
17374D402CB8E35500EDCEE7 /* KeyCodeTranslators.swift */,
140146
17840D1C2CB6394D0097374B /* ParsecUserData.swift */,
141147
27E61AA7292994B500FF6563 /* ActivityIndicator.swift */,
@@ -283,6 +289,8 @@
283289
84480EBE2ADC4FDA007DE5F1 /* GameController.swift in Sources */,
284290
27AC751829EA339B00E8CAF7 /* URLImage.swift in Sources */,
285291
27B23A242B1B98EF00B52F14 /* ParsecMetalViewController.swift in Sources */,
292+
E76224A12F8C017F00A2F86F /* ParsecBackgroundManager.swift in Sources */,
293+
E762250B2F8D0A0100A2F86F /* PictureInPictureManager.swift in Sources */,
286294
27A923E029E8E53000F54BDA /* TouchHandlingView.swift in Sources */,
287295
27E61A92292965FC00FF6563 /* AppDelegate.swift in Sources */,
288296
27E61AAA2929B92200FF6563 /* MainView.swift in Sources */,

OpenParsec/Info.plist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
</dict>
5959
<key>UIApplicationSupportsIndirectInputEvents</key>
6060
<true/>
61+
<key>UIBackgroundModes</key>
62+
<array>
63+
<string>audio</string>
64+
</array>
6165
<key>UILaunchStoryboardName</key>
6266
<string>LaunchScreen</string>
6367
<key>UIRequiredDeviceCapabilities</key>

OpenParsec/MainView.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,14 @@ struct MainView: View
397397
refreshHosts()
398398
refreshSelf()
399399
refreshFriends()
400+
401+
ParsecBackgroundManager.shared.onShouldReconnect = { peerId in
402+
if let host = hosts.first(where: { $0.id == peerId }) {
403+
connectTo(host)
404+
} else {
405+
refreshHosts()
406+
}
407+
}
400408
}
401409

402410
func refreshHosts()
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import UIKit
2+
import AVFoundation
3+
4+
class ParsecBackgroundManager {
5+
static let shared = ParsecBackgroundManager()
6+
7+
private(set) var hasActiveConnection = false
8+
private var lastPeerId: String?
9+
private var didDisconnectDueToBackground = false
10+
private(set) var isReconnecting = false
11+
12+
var onShouldReconnect: ((String) -> Void)?
13+
var onShouldDisconnect: (() -> Void)?
14+
15+
var isMarkedForReconnect: Bool {
16+
return didDisconnectDueToBackground || isReconnecting
17+
}
18+
19+
var isPiPActive: Bool {
20+
if #available(iOS 15.0, *) {
21+
return PictureInPictureManager.shared.isPiPActive
22+
}
23+
return false
24+
}
25+
26+
private init() {
27+
}
28+
29+
func connectionDidStart(peerId: String) {
30+
hasActiveConnection = true
31+
lastPeerId = peerId
32+
didDisconnectDueToBackground = false
33+
isReconnecting = false
34+
}
35+
36+
func connectionDidEnd() {
37+
hasActiveConnection = false
38+
}
39+
40+
func sceneWillResignActive() {
41+
}
42+
43+
func sceneDidBecomeActive() {
44+
// Takes priority over isPiPActive check because stopPiP() is async
45+
if didDisconnectDueToBackground, let peerId = lastPeerId {
46+
didDisconnectDueToBackground = false
47+
isReconnecting = true
48+
49+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
50+
self?.onShouldReconnect?(peerId)
51+
}
52+
}
53+
}
54+
55+
func sceneDidEnterBackground() {
56+
if hasActiveConnection {
57+
var pipAttempted = false
58+
if #available(iOS 15.0, *) {
59+
pipAttempted = isPiPActive || PictureInPictureManager.shared.isStarting
60+
}
61+
if !pipAttempted {
62+
didDisconnectDueToBackground = true
63+
}
64+
}
65+
}
66+
67+
func markForReconnect() {
68+
guard lastPeerId != nil else { return }
69+
didDisconnectDueToBackground = true
70+
}
71+
72+
func disableAutoReconnect() {
73+
didDisconnectDueToBackground = false
74+
isReconnecting = false
75+
lastPeerId = nil
76+
}
77+
}

OpenParsec/ParsecGLKRenderer.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ class ParsecGLKRenderer:NSObject, GLKViewDelegate, GLKViewControllerDelegate
4848

4949
CParsec.renderGLFrame(timeout: timeout)
5050

51+
if #available(iOS 15.0, *) {
52+
PictureInPictureManager.shared.captureFrame(
53+
viewWidth: GLsizei(view.drawableWidth),
54+
viewHeight: GLsizei(view.drawableHeight),
55+
streamWidth: GLsizei(CParsec.hostWidth),
56+
streamHeight: GLsizei(CParsec.hostHeight)
57+
)
58+
}
59+
5160
updateImage()
5261

5362
// glFinish()

OpenParsec/ParsecGLKViewController.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ class ParsecGLKViewController : ParsecPlayground {
6767
self.glkViewController.didMove(toParent: self.viewController)
6868
}
6969

70+
var eaglContext: EAGLContext? {
71+
return glkView?.context
72+
}
73+
7074
func cleanUp() {
71-
75+
7276
}
7377

7478
func updateSize(width: CGFloat, height: CGFloat) {

OpenParsec/ParsecSDKBridge.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,23 @@ class ParsecSDKBridge: ParsecService
113113
parsecClientCfg.pngCursor = false
114114

115115
self.startBackgroundTask()
116+
117+
let status = ParsecClientConnect(_parsec, &parsecClientCfg, NetworkHandler.clinfo?.session_id, peerID)
118+
119+
if status == PARSEC_OK || status == PARSEC_CONNECTING {
120+
ParsecBackgroundManager.shared.connectionDidStart(peerId: peerID)
121+
}
116122

117-
return ParsecClientConnect(_parsec, &parsecClientCfg, NetworkHandler.clinfo?.session_id, peerID)
123+
return status
118124
}
119125

120126
func disconnect() {
121127

122128
audio_clear(&_audio)
123129
ParsecClientDisconnect(_parsec)
124130
backgroundTaskRunning = false
131+
132+
ParsecBackgroundManager.shared.connectionDidEnd()
125133
}
126134

127135
func getStatus() -> ParsecStatus {

0 commit comments

Comments
 (0)