mirror of https://github.com/NekoX-Dev/NekoX.git
437 lines
17 KiB
Java
437 lines
17 KiB
Java
package org.telegram.ui.Components;
|
|
|
|
import android.graphics.Bitmap;
|
|
import android.text.TextUtils;
|
|
|
|
import org.telegram.messenger.AndroidUtilities;
|
|
import org.telegram.messenger.DownloadController;
|
|
import org.telegram.messenger.FileLoader;
|
|
import org.telegram.messenger.FileLog;
|
|
import org.telegram.messenger.MessageObject;
|
|
import org.telegram.messenger.UserConfig;
|
|
import org.telegram.messenger.Utilities;
|
|
import org.telegram.tgnet.TLRPC;
|
|
import org.telegram.ui.Cells.ChatMessageCell;
|
|
|
|
import java.io.File;
|
|
|
|
public class SlotsDrawable extends RLottieDrawable {
|
|
|
|
enum ReelValue {
|
|
bar,
|
|
berries,
|
|
lemon,
|
|
seven,
|
|
sevenWin
|
|
}
|
|
|
|
private ReelValue left;
|
|
private ReelValue center;
|
|
private ReelValue right;
|
|
|
|
private long[] nativePtrs = new long[5];
|
|
private int[] frameCounts = new int[5];
|
|
private int[] frameNums = new int[5];
|
|
private long[] secondNativePtrs = new long[3];
|
|
private int[] secondFrameCounts = new int[3];
|
|
private int[] secondFrameNums = new int[3];
|
|
|
|
private boolean playWinAnimation;
|
|
|
|
public SlotsDrawable(String diceEmoji, int w, int h) {
|
|
super(diceEmoji, w, h);
|
|
|
|
loadFrameRunnable = () -> {
|
|
if (isRecycled) {
|
|
return;
|
|
}
|
|
if (nativePtr == 0 || isDice == 2 && secondNativePtr == 0) {
|
|
if (frameWaitSync != null) {
|
|
frameWaitSync.countDown();
|
|
}
|
|
uiHandler.post(uiRunnableNoFrame);
|
|
return;
|
|
}
|
|
if (backgroundBitmap == null) {
|
|
try {
|
|
backgroundBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
} catch (Throwable e) {
|
|
FileLog.e(e);
|
|
}
|
|
}
|
|
if (backgroundBitmap != null) {
|
|
try {
|
|
int result;
|
|
if (isDice == 1) {
|
|
result = -1;
|
|
for (int a = 0; a < nativePtrs.length; a++) {
|
|
result = getFrame(nativePtrs[a], frameNums[a], backgroundBitmap, width, height, backgroundBitmap.getRowBytes(), a == 0);
|
|
if (a == 0) {
|
|
continue;
|
|
}
|
|
if (frameNums[a] + 1 < frameCounts[a]) {
|
|
frameNums[a]++;
|
|
} else if (a != 4) {
|
|
frameNums[a] = 0;
|
|
nextFrameIsLast = false;
|
|
if (secondNativePtr != 0) {
|
|
isDice = 2;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (setLastFrame) {
|
|
for (int a = 0; a < secondFrameNums.length; a++) {
|
|
secondFrameNums[a] = secondFrameCounts[a] - 1;
|
|
}
|
|
}
|
|
if (playWinAnimation) {
|
|
if (frameNums[0] + 1 < frameCounts[0]) {
|
|
frameNums[0]++;
|
|
} else {
|
|
frameNums[0] = -1;
|
|
}
|
|
}
|
|
getFrame(nativePtrs[0], Math.max(frameNums[0], 0), backgroundBitmap, width, height, backgroundBitmap.getRowBytes(), true);
|
|
for (int a = 0; a < secondNativePtrs.length; a++) {
|
|
getFrame(secondNativePtrs[a], secondFrameNums[a] >= 0 ? secondFrameNums[a] : (secondFrameCounts[a] - 1), backgroundBitmap, width, height, backgroundBitmap.getRowBytes(), false);
|
|
if (!nextFrameIsLast) {
|
|
if (secondFrameNums[a] + 1 < secondFrameCounts[a]) {
|
|
secondFrameNums[a]++;
|
|
} else {
|
|
secondFrameNums[a] = -1;
|
|
}
|
|
}
|
|
}
|
|
result = getFrame(nativePtrs[4], frameNums[4], backgroundBitmap, width, height, backgroundBitmap.getRowBytes(), false);
|
|
if (frameNums[4] + 1 < frameCounts[4]) {
|
|
frameNums[4]++;
|
|
}
|
|
if (secondFrameNums[0] == -1 && secondFrameNums[1] == -1 && secondFrameNums[2] == -1) {
|
|
nextFrameIsLast = true;
|
|
autoRepeatPlayCount++;
|
|
}
|
|
if (left == right && right == center) {
|
|
if (secondFrameNums[0] == secondFrameCounts[0] - 100) {
|
|
playWinAnimation = true;
|
|
if (left == ReelValue.sevenWin) {
|
|
Runnable runnable = onFinishCallback.get();
|
|
if (runnable != null) {
|
|
AndroidUtilities.runOnUIThread(runnable);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
frameNums[0] = -1;
|
|
}
|
|
}
|
|
if (result == -1) {
|
|
uiHandler.post(uiRunnableNoFrame);
|
|
if (frameWaitSync != null) {
|
|
frameWaitSync.countDown();
|
|
}
|
|
return;
|
|
}
|
|
nextRenderingBitmap = backgroundBitmap;
|
|
} catch (Exception e) {
|
|
FileLog.e(e);
|
|
}
|
|
}
|
|
uiHandler.post(uiRunnable);
|
|
if (frameWaitSync != null) {
|
|
frameWaitSync.countDown();
|
|
}
|
|
};
|
|
}
|
|
|
|
private ReelValue reelValue(int rawValue) {
|
|
switch (rawValue) {
|
|
case 0:
|
|
return ReelValue.bar;
|
|
case 1:
|
|
return ReelValue.berries;
|
|
case 2:
|
|
return ReelValue.lemon;
|
|
case 3:
|
|
default:
|
|
return ReelValue.seven;
|
|
}
|
|
}
|
|
|
|
private void init(int rawValue) {
|
|
rawValue--;
|
|
|
|
int leftRawValue = rawValue & 3;
|
|
int centerRawValue = rawValue >> 2 & 3;
|
|
int rightRawValue = rawValue >> 4;
|
|
|
|
ReelValue leftReelValue = reelValue(leftRawValue);
|
|
ReelValue centerReelValue = reelValue(centerRawValue);
|
|
ReelValue rightReelValue = reelValue(rightRawValue);
|
|
|
|
if (leftReelValue == ReelValue.seven && centerReelValue == ReelValue.seven && rightReelValue == ReelValue.seven) {
|
|
leftReelValue = ReelValue.sevenWin;
|
|
centerReelValue = ReelValue.sevenWin;
|
|
rightReelValue = ReelValue.sevenWin;
|
|
}
|
|
|
|
left = leftReelValue;
|
|
center = centerReelValue;
|
|
right = rightReelValue;
|
|
}
|
|
|
|
private boolean is777() {
|
|
return left == ReelValue.sevenWin && center == ReelValue.sevenWin && right == ReelValue.sevenWin;
|
|
}
|
|
|
|
public boolean setBaseDice(ChatMessageCell messageCell, TLRPC.TL_messages_stickerSet stickerSet) {
|
|
if (nativePtr != 0 || loadingInBackground) {
|
|
return true;
|
|
}
|
|
loadingInBackground = true;
|
|
MessageObject currentMessageObject = messageCell.getMessageObject();
|
|
int account = messageCell.getMessageObject().currentAccount;
|
|
Utilities.globalQueue.postRunnable(() -> {
|
|
if (destroyAfterLoading) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
loadingInBackground = false;
|
|
if (!secondLoadingInBackground && destroyAfterLoading) {
|
|
recycle();
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
boolean loading = false;
|
|
for (int a = 0; a < nativePtrs.length; a++) {
|
|
if (nativePtrs[a] != 0) {
|
|
continue;
|
|
}
|
|
int num;
|
|
if (a == 0) {
|
|
num = 1;
|
|
} else if (a == 1) {
|
|
num = 8;
|
|
} else if (a == 2) {
|
|
num = 14;
|
|
} else if (a == 3) {
|
|
num = 20;
|
|
} else {
|
|
num = 2;
|
|
}
|
|
TLRPC.Document document = stickerSet.documents.get(num);
|
|
File path = FileLoader.getInstance(UserConfig.selectedAccount).getPathToAttach(document, true);
|
|
String json = readRes(path, 0);
|
|
if (TextUtils.isEmpty(json)) {
|
|
loading = true;
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
String fileName = FileLoader.getAttachFileName(document);
|
|
DownloadController.getInstance(account).addLoadingFileObserver(fileName, currentMessageObject, messageCell);
|
|
FileLoader.getInstance(account).loadFile(document, stickerSet, 1, 1);
|
|
});
|
|
} else {
|
|
nativePtrs[a] = createWithJson(json, "dice", metaData, null);
|
|
frameCounts[a] = metaData[0];
|
|
}
|
|
}
|
|
if (loading) {
|
|
AndroidUtilities.runOnUIThread(() -> loadingInBackground = false);
|
|
return;
|
|
}
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
loadingInBackground = false;
|
|
if (!secondLoadingInBackground && destroyAfterLoading) {
|
|
recycle();
|
|
return;
|
|
}
|
|
nativePtr = nativePtrs[0];
|
|
DownloadController.getInstance(account).removeLoadingFileObserver(messageCell);
|
|
timeBetweenFrames = Math.max(16, (int) (1000.0f / metaData[1]));
|
|
scheduleNextGetFrame();
|
|
invalidateInternal();
|
|
});
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
public boolean setDiceNumber(ChatMessageCell messageCell, int number, TLRPC.TL_messages_stickerSet stickerSet, boolean instant) {
|
|
if (secondNativePtr != 0 || secondLoadingInBackground) {
|
|
return true;
|
|
}
|
|
init(number);
|
|
MessageObject currentMessageObject = messageCell.getMessageObject();
|
|
int account = messageCell.getMessageObject().currentAccount;
|
|
|
|
secondLoadingInBackground = true;
|
|
Utilities.globalQueue.postRunnable(() -> {
|
|
if (destroyAfterLoading) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
secondLoadingInBackground = false;
|
|
if (!loadingInBackground && destroyAfterLoading) {
|
|
recycle();
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
boolean loading = false;
|
|
for (int a = 0; a < secondNativePtrs.length + 2; a++) {
|
|
int num;
|
|
if (a <= 2) {
|
|
if (secondNativePtrs[a] != 0) {
|
|
continue;
|
|
}
|
|
if (a == 0) {
|
|
if (left == ReelValue.bar) {
|
|
num = 5;
|
|
} else if (left == ReelValue.berries) {
|
|
num = 6;
|
|
} else if (left == ReelValue.lemon) {
|
|
num = 7;
|
|
} else if (left == ReelValue.seven) {
|
|
num = 4;
|
|
} else {
|
|
num = 3;
|
|
}
|
|
} else if (a == 1) {
|
|
if (center == ReelValue.bar) {
|
|
num = 11;
|
|
} else if (center == ReelValue.berries) {
|
|
num = 12;
|
|
} else if (center == ReelValue.lemon) {
|
|
num = 13;
|
|
} else if (center == ReelValue.seven) {
|
|
num = 10;
|
|
} else {
|
|
num = 9;
|
|
}
|
|
} else {
|
|
if (right == ReelValue.bar) {
|
|
num = 17;
|
|
} else if (right == ReelValue.berries) {
|
|
num = 18;
|
|
} else if (right == ReelValue.lemon) {
|
|
num = 19;
|
|
} else if (right == ReelValue.seven) {
|
|
num = 16;
|
|
} else {
|
|
num = 15;
|
|
}
|
|
}
|
|
} else {
|
|
if (nativePtrs[a] != 0) {
|
|
continue;
|
|
}
|
|
if (a == 3) {
|
|
num = 1;
|
|
} else {
|
|
num = 2;
|
|
}
|
|
}
|
|
TLRPC.Document document = stickerSet.documents.get(num);
|
|
File path = FileLoader.getInstance(UserConfig.selectedAccount).getPathToAttach(document, true);
|
|
String json = readRes(path, 0);
|
|
if (TextUtils.isEmpty(json)) {
|
|
loading = true;
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
String fileName = FileLoader.getAttachFileName(document);
|
|
DownloadController.getInstance(account).addLoadingFileObserver(fileName, currentMessageObject, messageCell);
|
|
FileLoader.getInstance(account).loadFile(document, stickerSet, 1, 1);
|
|
});
|
|
} else {
|
|
if (a <= 2) {
|
|
secondNativePtrs[a] = createWithJson(json, "dice", metaData, null);
|
|
secondFrameCounts[a] = metaData[0];
|
|
} else {
|
|
nativePtrs[a == 3 ? 0 : 4] = createWithJson(json, "dice", metaData, null);
|
|
frameCounts[a == 3 ? 0 : 4] = metaData[0];
|
|
}
|
|
}
|
|
}
|
|
if (loading) {
|
|
AndroidUtilities.runOnUIThread(() -> secondLoadingInBackground = false);
|
|
return;
|
|
}
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
if (instant && nextRenderingBitmap == null && renderingBitmap == null && loadFrameTask == null) {
|
|
isDice = 2;
|
|
setLastFrame = true;
|
|
}
|
|
secondLoadingInBackground = false;
|
|
if (!loadingInBackground && destroyAfterLoading) {
|
|
recycle();
|
|
return;
|
|
}
|
|
secondNativePtr = secondNativePtrs[0];
|
|
DownloadController.getInstance(account).removeLoadingFileObserver(messageCell);
|
|
timeBetweenFrames = Math.max(16, (int) (1000.0f / metaData[1]));
|
|
scheduleNextGetFrame();
|
|
invalidateInternal();
|
|
});
|
|
});
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void recycle() {
|
|
isRunning = false;
|
|
isRecycled = true;
|
|
checkRunningTasks();
|
|
if (loadingInBackground || secondLoadingInBackground) {
|
|
destroyAfterLoading = true;
|
|
} else if (loadFrameTask == null && cacheGenerateTask == null) {
|
|
for (int a = 0; a < nativePtrs.length; a++) {
|
|
if (nativePtrs[a] != 0) {
|
|
if (nativePtrs[a] == nativePtr) {
|
|
nativePtr = 0;
|
|
}
|
|
destroy(nativePtrs[a]);
|
|
nativePtrs[a] = 0;
|
|
}
|
|
}
|
|
for (int a = 0; a < secondNativePtrs.length; a++) {
|
|
if (secondNativePtrs[a] != 0) {
|
|
if (secondNativePtrs[a] == secondNativePtr) {
|
|
secondNativePtr = 0;
|
|
}
|
|
destroy(secondNativePtrs[a]);
|
|
secondNativePtrs[a] = 0;
|
|
}
|
|
}
|
|
recycleResources();
|
|
} else {
|
|
destroyWhenDone = true;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void decodeFrameFinishedInternal() {
|
|
if (destroyWhenDone) {
|
|
checkRunningTasks();
|
|
if (loadFrameTask == null && cacheGenerateTask == null) {
|
|
for (int a = 0; a < nativePtrs.length; a++) {
|
|
if (nativePtrs[a] != 0) {
|
|
destroy(nativePtrs[a]);
|
|
nativePtrs[a] = 0;
|
|
}
|
|
}
|
|
for (int a = 0; a < secondNativePtrs.length; a++) {
|
|
if (secondNativePtrs[a] != 0) {
|
|
destroy(secondNativePtrs[a]);
|
|
secondNativePtrs[a] = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (nativePtr == 0 && secondNativePtr == 0) {
|
|
recycleResources();
|
|
return;
|
|
}
|
|
waitingForNextTask = true;
|
|
if (!hasParentView()) {
|
|
stop();
|
|
}
|
|
scheduleNextGetFrame();
|
|
}
|
|
}
|