Files
featherVoice/QXLive/Room(房间)/View/礼物特效/QXGiftDisplayManager.m

238 lines
8.0 KiB
Mathematica
Raw Normal View History

2025-10-20 20:05:55 +08:00
//
// 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;
2025-10-21 11:36:48 +08:00
CGFloat topMargin = 400;
CGFloat width = 290;
2025-10-20 20:05:55 +08:00
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