Files
peko-ios/YuMi/Modules/YMRoom/View/SendGiftView/GiftComboManager.m

279 lines
8.7 KiB
Objective-C

//
// GiftComboManager.m
// YuMi
//
// Created by P on 2024/9/5.
//
// 处理连击面板逻辑
#import "GiftComboManager.h"
#import "UserInfoModel.h"
#import "AttachmentModel.h"
#import "GiftReceiveInfoModel.h"
#import "XPMessageRemoteExtModel.h"
#import "Api+Gift.h"
@interface GiftComboManager ()
// 用来存储 GiftReceiveInfoModel 和 NSDictionary 的元数据队列
@property (nonatomic, strong) NSMutableArray *giftComboQueue;
// 定时器,处理请求的调度器
@property (nonatomic, strong) dispatch_source_t timer;
@property (nonatomic, copy) NSArray *sendGiftToUIDs;
@property (nonatomic, assign) GiftSourceType giftSourceType;
@property (nonatomic, strong) GiftInfoModel *giftInfo;
@property (nonatomic, assign) RoomSendGiftType roomSendGiftType;
@property (nonatomic, copy) NSString *roomUID;
@property (nonatomic, copy) NSString *giftNumPerTimes;
@property (nonatomic, strong) UserInfoModel *sendGiftUserInfo;
@property (nonatomic, copy) NSString *sessionID;
@property (nonatomic, assign) NSInteger combo;
@end
@implementation GiftComboManager
#pragma mark - 单例方法
+ (instancetype)sharedManager {
static GiftComboManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
sharedInstance.giftComboQueue = [NSMutableArray array];
});
return sharedInstance;
}
// 添加 GiftReceiveInfoModel 和 metadata 到队列
- (void)addGiftComboWithInfo:(GiftReceiveInfoModel *)info andMetadata:(NSDictionary *)metadata {
if (info && metadata) {
// 将元数据打包成字典并添加到队列
@synchronized (self) {
NSDictionary *comboData = @{@"info": info, @"metadata": metadata};
[self.giftComboQueue addObject:comboData];
}
// 启动定时器
[self startProcessingQueue];
}
}
- (void)addComboFromNIMAttachment:(AttachmentModel *)attachment {
if (attachment) {
// 将元数据打包成字典并添加到队列
@synchronized (self) {
[self.giftComboQueue addObject:attachment];
}
// 启动定时器
[self startProcessingQueue];
}
}
// 开始连击,重置
- (void)resetCombo {
_combo = 1;
}
// MARK: Logic is 连击面板出现后,每点击一次,就触发一次面板最后的请求,请求成功后,构造云信消息体,消息体进入队列并按 0.2s 一次的频率发送消息
#pragma mark - 管理队列
// 开始处理队列
- (void)startProcessingQueue {
if (self.timer) {
return; // 如果定时器已经在运行,直接返回
}
// 创建 GCD 定时器
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
// 设置定时器时间间隔:每 0.2 秒执行一次
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC, 0.01 * NSEC_PER_SEC);
// 定时器触发的事件处理
dispatch_source_set_event_handler(self.timer, ^{
[self processGiftComboQueue];
});
// 启动定时器
dispatch_resume(self.timer);
}
// 停止处理队列
- (void)stopProcessingQueue {
if (self.timer) {
dispatch_source_cancel(self.timer);
self.timer = nil;
}
}
// 处理队列中的第一个请求
- (void)processGiftComboQueue {
@synchronized (self) {
if (self.giftComboQueue.count > 0) {
// 获取并移除队列中的第一个元数据
AttachmentModel *attachment = [self.giftComboQueue firstObject];
[self.giftComboQueue removeObjectAtIndex:0];
// 处理逻辑
[self processGiftComboWith:attachment];
} else {
// 如果队列为空,停止定时器
[self stopProcessingQueue];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"礼物处理完成");
});
}
}
}
// 处理元数据的实际逻辑
- (void)processGiftComboWith:(AttachmentModel *)info {
[self sendCustomMessage:info];
}
#pragma mark - Gift meta data
- (void)saveSendGiftTo:(NSArray *)UIDs
{
_sendGiftToUIDs = UIDs;
}
- (void)saveGiftSourceType:(GiftSourceType)type
{
_giftSourceType = type;
}
- (void)saveSendGiftInfo:(GiftInfoModel *)model
{
_giftInfo = model;
}
- (void)saveSendGiftType:(RoomSendGiftType)type
{
_roomSendGiftType = type;
}
- (void)saveRoomUID:(NSString *)roomUID {
_roomUID = roomUID;
}
- (void)saveSendGiftNum:(NSString *)numString
{
_giftNumPerTimes = numString;
}
- (void)saveUserInfo:(UserInfoModel *)userInfo {
_sendGiftUserInfo = userInfo;
}
- (void)saveSessionID:(NSString *)sessionID {
_sessionID = sessionID;
}
#pragma mark - XPGiftPresenter
- (void)sendGift {
NSString *allUIDs = @"";
for (NSString *item in self.sendGiftToUIDs) {
if (allUIDs.length > 0) {
allUIDs = [allUIDs stringByAppendingString:@","];
}
allUIDs = [allUIDs stringByAppendingString:item];
}
@kWeakify(self);
[Api requestSendGift:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
@kStrongify(self);
if (code == 200) {
GiftReceiveInfoModel *receive = [GiftReceiveInfoModel modelWithJSON:data.data];
receive.sourceType = self.giftSourceType;
receive.roomSendGiftType = self.roomSendGiftType;
[self handleSendGiftSuccess:data];
} else {
// TODO: 发送失败处理
}
}
targetUids:allUIDs
giftNum:self.giftNumPerTimes
sendType:[NSString stringWithFormat:@"%ld", GiftSendType_OnMic]
giftId:[NSString stringWithFormat:@"%ld", self.giftInfo.giftId]
giftSource:[NSString stringWithFormat:@"%ld", self.giftSourceType]
giftType:[NSString stringWithFormat:@"%ld", self.giftInfo.giftType]
roomUid:self.roomUID
msg:@""
uid:[AccountInfoStorage instance].getUid];
}
- (void)handleSendGiftSuccess:(BaseModel *)response {
GiftReceiveInfoModel *receive = [GiftReceiveInfoModel modelWithJSON:response.data];
if (!receive) {
return;
}
NSDictionary *tempDic = response.data;
NSMutableDictionary *data = [NSMutableDictionary dictionary];
[data addEntriesFromDictionary:tempDic];
AttachmentModel *attachment = [[AttachmentModel alloc] init];
switch (receive.roomSendGiftType) {
case RoomSendGiftType_AllMic: {
attachment.first = CustomMessageType_AllMicroSend;
attachment.second = Custom_Message_Sub_AllMicroSend;
[data setObject:[tempDic valueForKeyPath:@"targetUsers.uid"] forKey:@"targetUids"];
attachment.data = data;
}
break;
case RoomSendGiftType_MutableOnMic: {
attachment.first = CustomMessageType_AllMicroSend;
attachment.second = Custom_Message_Sub_AllBatchSend;
attachment.data = data;
}
break;
case RoomSendGiftType_ToOne: {
attachment.first = CustomMessageType_Gift;
attachment.second = Custom_Message_Sub_Gift_Send;
NSDictionary *targetUsers = ((NSArray *)[data objectForKey:@"targetUsers"]).firstObject;
[data setObject:[targetUsers valueForKeyPath:@"uid"] forKey:@"targetUid"];
[data setObject:[targetUsers valueForKeyPath:@"nick"] forKey:@"targetNick"];
[data setObject:[targetUsers valueForKeyPath:@"avatar"] forKey:@"targetAvatar"];
attachment.data = data;
}
break;
default:
attachment = nil;
break;
}
if (attachment) {
// TODO: 添加到队列
[self sendCustomMessage:attachment];
}
}
- (void)sendCustomMessage:(AttachmentModel *)attachment {
NIMMessage *message = [[NIMMessage alloc]init];
NIMCustomObject *object = [[NIMCustomObject alloc] init];
object.attachment = attachment;
message.messageObject = object;
UserInfoModel *userInfo = self.sendGiftUserInfo;
XPMessageRemoteExtModel *extModel = [[XPMessageRemoteExtModel alloc] init];
extModel.androidBubbleUrl = userInfo.androidBubbleUrl;
extModel.iosBubbleUrl = userInfo.iosBubbleUrl;
extModel.fromSayHelloChannel = userInfo.fromSayHelloChannel;
NSMutableDictionary *remoteExt = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary forKey:[NSString stringWithFormat:@"%ld", userInfo.uid]];
message.remoteExt = remoteExt;
//构造会话
NIMSession *session = [NIMSession session:self.sessionID type:NIMSessionTypeChatroom];
[[NIMSDK sharedSDK].chatManager sendMessage:message toSession:session error:nil];
}
@end