新增 BannerScheduler 模块,统一管理 V2 Banner 的播放队列和状态,优化了 Banner 播放逻辑,支持优先级排序、状态控制和代理模式。更新 RoomAnimationView,集成 BannerScheduler,重构了 Banner 添加和播放逻辑,提升了代码可维护性和用户体验。同时,新增 BannerScheduler 的单元测试,确保功能的正确性和稳定性。
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
|
||||
#import "GiftComboManager.h"
|
||||
#import "GiftAnimationManager.h"
|
||||
#import "BannerScheduler.h"
|
||||
|
||||
#import "MSRoomGameWebVC.h"
|
||||
#import "XPRoomViewController.h"
|
||||
@@ -75,6 +76,8 @@
|
||||
#import "XPRoomAnchorRankEnterView.h"
|
||||
#import "MSRoomOnLineView.h"
|
||||
|
||||
#import "BannerScheduler.h"
|
||||
|
||||
static const CGFloat kTipViewStayDuration = 3.0;
|
||||
static const CGFloat kTipViewMoveDuration = 0.5;
|
||||
|
||||
@@ -92,7 +95,8 @@ PIRoomGiftBroadcastWindowDelegate,
|
||||
XPRoomAnchorRankBannerViewDelegate,
|
||||
|
||||
XPRoomGraffitiGiftAnimationViewDelegate,
|
||||
UIGestureRecognizerDelegate
|
||||
UIGestureRecognizerDelegate,
|
||||
BannerSchedulerDelegate
|
||||
>
|
||||
|
||||
@property (nonatomic, weak) id<RoomHostDelegate>hostDelegate;
|
||||
@@ -134,6 +138,7 @@ UIGestureRecognizerDelegate
|
||||
/// --- 飘屏
|
||||
@property (nonatomic, strong) NSMutableArray *roomBannertModelsQueueV2; // 特效播放队列,包括幸运礼物 banner, CP banner 和 CP 特效
|
||||
@property (nonatomic, assign) BOOL isRoomBannerV2Displaying;
|
||||
@property (nonatomic, strong) BannerScheduler *bannerScheduler; // 统一的 Banner 播放调度器
|
||||
|
||||
// --- Brove 金币动画
|
||||
@property (nonatomic, strong) SVGAVideoEntity *broveSVGAEntity_lv_1;
|
||||
@@ -267,6 +272,9 @@ UIGestureRecognizerDelegate
|
||||
|
||||
- (void)setupBanner {
|
||||
_roomBannertModelsQueueV2 = [NSMutableArray array];
|
||||
|
||||
// 初始化 Banner 调度器
|
||||
self.bannerScheduler = [[BannerScheduler alloc] initWithDelegate:self];
|
||||
}
|
||||
|
||||
|
||||
@@ -510,8 +518,8 @@ UIGestureRecognizerDelegate
|
||||
NSLog(@"🧪 DEBUG环境:收到banner数据,复制%ld份用于测试", (long)copyCount);
|
||||
NSLog(@"🧪 原始banner类型: %@", NSStringFromClass([obj class]));
|
||||
|
||||
// 添加原始数据
|
||||
[self.roomBannertModelsQueueV2 addObject:obj];
|
||||
// 添加原始数据到新调度器
|
||||
[self.bannerScheduler enqueueBanner:obj];
|
||||
|
||||
// 复制指定份数
|
||||
for (int i = 1; i < copyCount; i++) {
|
||||
@@ -532,68 +540,28 @@ UIGestureRecognizerDelegate
|
||||
copiedObj.seq = obj.seq;
|
||||
|
||||
NSLog(@"🧪 复制第%d份banner数据", i + 1);
|
||||
[self.roomBannertModelsQueueV2 addObject:copiedObj];
|
||||
[self.bannerScheduler enqueueBanner:copiedObj];
|
||||
}
|
||||
|
||||
NSLog(@"🧪 队列中banner总数: %ld", (long)self.roomBannertModelsQueueV2.count);
|
||||
NSLog(@"🧪 队列中banner总数: %ld", (long)self.bannerScheduler.queueCount);
|
||||
|
||||
// 显示队列中banner类型的分布
|
||||
NSMutableDictionary *typeCount = [NSMutableDictionary dictionary];
|
||||
for (AttachmentModel *banner in self.roomBannertModelsQueueV2) {
|
||||
NSString *typeKey = [NSString stringWithFormat:@"%d", banner.second];
|
||||
NSNumber *count = typeCount[typeKey];
|
||||
typeCount[typeKey] = @(count.integerValue + 1);
|
||||
}
|
||||
|
||||
NSLog(@"🧪 队列中banner类型分布:");
|
||||
for (NSString *typeKey in typeCount.allKeys) {
|
||||
NSLog(@" - 类型%@: %@个", typeKey, typeCount[typeKey]);
|
||||
}
|
||||
NSLog(@"🧪 队列状态: %@", [self.bannerScheduler queueStatusDescription]);
|
||||
} else {
|
||||
// 禁用复制功能,正常添加
|
||||
NSLog(@"🧪 DEBUG环境:复制功能已禁用,正常添加banner");
|
||||
[self.roomBannertModelsQueueV2 addObject:obj];
|
||||
[self.bannerScheduler enqueueBanner:obj];
|
||||
}
|
||||
#else
|
||||
// 生产环境:正常添加
|
||||
[self.roomBannertModelsQueueV2 addObject:obj];
|
||||
[self.bannerScheduler enqueueBanner:obj];
|
||||
#endif
|
||||
|
||||
if (!self.isRoomBannerV2Displaying) {
|
||||
[self processNextRoomEffectAttachment];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sortBannerQueue {
|
||||
RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo;
|
||||
NSString *currentRoomUid = @(roomInfo.uid).stringValue;
|
||||
NSString *currentUid = [AccountInfoStorage instance].getUid;
|
||||
[self.roomBannertModelsQueueV2 sortUsingComparator:^NSComparisonResult(AttachmentModel * _Nonnull obj1, AttachmentModel * _Nonnull obj2) {
|
||||
|
||||
// 检查 obj1 的属性
|
||||
NSArray *obj1UidList = [obj1.data valueForKey:@"uidList"];
|
||||
NSNumber *obj1RoomUid = [obj1.data valueForKey:@"roomUid"];
|
||||
BOOL obj1IsCurrentUser = obj1UidList && [obj1UidList containsObject:currentUid];
|
||||
BOOL obj1IsCurrentRoom = obj1RoomUid && [obj1RoomUid.stringValue isEqualToString:currentRoomUid];
|
||||
|
||||
// 检查 obj2 的属性
|
||||
NSArray *obj2UidList = [obj2.data valueForKey:@"uidList"];
|
||||
NSNumber *obj2RoomUid = [obj2.data valueForKey:@"roomUid"];
|
||||
BOOL obj2IsCurrentUser = obj2UidList && [obj2UidList containsObject:currentUid];
|
||||
BOOL obj2IsCurrentRoom = obj2RoomUid && [obj2RoomUid.stringValue isEqualToString:currentRoomUid];
|
||||
|
||||
if (obj1IsCurrentUser && !obj2IsCurrentUser) {
|
||||
return NSOrderedAscending;
|
||||
} else if (!obj1IsCurrentUser && obj2IsCurrentUser) {
|
||||
return NSOrderedDescending;
|
||||
} else if (obj1IsCurrentRoom && !obj2IsCurrentRoom) {
|
||||
return NSOrderedAscending;
|
||||
} else if (!obj1IsCurrentRoom && obj2IsCurrentRoom) {
|
||||
return NSOrderedDescending;
|
||||
} else {
|
||||
return NSOrderedSame;
|
||||
}
|
||||
}];
|
||||
// 保持先进先出(FIFO)策略,不需要排序
|
||||
// 队列顺序就是添加顺序,确保公平性
|
||||
NSLog(@"🔄 RoomAnimationView: 使用先进先出策略,保持队列原有顺序");
|
||||
}
|
||||
|
||||
- (void)processNextRoomEffectAttachment {
|
||||
@@ -670,7 +638,7 @@ UIGestureRecognizerDelegate
|
||||
- (void)playBroveBanner:(AttachmentModel *)obj {
|
||||
if (!obj.data) {
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
return;
|
||||
}
|
||||
self.isRoomBannerV2Displaying = YES;
|
||||
@@ -683,7 +651,7 @@ UIGestureRecognizerDelegate
|
||||
@kStrongify(self);
|
||||
NSLog(@"🔄 BravoGiftBannerView complete 回调被调用");
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
} exitCurrentRoom:^{
|
||||
@kStrongify(self);
|
||||
[self.hostDelegate exitRoom];
|
||||
@@ -693,7 +661,7 @@ UIGestureRecognizerDelegate
|
||||
- (void)playLuckyPackageBanner:(AttachmentModel *)obj {
|
||||
if (!obj.data) {
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
return;
|
||||
}
|
||||
self.isRoomBannerV2Displaying = YES;
|
||||
@@ -706,7 +674,7 @@ UIGestureRecognizerDelegate
|
||||
@kStrongify(self);
|
||||
NSLog(@"🔄 LuckyPackageBannerView complete 回调被调用");
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
} exitCurrentRoom:^{
|
||||
@kStrongify(self);
|
||||
[self.hostDelegate exitRoom];
|
||||
@@ -720,7 +688,7 @@ UIGestureRecognizerDelegate
|
||||
- (void)playRoomGiftBanner:(AttachmentModel *)obj {
|
||||
if (!obj.data) {
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
return;
|
||||
}
|
||||
self.isRoomBannerV2Displaying = YES;
|
||||
@@ -731,7 +699,7 @@ UIGestureRecognizerDelegate
|
||||
@kStrongify(self);
|
||||
NSLog(@"🔄 RoomHighValueGiftBannerAnimation complete 回调被调用");
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -746,7 +714,7 @@ UIGestureRecognizerDelegate
|
||||
complete:^{
|
||||
@kStrongify(self);
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -758,7 +726,7 @@ UIGestureRecognizerDelegate
|
||||
@kStrongify(self);
|
||||
NSLog(@"🔄 CPGiftBanner complete 回调被调用");
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -769,7 +737,7 @@ UIGestureRecognizerDelegate
|
||||
complete:^{
|
||||
@kStrongify(self);
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -932,7 +900,7 @@ UIGestureRecognizerDelegate
|
||||
@kStrongify(self);
|
||||
NSLog(@"🔄 LuckyGiftWinningBannerView complete 回调被调用");
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
} exitCurrentRoom:^{
|
||||
@kStrongify(self);
|
||||
[self.hostDelegate exitRoom];
|
||||
@@ -971,7 +939,7 @@ UIGestureRecognizerDelegate
|
||||
@kStrongify(self);
|
||||
NSLog(@"🔄 GameUniversalBannerView complete 回调被调用");
|
||||
self.isRoomBannerV2Displaying = NO;
|
||||
[self processNextRoomEffectAttachment];
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
} goToGame:^(NSInteger gameID) {
|
||||
@kStrongify(self);
|
||||
NSArray *baishunList = [self.hostDelegate getPlayList];
|
||||
@@ -3510,6 +3478,111 @@ UIGestureRecognizerDelegate
|
||||
self.savedTapPoint = CGPointZero;
|
||||
}
|
||||
|
||||
- (void)debugBannerSchedulerStatus {
|
||||
NSLog(@"🔍 BannerScheduler 调试信息:");
|
||||
NSLog(@"%@", [self.bannerScheduler debugStatus]);
|
||||
NSLog(@"🔍 RoomAnimationView 状态:");
|
||||
NSLog(@" - isRoomBannerV2Displaying: %@", self.isRoomBannerV2Displaying ? @"YES" : @"NO");
|
||||
NSLog(@" - bannerContainer.subviews.count: %ld", (long)self.bannerContainer.subviews.count);
|
||||
}
|
||||
|
||||
- (void)testBannerScheduler {
|
||||
NSLog(@"🧪 开始测试 BannerScheduler");
|
||||
|
||||
// 测试添加 Banner
|
||||
AttachmentModel *testBanner = [[AttachmentModel alloc] init];
|
||||
testBanner.second = Custom_Message_Sub_Super_Gift_Banner;
|
||||
testBanner.data = @{@"test": @"data"};
|
||||
|
||||
[self.bannerScheduler enqueueBanner:testBanner];
|
||||
|
||||
NSLog(@"🧪 测试完成");
|
||||
}
|
||||
|
||||
#pragma mark - BannerSchedulerDelegate
|
||||
|
||||
- (void)bannerScheduler:(BannerScheduler *)scheduler shouldPlayBanner:(id)banner {
|
||||
NSLog(@"🎯 BannerSchedulerDelegate: 收到播放 Banner 请求");
|
||||
NSLog(@"🎯 Banner 类型: %@", [banner class]);
|
||||
|
||||
// 将 Banner 数据转换为 AttachmentModel 并播放
|
||||
if ([banner isKindOfClass:[AttachmentModel class]]) {
|
||||
AttachmentModel *attachment = (AttachmentModel *)banner;
|
||||
NSLog(@"🎯 AttachmentModel 类型: %ld", (long)attachment.second);
|
||||
NSLog(@"🎯 AttachmentModel 数据: %@", attachment.data);
|
||||
[self _playBannerWithAttachment:attachment];
|
||||
} else {
|
||||
NSLog(@"⚠️ BannerSchedulerDelegate: Banner 不是 AttachmentModel 类型");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)bannerSchedulerDidFinishPlaying:(BannerScheduler *)scheduler {
|
||||
// Banner 播放完成,可以在这里进行清理工作
|
||||
NSLog(@"🔄 BannerScheduler: Banner 播放完成");
|
||||
}
|
||||
|
||||
- (void)bannerScheduler:(BannerScheduler *)scheduler didStartPlayingBanner:(id)banner {
|
||||
// Banner 开始播放
|
||||
NSLog(@"🔄 BannerScheduler: Banner 开始播放 - 类型: %@", [banner class]);
|
||||
}
|
||||
|
||||
#pragma mark - Private Methods
|
||||
|
||||
- (void)_playBannerWithAttachment:(AttachmentModel *)attachment {
|
||||
NSLog(@"🎯 _playBannerWithAttachment: 开始处理 Banner - 类型: %ld", (long)attachment.second);
|
||||
|
||||
// 清理之前的 banner,防止多个banner同时显示
|
||||
NSMutableArray *viewsToRemove = [NSMutableArray array];
|
||||
for (UIView *subview in self.bannerContainer.subviews) {
|
||||
[viewsToRemove addObject:subview];
|
||||
NSLog(@"🔄 标记移除banner: %@", NSStringFromClass([subview class]));
|
||||
}
|
||||
|
||||
for (UIView *view in viewsToRemove) {
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
|
||||
// 根据 Banner 类型分发到不同的播放方法
|
||||
switch (attachment.second) {
|
||||
case Custom_Message_Sub_General_Floating_Screen_One_Room:
|
||||
case Custom_Message_Sub_General_Floating_Screen_All_Room:
|
||||
NSLog(@"🎯 分发到 playGameBanner");
|
||||
[self playGameBanner:attachment];
|
||||
break;
|
||||
case Custom_Message_Sub_Super_Gift_Winning_Coins_ALL_Room:
|
||||
NSLog(@"🎯 分发到 playLuckyWinningBanner");
|
||||
[self playLuckyWinningBanner:attachment];
|
||||
break;
|
||||
case Custom_Message_Sub_CP_Gift:
|
||||
NSLog(@"🎯 分发到 playCPGiftBanner");
|
||||
[self playCPGiftBanner:attachment];
|
||||
break;
|
||||
case Custom_Message_Sub_CP_Upgrade:
|
||||
NSLog(@"🎯 分发到 playCPLevelUp");
|
||||
[self playCPLevelUp:attachment];
|
||||
break;
|
||||
case Custom_Message_Sub_CP_Binding:
|
||||
NSLog(@"🎯 分发到 playCPBinding");
|
||||
[self playCPBinding:attachment];
|
||||
break;
|
||||
case Custom_Message_Sub_Gift_ChannelNotify:
|
||||
NSLog(@"🎯 分发到 playRoomGiftBanner");
|
||||
[self playRoomGiftBanner:attachment];
|
||||
break;
|
||||
case Custom_Message_Sub_LuckyPackage:
|
||||
NSLog(@"🎯 分发到 playLuckyPackageBanner");
|
||||
[self playLuckyPackageBanner:attachment];
|
||||
break;
|
||||
case Custom_Message_Sub_Super_Gift_Banner:
|
||||
NSLog(@"🎯 分发到 playBroveBanner");
|
||||
[self playBroveBanner:attachment];
|
||||
break;
|
||||
default:
|
||||
NSLog(@"⚠️ 未知的 Banner 类型: %ld", (long)attachment.second);
|
||||
// 标记播放完成,继续下一个
|
||||
[self.bannerScheduler markBannerFinished];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
Reference in New Issue
Block a user