新增 CP SVGA 逻辑迁移测试报告,详细记录了在 MicMidpointRectManager 中新增的 CP 业务逻辑方法及其在 XPRoomViewController 中的简化调用。修复了编译错误,优化了代码结构,提升了可维护性和可测试性。同时,更新了 MicMidpointRectManager 的头文件,添加了新方法的声明,确保代码一致性和清晰性。

This commit is contained in:
edwinQQQ
2025-09-15 16:12:41 +08:00
parent 645be6184e
commit 6470c642eb
18 changed files with 10449 additions and 10019 deletions

View File

@@ -1071,7 +1071,7 @@ XPCandyTreeInsufficientBalanceViewDelegate>
// 🔧 stage viewCPAPI
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
[self callMicCpListByUidListOnMicChangeWithQueue:currentQueue];
[self callMicCpListByUidListWithQueue:currentQueue];
// 🔧 19 micposition 6
[self checkCentralPositionUserQualification:currentQueue];
@@ -2566,10 +2566,52 @@ XPCandyTreeInsufficientBalanceViewDelegate>
break;
}
break;
case CustomMessageType_CP:
switch (attachment.second) {
case Custom_Message_Sub_CP_Binding:
case Custom_Message_Sub_CP_Upgrade:
[self handleCPBindingOrUpgradeMessage:attachment];
break;
}
break;
}
}
}
/// CP
- (void)handleCPBindingOrUpgradeMessage:(AttachmentModel *)attachment {
NSLog(@"🔧 处理CP绑定或升级消息first=%ld, second=%ld", (long)attachment.first, (long)attachment.second);
// CP
if (!self.hasCompletedRoomInitialization) {
NSLog(@"🔧 进房初始化中跳过CP绑定/升级处理");
return;
}
//
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
if (!currentQueue) {
NSLog(@"⚠️ 无法获取当前麦位队列跳过CP绑定/升级处理");
return;
}
// 使 MicMidpointRectManager CP/
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager handleCPBindingOrUpgradeMessageWithStageView:self.stageView
micCount:micCount
queue:currentQueue];
}
// CP API
[self callMicCpListByUidListWithQueue:currentQueue];
NSLog(@"✅ CP绑定/升级消息处理完成");
}
/// CP
- (void)handleMicChangeForCP:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
NSLog(@"🔧 处理麦位变化相关的CP逻辑");
@@ -2577,19 +2619,22 @@ XPCandyTreeInsufficientBalanceViewDelegate>
//
[self updateCurrentUserMicStatus:queue];
//
[self updateMicMidpointRectManagerSnapshot];
// CP
if (self.hasCompletedRoomInitialization) {
// CP
[self handleDownMicEventIfNeeded:queue];
// 🔧 micCP SVGA
[self handleMicSwitchScenarioIfNeeded:queue];
// 使 MicMidpointRectManager CP
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager handleMicChangeForCPWithStageView:self.stageView
micCount:micCount
queue:queue
currentUserUid:[AccountInfoStorage instance].getUid.integerValue
roomType:self.roomInfo.type];
}
// CP API
[self callMicCpListByUidListOnMicChangeWithQueue:queue];
[self callMicCpListByUidListWithQueue:queue];
// 🔧 19 mic
[self checkCentralPositionUserQualification:queue];
@@ -2640,8 +2685,11 @@ XPCandyTreeInsufficientBalanceViewDelegate>
// CP
self.currentCpList = cpList.copy;
// MicMidpointRectManager
[self updateMicMidpointRectManagerCache:cpList];
// 使 MicMidpointRectManager CP
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
[manager handleMicRelationshipCPMessage:cpList];
}
// CP SVGA
[self drawSocialStageMidpointRects];
@@ -3208,28 +3256,42 @@ XPCandyTreeInsufficientBalanceViewDelegate>
[[RoomBoomManager sharedManager] receiveEnterRoomBoom:model];
}
- (void)getMicCpListByRoomUidSuccess:(NSArray <MicCpInfoModel *> *)cpList {
self.currentCpList = cpList;
// MicMidpointRectManager
[self updateMicMidpointRectManagerCache:cpList];
// CPSVGA
[self drawSocialStageMidpointRects];
}
- (void)getMicCpListByUidListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
/// CP API
- (void)handleMicCpListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
NSLog(@"🔧 CP API成功回调接收到 %lu 条CP数据", (unsigned long)cpList.count);
self.currentCpList = cpList;
// 🔧 MicMidpointRectManager
[self updateMicMidpointRectManagerCache:cpList];
// CPSVGA
[self drawSocialStageMidpointRects];
// 使 MicMidpointRectManager CP
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager updateCpListCacheAndRedraw:cpList
stageView:self.stageView
micCount:micCount
roomType:self.roomInfo.type];
}
// NIM message
if (self.currentUserMicStatusChanged) {
[self sendMicRelationshipNIMessage:cpList];
self.currentUserMicStatusChanged = NO; //
}
NSLog(@"🔧 CP API成功回调处理完成");
}
/// UIDCP
- (void)getMicCpListByRoomUidSuccess:(NSArray <MicCpInfoModel *> *)cpList {
NSLog(@"🔧 按房间UID获取CP列表成功接收到 %lu 条CP数据", (unsigned long)cpList.count);
[self handleMicCpListSuccess:cpList];
}
/// UIDCP
- (void)getMicCpListByUidListSuccess:(NSArray<MicCpInfoModel *> *)cpList {
NSLog(@"🔧 按用户UID列表获取CP列表成功接收到 %lu 条CP数据", (unsigned long)cpList.count);
[self handleMicCpListSuccess:cpList];
}
#pragma mark - 退
@@ -3640,110 +3702,17 @@ XPCandyTreeInsufficientBalanceViewDelegate>
return;
}
NSString *stageViewClass = NSStringFromClass([self.stageView class]);
NSLog(@"🔧 开始绘制 %@ 中点矩形", stageViewClass);
//
if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
// 使
id manager = [self.stageView valueForKey:@"midpointRectManager"];
if ([manager respondsToSelector:@selector(removeAllMidpointRects)]) {
[manager removeAllMidpointRects];
}
//
if ([manager respondsToSelector:@selector(setRoomType:)]) {
[manager setRoomType:self.roomInfo.type];
}
// 使 MicMidpointRectManager
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager drawSocialStageMidpointRectsWithStageView:self.stageView
micCount:micCount
roomType:self.roomInfo.type];
} else {
//
NSArray<UIView *> *subviews = [self.stageView.subviews copy];
for (UIView *view in subviews) {
if (view.tag == 56002) {
[view removeFromSuperview];
}
}
NSLog(@"🔧 无法获取 midpointRectManager跳过中点矩形绘制");
}
// StageView
NSArray *validPairs = nil;
if ([self.stageView isKindOfClass:[SocialStageView class]]) {
validPairs = @[@[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8]];
} else if ([self.stageView isKindOfClass:[TenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9]];
} else if ([self.stageView isKindOfClass:[FifteenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9], @[@10, @11], @[@11, @12], @[@12, @13], @[@13, @14]];
} else if ([self.stageView isKindOfClass:[NineteenMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@8, @9], @[@10, @11], @[@12, @13], @[@14, @15], @[@15, @16], @[@16, @17], @[@17, @18]];
} else if ([self.stageView isKindOfClass:[TwentyMicStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@5, @6], @[@6, @7], @[@7, @8], @[@8, @9], @[@10, @11], @[@11, @12], @[@12, @13], @[@13, @14], @[@15, @16], @[@16, @17], @[@17, @18], @[@18, @19]];
} else if ([self.stageView isKindOfClass:[AnchorStageView class]]) {
validPairs = @[@[@1, @2], @[@2, @3]];
} else if ([self.stageView isKindOfClass:[DatingStageView class]]) {
validPairs = @[@[@1, @2], @[@3, @4], @[@5, @6], @[@7, @8]];
} else if ([self.stageView isKindOfClass:[LittleGameStageView class]]) {
validPairs = @[@[@0, @1], @[@1, @2], @[@2, @3], @[@3, @4], @[@4, @5]];
} else if ([self.stageView isKindOfClass:[LittleGameScrollStageView class]]) {
//
NSInteger micCount = [self.stageView countOfMicroView];
NSMutableArray *pairs = [NSMutableArray array];
for (NSInteger i = 0; i < micCount - 1; i++) {
[pairs addObject:@[@(i), @(i + 1)]];
}
validPairs = pairs;
} else if ([self.stageView isKindOfClass:[AnchorPKStageView class]]) {
validPairs = @[@[@0, @1]];
} else {
NSLog(@"🔧 未支持的 StageView 类型: %@", stageViewClass);
return;
}
NSLog(@"🔧 开始绘制 %@ 中点矩形,共 %lu 对相邻麦位", stageViewClass, (unsigned long)validPairs.count);
for (NSArray *pair in validPairs) {
NSInteger firstIndex = [pair[0] integerValue];
NSInteger secondIndex = [pair[1] integerValue];
CGRect rect = [self.stageView rectForMidpointBetweenMicAtIndex:firstIndex andIndex:secondIndex];
if (!CGRectIsEmpty(rect)) {
UIView *micRelationshipView = [[UIView alloc] initWithFrame:rect];
micRelationshipView.backgroundColor = [[UIColor blueColor] colorWithAlphaComponent:0.3];
micRelationshipView.layer.borderColor = [UIColor blueColor].CGColor;
micRelationshipView.layer.borderWidth = 2.0;
micRelationshipView.layer.cornerRadius = 8.0;
micRelationshipView.tag = 56002;
micRelationshipView.userInteractionEnabled = NO;
//
UILabel *label = [[UILabel alloc] init];
label.text = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
label.textColor = [UIColor whiteColor];
label.font = [UIFont boldSystemFontOfSize:12];
label.textAlignment = NSTextAlignmentCenter;
label.frame = micRelationshipView.bounds;
[micRelationshipView addSubview:label];
// midpointRectManager SVGA退
if ([self.stageView respondsToSelector:@selector(midpointRectManager)]) {
id manager = [self.stageView valueForKey:@"midpointRectManager"];
if ([manager respondsToSelector:@selector(addRelationshipAtFrame:micPairText:leftUid:rightUid:cpList:)]) {
NSString *micPairText = [NSString stringWithFormat:@"%ld-%ld", (long)firstIndex, (long)secondIndex];
UIView<MicroViewProtocol> *leftView = [self.stageView findMicroViewByIndex:firstIndex];
UIView<MicroViewProtocol> *rightView = [self.stageView findMicroViewByIndex:secondIndex];
NSInteger leftUid = [[leftView getUser] uid];
NSInteger rightUid = [[rightView getUser] uid];
[manager addRelationshipAtFrame:rect micPairText:micPairText leftUid:leftUid rightUid:rightUid cpList:self.currentCpList ?: @[]];
}
} else {
[self.stageView addSubview:micRelationshipView];
}
NSLog(@"🔧 绘制中点矩形: %ld-%ld, rect: %@", (long)firstIndex, (long)secondIndex, NSStringFromCGRect(rect));
} else {
NSLog(@"🔧 跳过无效麦位对: %ld-%ld", (long)firstIndex, (long)secondIndex);
}
}
NSLog(@"🔧 %@ 中点矩形绘制完成", stageViewClass);
}
/// CPAPI
@@ -3783,7 +3752,8 @@ XPCandyTreeInsufficientBalanceViewDelegate>
if (currentUserMicPosition == -1) {
NSLog(@"🔧 获取mic用户列表当前用户不在麦上返回空数据");
// manager UID
[self removeCurrentUserCpDataFromManager];
NSInteger currentUid = [AccountInfoStorage instance].getUid.integerValue;
[self removeCpDataForUids:@[@(currentUid)]];
return micUserUids;
}
@@ -3839,12 +3809,10 @@ XPCandyTreeInsufficientBalanceViewDelegate>
}
}
//
// 🔧 使UIDNIM message
if (micUserUids.count == 1) {
NSLog(@"🔧 获取mic用户列表只有当前用户一个人返回空数据");
// manager UID
[self removeCurrentUserCpDataFromManager];
return [NSArray array];
NSLog(@"🔧 获取mic用户列表只有当前用户一个人但仍需发送NIM message");
// UIDCP APINIM message
}
NSLog(@"🔧 获取mic用户列表当前用户麦位 %ld找到 %lu 个相关用户: %@",
@@ -3852,6 +3820,7 @@ XPCandyTreeInsufficientBalanceViewDelegate>
return micUserUids;
}
/// mic
- (void)handleOtherUserMicChange:(UserInfoModel *)userInfo changeType:(NSInteger)changeType {
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
@@ -3859,178 +3828,102 @@ XPCandyTreeInsufficientBalanceViewDelegate>
return;
}
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (!midpointRectManager) {
NSLog(@"🔧 处理其他用户mic变化无法获取 midpointRectManager跳过处理");
//
NSMutableDictionary<NSString *,MicroQueueModel *> *currentQueue = [self.stageView getMicroQueue];
if (!currentQueue) {
NSLog(@"🔧 处理其他用户mic变化无法获取当前麦位队列跳过处理");
return;
}
//
midpointRectManager.roomType = self.roomInfo.type;
NSInteger userUid = userInfo.uid;
NSArray<NSNumber *> *userUids = @[@(userUid)];
if (changeType == 2) {
//
NSLog(@"🔧 处理其他用户下麦UID %ld", (long)userUid);
//
[self updateMicMidpointRectManagerSnapshot];
// cpSVGA
[midpointRectManager removeCpEntriesForUids:userUids];
[midpointRectManager removeMidpointRectsForUids:userUids];
//
[self drawSocialStageMidpointRects];
NSLog(@"🔧 其他用户下麦处理完成UID %ld", (long)userUid);
} else if (changeType == 1) {
//
NSLog(@"🔧 处理其他用户上麦UID %ld", (long)userUid);
//
[self updateMicMidpointRectManagerSnapshot];
// CPCP
[self drawSocialStageMidpointRects];
NSLog(@"🔧 其他用户上麦处理完成UID %ld", (long)userUid);
}
}
/// CPmanager
- (void)removeCurrentUserCpDataFromManager {
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
NSLog(@"🔧 移除当前用户CP数据stageView 不支持 midpointRectManager跳过处理");
return;
// 使 MicMidpointRectManager mic
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
//
NSInteger micCount = [self getMicCountForRoomType:self.roomInfo.type];
[manager handleOtherUserMicChange:userInfo
changeType:changeType
stageView:self.stageView
micCount:micCount
queue:currentQueue
roomType:self.roomInfo.type];
}
NSInteger currentUid = [AccountInfoStorage instance].getUid.integerValue;
NSArray<NSNumber *> *removedUids = @[@(currentUid)];
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (midpointRectManager) {
//
midpointRectManager.roomType = self.roomInfo.type;
//
[midpointRectManager removeCpEntriesForUids:removedUids];
// UI
[midpointRectManager removeMidpointRectsForUids:removedUids];
NSLog(@"🔧 移除当前用户CP数据完成UID %ld", (long)currentUid);
}
}
/// micCP SVGA
- (void)handleMicSwitchScenarioIfNeeded:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
NSLog(@"🔧 处理切换mic场景stageView 不支持 midpointRectManager跳过处理");
return;
}
// 🔧
//
BOOL hasMicPositionChanged = self.currentUserMicStatusChanged;
if (hasMicPositionChanged) {
NSLog(@"🔧 检测到当前用户麦位状态变化可能是切换mic场景");
//
NSInteger micCount = 0;
if (self.roomInfo) {
switch (self.roomInfo.type) {
case RoomType_Room: micCount = 9; break;
case RoomType_10Mic: micCount = 10; break;
case RoomType_15Mic: micCount = 15; break;
case RoomType_19Mic: micCount = 19; break;
case RoomType_20Mic: micCount = 20; break;
default: micCount = 9; break;
// API
if (changeType == 2) { //
//
NSMutableArray<NSString *> *remainingUids = [NSMutableArray array];
for (NSString *positionKey in currentQueue.allKeys) {
MicroQueueModel *micModel = currentQueue[positionKey];
if (micModel && micModel.userInfo && micModel.userInfo.uid > 0) {
[remainingUids addObject:[NSString stringWithFormat:@"%ld", (long)micModel.userInfo.uid]];
}
}
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (midpointRectManager) {
//
midpointRectManager.roomType = self.roomInfo.type;
// CP
// 1. SVGA
[midpointRectManager removeAllMidpointRects];
// 2.
[midpointRectManager rebuildMicSnapshotWithStageView:self.stageView micCount:micCount];
// 3. CP
[self drawSocialStageMidpointRects];
NSLog(@"🔧 用户麦位变化场景处理完成重新构建了所有CP关系");
// APICP
if (remainingUids.count > 0) {
[self.presenter micCpListByUidList:remainingUids];
}
// 🔧 API
// getMicCpListByUidListSuccess
} else {
NSLog(@"🔧 当前用户麦位状态未变化,跳过切换场景处理");
//
[self drawSocialStageMidpointRects];
} else if (changeType == 1) { //
// CP API
[self callMicCpListByUidListWithQueue:currentQueue];
// CP
[self drawSocialStageMidpointRects];
}
}
///
- (void)handleDownMicEventIfNeeded:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
/// CP
- (void)removeCpDataForUids:(NSArray<NSNumber *> *)uids {
if (!self.stageView || ![self.stageView respondsToSelector:@selector(midpointRectManager)]) {
NSLog(@"🔧 处理下麦事件stageView 不支持 midpointRectManager跳过处理");
NSLog(@"🔧 移除CP数据stageView 不支持 midpointRectManager跳过处理");
return;
}
//
NSInteger micCount = 0;
if (self.roomInfo) {
switch (self.roomInfo.type) {
case RoomType_Room: micCount = 9; break;
case RoomType_10Mic: micCount = 10; break;
case RoomType_15Mic: micCount = 15; break;
case RoomType_19Mic: micCount = 19; break;
case RoomType_20Mic: micCount = 20; break;
default: micCount = 9; break;
}
if (uids.count == 0) {
NSLog(@"🔧 移除CP数据没有需要移除的用户跳过处理");
return;
}
// 使 MicMidpointRectManager
// MicMidpointRectManager *midpointRectManager = [self.stageView midpointRectManager];
MicMidpointRectManager *midpointRectManager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (midpointRectManager) {
//
midpointRectManager.roomType = self.roomInfo.type;
NSDictionary<NSString *, NSArray<NSNumber *> *> *micChanges =
[midpointRectManager diffMicChangeWithStageView:self.stageView micCount:micCount];
NSArray<NSNumber *> *removedUids = micChanges[@"removed"];
if (removedUids && removedUids.count > 0) {
NSLog(@"🔧 检测到下麦用户:%@", removedUids);
// MicMidpointRectManager
[midpointRectManager handleDownMicEvent:removedUids stageView:self.stageView micCount:micCount];
}
// 使 MicMidpointRectManager CP
MicMidpointRectManager *manager = (MicMidpointRectManager *)[self.stageView performSelector:@selector(midpointRectManager)];
if (manager) {
[manager removeCpDataForUids:uids];
NSLog(@"🔧 移除CP数据完成UIDs %@", uids);
}
}
/// micCPAPI
- (void)callMicCpListByUidListOnMicChangeWithQueue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
NSLog(@"🔧 mic位变动开始调用 micCpListByUidList API");
/// CP API
- (void)callMicCpListByUidListWithQueue:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
NSLog(@"🔧 调用CP API开始获取mic用户列表");
NSArray<NSString *> *micUserUids = [self getAllMicUserUidsWithQueue:queue];
// queuemicuid
NSMutableArray<NSString *> *micUserUids = [NSMutableArray array];
if (queue) {
for (NSString *positionKey in queue.allKeys) {
MicroQueueModel *micModel = queue[positionKey];
if (micModel && micModel.userInfo && micModel.userInfo.uid > 0) {
[micUserUids addObject:[NSString stringWithFormat:@"%ld", (long)micModel.userInfo.uid]];
}
}
}
if (micUserUids.count == 0) {
NSLog(@"🔧 mic位变动:没有相关用户在mic上跳过API调用");
NSLog(@"🔧 调用CP API没有用户在mic上跳过API调用");
return;
}
// micCpListByUidList
if ([micUserUids containsObject:[AccountInfoStorage instance].getUid]) {
NSLog(@"🔧 mic位变动且包含了当前用户调用 micCpListByUidList: %@", micUserUids);
[self.presenter micCpListByUidList:micUserUids];
}
NSLog(@"🔧 调用CP APImicCpListByUidList: %@", micUserUids);
[self.presenter micCpListByUidList:micUserUids];
NSLog(@"🔧 mic位变动micCpListByUidList API调用完成");
NSLog(@"🔧 调用CP API完成");
}
///
@@ -4294,6 +4187,18 @@ XPCandyTreeInsufficientBalanceViewDelegate>
}
}
///
- (NSInteger)getMicCountForRoomType:(NSInteger)roomType {
switch (roomType) {
case RoomType_Room: return 9;
case RoomType_10Mic: return 10;
case RoomType_15Mic: return 15;
case RoomType_19Mic: return 19;
case RoomType_20Mic: return 20;
default: return 9;
}
}
/// 19 micposition 6
- (void)checkCentralPositionUserQualification:(NSMutableDictionary<NSString *,MicroQueueModel *> *)queue {
// 19 mic