Merge branch 'Integration' into stylus3
# Conflicts: # VoidLink/ViewControllers/StreamFrameViewController.m
This commit is contained in:
@@ -9,8 +9,8 @@
|
||||
import Foundation
|
||||
import QuartzCore
|
||||
|
||||
/// SafeTimer: 高精度、可暂停/重启、可彻底清理
|
||||
final class SafeTimer {
|
||||
@objc(SafeTimer)
|
||||
final class SafeTimer: NSObject {
|
||||
private var timer: DispatchSourceTimer?
|
||||
private let timerQueue: DispatchQueue // 私有串行队列
|
||||
private let userHandler: () -> Void
|
||||
@@ -20,7 +20,7 @@ final class SafeTimer {
|
||||
private var shouldRunHandler: Bool = false // 控制逻辑上的暂停/恢复
|
||||
private var isCleaned: Bool = false // 是否已经 clean
|
||||
|
||||
init(interval: TimeInterval = 1.0,
|
||||
@objc init(interval: TimeInterval = 1.0,
|
||||
delay: TimeInterval = 0,
|
||||
queueLabel: String = "com.example.safetimer",
|
||||
handler: @escaping () -> Void) {
|
||||
@@ -29,6 +29,8 @@ final class SafeTimer {
|
||||
self.delay = delay
|
||||
self.userHandler = handler
|
||||
self.timerQueue = DispatchQueue(label: queueLabel)
|
||||
|
||||
super.init()
|
||||
|
||||
let t = DispatchSource.makeTimerSource(queue: timerQueue)
|
||||
t.schedule(deadline: .now() + delay, repeating: interval)
|
||||
@@ -48,7 +50,7 @@ final class SafeTimer {
|
||||
}
|
||||
|
||||
/// 开始逻辑上的计时
|
||||
func start() {
|
||||
@objc func start() {
|
||||
timerQueue.async { [weak self] in
|
||||
guard let self = self, !self.isCleaned else { return }
|
||||
self.shouldRunHandler = true
|
||||
@@ -56,7 +58,7 @@ final class SafeTimer {
|
||||
}
|
||||
|
||||
/// 暂停逻辑上的计时
|
||||
func pause() {
|
||||
@objc func pause() {
|
||||
timerQueue.async { [weak self] in
|
||||
guard let self = self, !self.isCleaned else { return }
|
||||
self.shouldRunHandler = false
|
||||
@@ -64,7 +66,7 @@ final class SafeTimer {
|
||||
}
|
||||
|
||||
/// 重置下一次触发时间,并开始执行 handler
|
||||
func restart() {
|
||||
@objc func restart() {
|
||||
timerQueue.async { [weak self] in
|
||||
guard let self = self, let t = self.timer, !self.isCleaned else { return }
|
||||
t.schedule(deadline: .now() + self.delay, repeating: self.interval)
|
||||
@@ -73,7 +75,7 @@ final class SafeTimer {
|
||||
}
|
||||
|
||||
/// 彻底清理 timer,返回后保证 handler 不再执行
|
||||
func clean() {
|
||||
@objc func clean() {
|
||||
if isCleaned { return }
|
||||
// 同步在 timerQueue 执行,保证已排队事件全部处理完(或跳过)
|
||||
timerQueue.sync {
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
dispatch_block_t _delayedRemoveExtScreen;
|
||||
VideoDecoderRenderer *_videoRenderer;
|
||||
BOOL _isRestoringFromPiP;
|
||||
CADisplayLink *_displayLink;
|
||||
SafeTimer* safeTimer;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
CustomEdgeSlideGestureRecognizer *_slideToSettingsRecognizer;
|
||||
@@ -439,11 +439,12 @@
|
||||
[self.view bringSubviewToFront:self.imguiView.mtkView];
|
||||
}
|
||||
|
||||
[self stopDisplayLink];
|
||||
// [self pauseTimer];
|
||||
if(_settings.sendDummyEvent){
|
||||
[self setupDisplayLink];
|
||||
[self startDisplayLink];
|
||||
if(!safeTimer) [self setupTimer];
|
||||
if(!viewJustLoaded) [safeTimer start];
|
||||
}
|
||||
else [safeTimer pause];
|
||||
|
||||
_motionHandler = [MotionHandler sharedWithProfile: nil];
|
||||
_motionHandler.gyroBiasX = _settings.gyroBiasX.doubleValue;
|
||||
@@ -461,12 +462,11 @@
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
if(_settings.sendDummyEvent) [self startDisplayLink];
|
||||
// if(_settings.sendDummyEvent) [self startTimer];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
[super viewWillDisappear:animated];
|
||||
[self stopDisplayLink];
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
@@ -541,7 +541,8 @@
|
||||
selector:@selector(keyboardWillHide)
|
||||
name:UIKeyboardWillHideNotification
|
||||
object:nil];
|
||||
|
||||
|
||||
[safeTimer start];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -841,6 +842,9 @@
|
||||
for(UIView* view in self.view.subviews){
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
|
||||
[safeTimer pause];
|
||||
[safeTimer clean];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1698,36 +1702,17 @@
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self stopDisplayLink];
|
||||
NSLog(@"dealloc StreamFrameViewController %f", CACurrentMediaTime());
|
||||
}
|
||||
|
||||
- (void)setupDisplayLink {
|
||||
if (_displayLink != nil) return;
|
||||
- (void)setupTimer {
|
||||
TemporarySettings* tempSettings = [[[DataManager alloc] init] getSettings]; //StreamFrameViewController retrieve the settings here.
|
||||
if (@available(iOS 15.0, tvOS 15.0, *)) {
|
||||
[_displayLink setPreferredFrameRateRange:CAFrameRateRangeMake(tempSettings.framerate.intValue,tempSettings.framerate.intValue, tempSettings.framerate.intValue)];
|
||||
}
|
||||
else {
|
||||
_displayLink.preferredFramesPerSecond = tempSettings.framerate.intValue;
|
||||
}
|
||||
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick:)];
|
||||
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
|
||||
- (void)startDisplayLink {
|
||||
_displayLink.paused = NO;
|
||||
}
|
||||
|
||||
- (void)stopDisplayLink {
|
||||
[_displayLink invalidate];
|
||||
_displayLink = nil;
|
||||
}
|
||||
|
||||
- (void)displayLinkTick:(CADisplayLink *)link {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
LiSendKeyboardEvent(0xFF, KEY_ACTION_UP, 0);
|
||||
});
|
||||
safeTimer = [[SafeTimer alloc] initWithInterval:1.0/tempSettings.framerate.intValue delay:0 queueLabel:@"streamview.timer" handler:^{
|
||||
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^{
|
||||
LiSendKeyboardEvent(0xFF, KEY_ACTION_UP, 0);
|
||||
// LiSendTouchEvent(LI_TOUCH_EVENT_UP, 200, 1, 1, 0, 0, 0, 0);
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user