Files
featherVoice/QXLive/Room(房间)/View/礼物特效/QXGiftDisplayManager.m
2025-10-21 11:36:48 +08:00

238 lines
8.0 KiB
Objective-C

//
// QXGiftDisplayManager.m
// Test
//
// Created by 启星 on 2025/10/20.
//
// QXGiftDisplayManager.m
#import "QXGiftDisplayManager.h"
#import "QXGiftDisplayView.h"
@interface QXGiftDisplayManager () <QXGiftDisplayViewDelegate>
@property (nonatomic, weak) UIView *containerView;
@property (nonatomic, strong) NSMutableArray<QXGiftDisplayView *> *displayViews;
@property (nonatomic, strong) NSMutableArray<QXRoomChatListModel *> *giftQueue;
@property (nonatomic, strong) NSMutableDictionary *accumulatedGifts;
@property (nonatomic, strong) NSMutableDictionary *waitingUpdateGifts; // 等待更新的礼物
@property (nonatomic, assign) BOOL isProcessingQueue; // 防止重复处理队列
@end
@implementation QXGiftDisplayManager
+ (instancetype)sharedManager {
static QXGiftDisplayManager *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
instance = [[QXGiftDisplayManager alloc] init];
});
return instance;
}
- (instancetype)init {
self = [super init];
if (self) {
_displayViews = [NSMutableArray array];
_giftQueue = [NSMutableArray array];
_accumulatedGifts = [NSMutableDictionary dictionary];
_waitingUpdateGifts = [NSMutableDictionary dictionary];
_isProcessingQueue = NO;
}
return self;
}
- (void)setupDisplayViewInContainer:(UIView *)container {
self.containerView = container;
[self createDisplayViews];
}
- (void)createDisplayViews {
if (self.displayViews.count > 0) return;
CGFloat viewHeight = 40;
CGFloat spacing = 10;
CGFloat topMargin = 400;
CGFloat width = 290;
for (int i = 0; i < 3; i++) {
CGFloat y = topMargin + (viewHeight + spacing) * i;
CGRect frame = CGRectMake(0, y, width, viewHeight);
QXGiftDisplayView *displayView = [[QXGiftDisplayView alloc] initWithFrame:frame];
displayView.delegate = self;
displayView.tag = 1000 + i; // 设置tag便于调试
displayView.alpha = 0.0;
[self.containerView addSubview:displayView];
[self.displayViews addObject:displayView];
NSLog(@"创建飘屏视图 %d", i);
}
}
- (void)receiveGift:(QXRoomChatListModel *)gift {
if (!gift) return;
dispatch_async(dispatch_get_main_queue(), ^{
[self internalReceiveGift:gift];
});
}
- (void)internalReceiveGift:(QXRoomChatListModel *)gift {
// 查找正在显示的同类型礼物
QXGiftDisplayView *displayingView = [self findDisplayingViewForGift:gift];
if (displayingView) {
// 找到正在显示的视图,直接累加
NSString *key = [self giftKeyForGift:gift];
QXRoomChatListModel *accumulatedGift = self.accumulatedGifts[key];
if (accumulatedGift) {
NSInteger gift_num = accumulatedGift.gift_num.integerValue;
gift_num += gift.gift_num.integerValue;
accumulatedGift.gift_num = [NSString stringWithFormat:@"%ld",gift_num];
[displayingView updateGiftCount:accumulatedGift.gift_num.integerValue];
NSLog(@"礼物累加: %@ x%@", gift.GiftInfo.gift_name, accumulatedGift.gift_num);
}
} else {
// 新礼物,检查是否可以立即显示
QXGiftDisplayView *availableView = [self findAvailableDisplayView];
if (availableView) {
// 有可用视图,立即显示
NSString *key = [self giftKeyForGift:gift];
self.accumulatedGifts[key] = [gift copy];
[availableView showGift:gift];
NSLog(@"立即显示礼物在视图 %ld", (long)availableView.tag);
} else {
// 没有可用视图,加入队列
[self.giftQueue addObject:gift];
NSLog(@"加入队列,当前队列长度: %lu", (unsigned long)self.giftQueue.count);
}
}
// 处理队列
[self processGiftQueue];
}
- (QXGiftDisplayView *)findDisplayingViewForGift:(QXRoomChatListModel *)gift {
for (QXGiftDisplayView *view in self.displayViews) {
if (view.isAnimating && [view.currentGift isSameGiftFromSameSender:gift]) {
return view;
}
}
return nil;
}
- (QXGiftDisplayView *)findAvailableDisplayView {
for (QXGiftDisplayView *view in self.displayViews) {
if (!view.isAnimating) {
return view;
}
}
return nil;
}
- (void)processGiftQueue {
if (self.isProcessingQueue) {
return;
}
self.isProcessingQueue = YES;
// 循环处理队列直到队列为空或没有可用视图
while (self.giftQueue.count > 0) {
QXGiftDisplayView *availableView = [self findAvailableDisplayView];
if (!availableView) {
break;
}
QXRoomChatListModel *gift = self.giftQueue.firstObject;
[self.giftQueue removeObjectAtIndex:0];
// 检查是否已经有同类型礼物在显示
QXGiftDisplayView *displayingView = [self findDisplayingViewForGift:gift];
if (!displayingView) {
NSString *key = [self giftKeyForGift:gift];
self.accumulatedGifts[key] = [gift copy];
[availableView showGift:gift];
NSLog(@"从队列显示礼物: %@", gift.GiftInfo.gift_name);
} else {
// 如果已经在显示,累加到现有视图
NSString *key = [self giftKeyForGift:gift];
QXRoomChatListModel *accumulatedGift = self.accumulatedGifts[key];
if (accumulatedGift) {
NSInteger gift_num = accumulatedGift.gift_num.integerValue;
gift_num += gift.gift_num.integerValue;
accumulatedGift.gift_num = [NSString stringWithFormat:@"%ld",gift_num];
[displayingView updateGiftCount:accumulatedGift.gift_num.integerValue];
NSLog(@"队列礼物累加到现有显示: %@ x%@", gift.GiftInfo.gift_name, accumulatedGift.gift_num);
}
}
}
self.isProcessingQueue = NO;
// 打印队列状态
if (self.giftQueue.count > 0) {
NSLog(@"队列中还有 %lu 个礼物等待显示", (unsigned long)self.giftQueue.count);
}
}
- (NSString *)giftKeyForGift:(QXRoomChatListModel *)gift {
return [NSString stringWithFormat:@"%@_%@_%@", gift.FromUserInfo.nickname ?: @"unknown", gift.GiftInfo.gift_id ?: @"unknown",gift.ToUserInfo.nickname ?: @"unknown"];
}
#pragma mark - QXGiftDisplayViewDelegate
- (void)QXGiftDisplayViewDidFinishAnimation:(QXGiftDisplayView *)view {
NSLog(@"飘屏动画结束: %ld", (long)view.tag);
// 从累加记录中移除
if (view.currentGift) {
NSString *key = [self giftKeyForGift:view.currentGift];
[self.accumulatedGifts removeObjectForKey:key];
NSLog(@"移除累加记录: %@", key);
}
// 重置视图状态
view.currentGift = nil;
view.isAnimating = NO;
// 延迟一下再处理队列,确保视图状态完全重置
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self processGiftQueue];
});
}
- (void)clearAll {
NSLog(@"清空所有礼物和队列");
for (QXGiftDisplayView *view in self.displayViews) {
[view finishAnimationImmediately];
[view removeFromSuperview];
}
[self.displayViews removeAllObjects];
[self.giftQueue removeAllObjects];
[self.accumulatedGifts removeAllObjects];
[self.waitingUpdateGifts removeAllObjects];
self.isProcessingQueue = NO;
}
// 调试方法
- (void)printDebugInfo {
NSLog(@"=== 飘屏管理器状态 ===");
NSLog(@"队列长度: %lu", (unsigned long)self.giftQueue.count);
NSLog(@"累加记录: %lu", (unsigned long)self.accumulatedGifts.count);
for (int i = 0; i < self.displayViews.count; i++) {
QXGiftDisplayView *view = self.displayViews[i];
NSLog(@"视图 %d: 动画中=%@, 礼物=%@", i, view.isAnimating ? @"" : @"", view.currentGift.GiftInfo.gift_name ?: @"");
}
NSLog(@"====================");
}
@end