chatapp3-flutter/lib/services/gift/gift_animation_manager.dart
2026-04-20 18:52:03 +08:00

140 lines
4.1 KiB
Dart

import 'dart:collection';
import 'package:flutter/cupertino.dart';
import 'package:yumi/ui_kit/widgets/room/anim/l_gift_animal_view.dart';
class GiftAnimationManager extends ChangeNotifier {
static const int _maxPendingAnimations = 24;
Queue<LGiftModel> pendingAnimationsQueue = Queue<LGiftModel>();
List<LGiftScrollingScreenAnimsBean> animationControllerList = [];
//每个控件正在播放的动画
Map<int, LGiftModel?> giftMap = {0: null, 1: null, 2: null, 3: null};
bool get _controllersReady =>
animationControllerList.length >= giftMap.length;
void enqueueGiftAnimation(LGiftModel giftModel) {
if (_mergeIntoActiveAnimation(giftModel)) {
return;
}
if (_mergeIntoPendingAnimation(giftModel)) {
return;
}
_trimPendingAnimations();
pendingAnimationsQueue.add(giftModel);
proceedToNextAnimation();
}
void _trimPendingAnimations() {
while (pendingAnimationsQueue.length >= _maxPendingAnimations) {
pendingAnimationsQueue.removeFirst();
}
}
bool _mergeIntoActiveAnimation(LGiftModel incoming) {
for (final entry in giftMap.entries) {
final current = entry.value;
if (current == null || current.labelId != incoming.labelId) {
continue;
}
_mergeGiftModel(target: current, incoming: incoming);
notifyListeners();
if (animationControllerList.length > entry.key) {
animationControllerList[entry.key].controller.forward(from: 0.45);
}
return true;
}
return false;
}
bool _mergeIntoPendingAnimation(LGiftModel incoming) {
for (final pending in pendingAnimationsQueue) {
if (pending.labelId != incoming.labelId) {
continue;
}
_mergeGiftModel(target: pending, incoming: incoming);
return true;
}
return false;
}
void _mergeGiftModel({
required LGiftModel target,
required LGiftModel incoming,
}) {
target.giftCount = (target.giftCount) + (incoming.giftCount);
if (target.sendUserName.isEmpty) {
target.sendUserName = incoming.sendUserName;
}
if (target.sendToUserName.isEmpty) {
target.sendToUserName = incoming.sendToUserName;
}
if (target.sendUserPic.isEmpty) {
target.sendUserPic = incoming.sendUserPic;
}
if (target.giftPic.isEmpty) {
target.giftPic = incoming.giftPic;
}
if (target.giftName.isEmpty) {
target.giftName = incoming.giftName;
}
if (incoming.rewardAmountText.isNotEmpty) {
target.rewardAmountText = incoming.rewardAmountText;
}
target.showLuckyRewardFrame =
target.showLuckyRewardFrame || incoming.showLuckyRewardFrame;
}
///开始播放
proceedToNextAnimation() {
if (pendingAnimationsQueue.isEmpty || !_controllersReady) {
return;
}
var playGift = pendingAnimationsQueue.first;
for (var key in giftMap.keys) {
var value = giftMap[key];
if (value == null) {
giftMap[key] = playGift;
pendingAnimationsQueue.removeFirst();
notifyListeners();
animationControllerList[key].controller.forward(from: 0);
break;
} else {
if (value.labelId == playGift.labelId) {
_mergeGiftModel(target: value, incoming: playGift);
pendingAnimationsQueue.removeFirst();
notifyListeners();
animationControllerList[key].controller.forward(from: 0.45);
break;
}
}
}
}
void attachAnimationControllers(List<LGiftScrollingScreenAnimsBean> anins) {
animationControllerList = anins;
proceedToNextAnimation();
}
void cleanupAnimationResources() {
pendingAnimationsQueue.clear();
giftMap[0] = null;
giftMap[1] = null;
giftMap[2] = null;
giftMap[3] = null;
for (var element in animationControllerList) {
element.controller.dispose();
}
animationControllerList.clear();
}
void markAnimationAsFinished(int index) {
giftMap[index] = null;
notifyListeners();
proceedToNextAnimation();
}
}