Skip to content

Commit

Permalink
Merge pull request #450 from Hpero4/master
Browse files Browse the repository at this point in the history
修复搜索界面的若干问题;修复生涯背景设置的若干问题
  • Loading branch information
Zzaphkiel authored Aug 19, 2024
2 parents 22172c7 + ab80fa7 commit d7da2ca
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
5 changes: 5 additions & 0 deletions app/components/search_line_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,8 @@ def focusInEvent(self, e):
if e.reason() != 4:
self._showCompleterMenu()
super().focusInEvent(e)

def mousePressEvent(self, e):
if self.hasFocus():
self._showCompleterMenu()
super().mousePressEvent(e)
9 changes: 8 additions & 1 deletion app/lol/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
import threading
import re
from asyncio import CancelledError
from collections import deque

import requests
Expand Down Expand Up @@ -86,6 +87,12 @@ async def wrapper(*args, **kwargs):
try:
async with connector.semaphore:
res = await func(*args, **kwargs)
except CancelledError:
# Fix: 使用task.cancel()偶尔会停不下task -- By Hpero4
# 在调用cancel()时, 会从调用栈的最底抛出CancelledError, 最终传递到loop终止task;
# 由于CancelledError是BaseException的子类,
# 若task恰好跑到被retry装饰的函数中, 会被retry中的BaseException捕获并吞掉, 从而无事发生
raise
except BaseException as e:
time.sleep(retry_sep)
exce = e
Expand Down Expand Up @@ -324,7 +331,7 @@ def __initFolder(self):
"profile icons",
"rune icons",
"summoner spell icons",
"augment icons"
"augment icons",
"splashes",
]:
p = f"app/resource/game/{folder}"
Expand Down
34 changes: 30 additions & 4 deletions app/view/search_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
QSpacerItem, QSizePolicy, QLabel, QStackedWidget, QWidget)
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QPixmap, QColor

from ..common.logger import logger
from ..common.qfluentwidgets import (SmoothScrollArea, PushButton, ToolButton, InfoBar,
InfoBarPosition, ToolTipFilter, ToolTipPosition,
isDarkTheme, FlyoutViewBase, Flyout, Theme,
Expand All @@ -31,6 +33,23 @@
from ..components.seraphine_interface import SeraphineInterface


TAG = "SearchInterface"


def asyncLockDecorator(lockName):
"""
给任何一个方法加锁, return时释放
args[0]是self, 通过getattr找到lockName
"""
def decorator(func):
async def wrapper(*args, **kwargs):
lock = getattr(args[0], lockName)
async with lock:
return await func(*args, **kwargs)
return wrapper
return decorator


class GamesTab(QFrame):
tabClicked = pyqtSignal(str)
gameDetailReady = pyqtSignal(dict)
Expand Down Expand Up @@ -1008,6 +1027,8 @@ def __init__(self, parent=None):
self.detailViewLoadTask = None
self.loadingGameId = 0

self.loadFirstPageLock = asyncio.Lock()

self.__initWidget()
self.__initLayout()
self.__connectSignalToSlot()
Expand Down Expand Up @@ -1077,6 +1098,8 @@ def __showSummonerNotFoundMsg(self):
parent=self
)

# Fix: 超快速的在候选栏选中两次同样puuid会起两个task加载战绩, 100%干掉客户端 -- By Hpero4
@asyncLockDecorator('loadFirstPageLock')
async def searchAndShowFirstPage(self, puuid=None):
name = self.searchLineEdit.text()
if name == "":
Expand Down Expand Up @@ -1105,9 +1128,7 @@ async def searchAndShowFirstPage(self, puuid=None):

while not self.gameLoadingTask.cancelled() \
and not self.gameLoadingTask.done():
# FIX: task有可能会错过cancel(), 导致必须等到查询结束; -- By Hpero4
self.gameLoadingTask.cancel()
await asyncio.sleep(.2)
await asyncio.sleep(.3)

self.puuid = summoner['puuid']
self.gamesView.gamesTab.clear()
Expand All @@ -1132,7 +1153,6 @@ async def searchAndShowFirstPage(self, puuid=None):
# 启动任务,往 gamesTab 里丢数据
# NOTE 既然创建新任务, 并且刷新了self.puuid 就应该用self的, 否则就违背了loadGames判断的初衷

# FIXME: 当从两名召唤师之间反复横跳时, 有可能会导致一puuid起了2个(或更多)task -- By Hpero4
self.gameLoadingTask = asyncio.create_task(
self.__loadGames(self.puuid))

Expand Down Expand Up @@ -1188,12 +1208,15 @@ async def __loadGames(self, puuid):
begIdx = 20
endIdx = 29

logger.debug(f"welcome load games task: {puuid}", TAG)

# NOTE 换了查询目标, 若之前正在查, 先等 task 被 release 掉 -- By Hpero4
while self.gameLoadingTask \
and not self.gameLoadingTask.done() \
and puuid != self.puuid:
await asyncio.sleep(.2)

logger.debug(f"start load {puuid}", TAG)
# 连续查多个人时, 将前面正在查的task给release掉
while self.puuid == puuid:
# 为加载战绩详情让行
Expand All @@ -1205,6 +1228,7 @@ async def __loadGames(self, puuid):
):
await asyncio.sleep(.2)

t1 = time.time()
try:
games = await connector.getSummonerGamesByPuuidSlowly(
puuid, begIdx, endIdx)
Expand All @@ -1213,7 +1237,9 @@ async def __loadGames(self, puuid):
# NOTE 触发 SummonerGamesNotFound 时, 异常信息会通过 connector 下发到 main_window 的 __onShowLcuConnectError
# 理论上会有弹框提示 -- By Hpero4
return
t2 = time.time()

logger.debug(f"load games {self.puuid} [{begIdx}-{endIdx}] finish {t2-t1}s", TAG)
# 1000 局搜完了,或者正好上一次就是最后
# 在切换了puuid时, 就不要再把数据刷到Games上了 -- By Hpero4
if games['gameCount'] == 0 or self.puuid != puuid:
Expand Down

0 comments on commit d7da2ca

Please sign in to comment.