-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGameContext.py
More file actions
155 lines (136 loc) · 5.81 KB
/
Copy pathGameContext.py
File metadata and controls
155 lines (136 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import asyncio
import threading
from GameServer import Event
import GameServer
# 全局状态变量
subscribers = [] # 订阅者列表
event = None
gameInfo = None
choice = None
choose = False
# 异步等待相关 - 使用全局持久化Future和事件循环
_choice_future = None
_choice_future_lock = threading.Lock() # 用于保护Future的创建和设置
_main_loop = None # 保存主事件循环的引用
def _ensure_future():
"""确保有一个有效的Future (同步方法)"""
global _choice_future, _main_loop
with _choice_future_lock:
if _choice_future is None or _choice_future.done():
# 在主事件循环中创建Future
try:
# 获取或保存主事件循环
if _main_loop is None:
try:
_main_loop = asyncio.get_event_loop()
except RuntimeError:
# 如果没有事件循环,创建一个新的
_main_loop = asyncio.new_event_loop()
if _main_loop.is_running():
_choice_future = _main_loop.create_future()
else:
_choice_future = asyncio.Future()
except RuntimeError:
_choice_future = asyncio.Future()
print(f"[DEBUG-GameContext] 创建新的Future, loop: {_main_loop}")
return _choice_future
def set_event(new_event: Event):
global event
event = new_event
def set_game_info(new_game_info):
global gameInfo
gameInfo = new_game_info
def set_choice(new_choice):
global choice
choice = new_choice
def set_choose_state(state: bool):
global choose
print(f"[DEBUG-GameContext] set_choose_state: {state}")
choose = state
def get_choose_state():
global choose
return choose
def reset_actions():
"""清空actions列表(使用GameServer.actions)"""
GameServer.actions.clear()
def add_action(action):
"""添加action到GameServer.actions列表"""
GameServer.actions.append(action)
def get_actions():
"""获取GameServer.actions列表"""
return GameServer.actions
def set_choice_result(result):
global _choice_future, _main_loop, choice
print(f"[DEBUG-GameContext] set_choice_result被调用, result数量: {len(result) if isinstance(result, list) else 1}")
with _choice_future_lock:
if _choice_future is not None and not _choice_future.done():
print(f"[DEBUG-GameContext] 设置Future结果, loop: {_main_loop}")
# 在主事件循环中设置结果
try:
# 确保我们有主事件循环的引用
if _main_loop is None:
try:
_main_loop = asyncio.get_event_loop()
except RuntimeError:
pass
if _main_loop and _main_loop.is_running():
_main_loop.call_soon_threadsafe(_choice_future.set_result, result)
else:
if _main_loop:
_main_loop.call_soon_threadsafe(_choice_future.set_result, result)
else:
_choice_future.set_result(result)
except Exception as e:
print(f"[DEBUG-GameContext] 设置Future结果失败: {e}")
import traceback
traceback.print_exc()
choice = result
else:
print(f"[DEBUG-GameContext] Future不存在或已完成, _choice_future={_choice_future}, done={_choice_future.done() if _choice_future else 'N/A'}")
# 尝试创建新Future并立即设置结果
try:
# 确保我们有主事件循环的引用
if _main_loop is None:
try:
_main_loop = asyncio.get_event_loop()
except RuntimeError:
_main_loop = asyncio.new_event_loop()
new_future = _main_loop.create_future() if _main_loop.is_running() else asyncio.Future()
_choice_future = new_future
if _main_loop.is_running():
_main_loop.call_soon_threadsafe(new_future.set_result, result)
else:
new_future.set_result(result)
choice = result
print(f"[DEBUG-GameContext] 创建新Future并设置结果")
except Exception as e:
print(f"[DEBUG-GameContext] 无法获取事件循环: {e}")
import traceback
traceback.print_exc()
async def wait_for_choose():
"""等待选择完成"""
global _choice_future
print(f"[DEBUG-GameContext] wait_for_choose: 获取或创建Future")
# 确保有有效的Future
future = _ensure_future()
print(f"[DEBUG-GameContext] wait_for_choose: 获取到Future, done={future.done()}")
try:
# 只有Future未完成时才await
if future.done():
print(f"[DEBUG-GameContext] Future已直接完成,立即返回结果")
# 如果Future已经完成(比如set_choice_result被提前调用),直接获取结果
try:
result = future.result()
print(f"[DEBUG-GameContext] wait_for_choose: 直接获取结果, 结果: {result}")
return result
except asyncio.CancelledError:
print(f"[DEBUG-GameContext] wait_for_choose: Future被取消")
raise
else:
print(f"[DEBUG-GameContext] wait_for_choose: 开始await Future")
result = await future
print(f"[DEBUG-GameContext] wait_for_choose: Future完成, 结果: {result}")
return result
except asyncio.CancelledError:
print(f"[DEBUG-GameContext] wait_for_choose: Future被取消")
raise