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 pendingAnimationsQueue = Queue(); List animationControllerList = []; //每个控件正在播放的动画 Map 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; } target.rewardAmount = target.rewardAmount + incoming.rewardAmount; 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 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(); } }