Files
peko-ios/YuMi/Modules/YMRoom/View/AnimationView/BannerScheduler.m

231 lines
6.4 KiB
Mathematica
Raw Normal View History

//
// BannerScheduler.m
// YuMi
//
// Created by AI Assistant on 2025/1/13.
//
#import "BannerScheduler.h"
@interface BannerScheduler ()
@property (nonatomic, strong) NSMutableArray *bannerQueue;
@property (nonatomic, assign) BOOL isPlaying;
@property (nonatomic, assign) BOOL isPaused;
@end
@implementation BannerScheduler
#pragma mark - Initialization
- (instancetype)initWithDelegate:(id<BannerSchedulerDelegate>)delegate {
if (self = [super init]) {
_delegate = delegate;
_bannerQueue = [NSMutableArray array];
_isPlaying = NO;
_isPaused = NO;
}
return self;
}
#pragma mark - Public Methods
- (void)enqueueBanner:(id)banner {
if (!banner) {
return;
}
[self.bannerQueue addObject:banner];
//
if (!self.isPlaying && !self.isPaused) {
[self processNextBanner];
}
}
- (void)processNextBanner {
if (self.isPaused) {
return;
}
// 🔧 delegate
if (!self.delegate) {
[self clearQueue];
self.isPlaying = NO;
return;
}
if (self.isPaused) {
return;
}
if (self.bannerQueue.count == 0) {
self.isPlaying = NO;
return;
}
if (self.isPlaying) {
return;
}
//
[self sortQueueByPriority];
// Banner
id nextBanner = [self.bannerQueue firstObject];
[self.bannerQueue removeObjectAtIndex:0];
self.isPlaying = YES;
//
if ([self.delegate respondsToSelector:@selector(bannerScheduler:didStartPlayingBanner:)]) {
[self.delegate bannerScheduler:self didStartPlayingBanner:nextBanner];
}
// Banner
if ([self.delegate respondsToSelector:@selector(bannerScheduler:shouldPlayBanner:)]) {
[self.delegate bannerScheduler:self shouldPlayBanner:nextBanner];
}
}
- (void)clearQueue {
[self.bannerQueue removeAllObjects];
}
- (void)sortQueueByPriority {
// FIFO
//
NSLog(@"🔄 BannerScheduler: 使用先进先出策略,保持队列原有顺序");
}
- (void)pause {
if (self.isPaused) {
NSLog(@"⏸️ BannerScheduler: 调度器已经处于暂停状态");
return;
}
NSLog(@"⏸️ BannerScheduler: 暂停调度器");
self.isPaused = YES;
}
- (void)resume {
NSLog(@"▶️ BannerScheduler: 恢复调度器");
self.isPaused = NO;
//
if (!self.isPlaying) {
[self processNextBanner];
}
}
- (BOOL)isQueueEmpty {
return self.bannerQueue.count == 0;
}
- (nullable id)bannerAtIndex:(NSInteger)index {
if (index < 0 || index >= self.bannerQueue.count) {
return nil;
}
return [self.bannerQueue objectAtIndex:index];
}
- (BOOL)removeBannerAtIndex:(NSInteger)index {
if (index < 0 || index >= self.bannerQueue.count) {
return NO;
}
id removedBanner = [self.bannerQueue objectAtIndex:index];
[self.bannerQueue removeObjectAtIndex:index];
NSLog(@"🗑️ BannerScheduler: 从队列中移除 Banner - 索引: %ld, 类型: %@",
(long)index, [removedBanner class]);
return YES;
}
- (NSString *)queueStatusDescription {
NSMutableString *description = [NSMutableString string];
[description appendFormat:@"BannerScheduler 状态:\n"];
[description appendFormat:@"- 播放状态: %@\n", self.isPlaying ? @"播放中" : @"空闲"];
[description appendFormat:@"- 暂停状态: %@\n", self.isPaused ? @"已暂停" : @"运行中"];
[description appendFormat:@"- 队列长度: %ld\n", (long)self.bannerQueue.count];
if (self.bannerQueue.count > 0) {
[description appendString:@"- 队列内容:\n"];
for (NSInteger i = 0; i < self.bannerQueue.count; i++) {
id banner = self.bannerQueue[i];
[description appendFormat:@" [%ld] 类型: %@\n", (long)i, [banner class]];
}
}
return description;
}
#pragma mark - Public Properties
- (NSInteger)queueCount {
return self.bannerQueue.count;
}
#pragma mark - Internal Methods
/**
* Banner
* Banner
*/
- (void)markBannerFinished {
if (!self.isPlaying) {
NSLog(@"⚠️ BannerScheduler: 尝试标记未播放的 Banner 为完成");
return;
}
// banner
static NSTimeInterval lastFinishTime = 0;
NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
//
if (currentTime - lastFinishTime < 0.3) {
NSLog(@"⏳ BannerScheduler: Banner 完成间隔过短,延迟处理 (间隔: %.2f秒)", currentTime - lastFinishTime);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self markBannerFinished];
});
return;
}
lastFinishTime = currentTime;
NSLog(@"✅ BannerScheduler: Banner 播放完成");
self.isPlaying = NO;
//
if ([self.delegate respondsToSelector:@selector(bannerSchedulerDidFinishPlaying:)]) {
[self.delegate bannerSchedulerDidFinishPlaying:self];
}
// Banner
[self processNextBanner];
}
/**
*
* @return
*/
- (NSString *)debugStatus {
NSMutableString *debugInfo = [NSMutableString string];
[debugInfo appendFormat:@"BannerScheduler Debug Status:\n"];
[debugInfo appendFormat:@"- 播放状态: %@\n", self.isPlaying ? @"播放中" : @"空闲"];
[debugInfo appendFormat:@"- 暂停状态: %@\n", self.isPaused ? @"已暂停" : @"运行中"];
[debugInfo appendFormat:@"- 队列长度: %ld\n", (long)self.bannerQueue.count];
if (self.bannerQueue.count > 0) {
[debugInfo appendString:@"- 队列内容:\n"];
for (NSInteger i = 0; i < self.bannerQueue.count; i++) {
id banner = self.bannerQueue[i];
[debugInfo appendFormat:@" [%ld] 类型: %@\n", (long)i, [banner class]];
}
}
return debugInfo;
}
@end