Skip to content

Commit e9f977d

Browse files
committed
Release v0.2.0
- Removed stdout and stderr redirects. - Updated bunch of examples.
1 parent a9fda00 commit e9f977d

File tree

15 files changed

+437
-255
lines changed

15 files changed

+437
-255
lines changed

Examples/TrainingPack.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def boom(args):
105105

106106
def shootie(gw):
107107
ball.SetVelocity(shot)
108-
print("VEL X: " + str(shot.X) + ", Y:" + str(shot.Y) + ", Z:" + str(shot.Z))
108+
cvarManager.log("VEL X: " + str(shot.X) + ", Y:" + str(shot.Y) + ", Z:" + str(shot.Z))
109109

110110
gameWrapper.SetTimeout(shootie, 1)
111111

@@ -258,7 +258,7 @@ def dribble(args):
258258

259259
def tick(args):
260260
def callback(eventName):
261-
print('tick')
261+
cvarManager.log("tick")
262262
gameWrapper.HookEvent('Function GameEvent_Soccar_TA.Active.Tick', callback)
263263

264264

Examples/async_class_test.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import asyncio
2+
import bakkesmod
3+
from bmutils import logger, decorators
4+
5+
logger.redirectStandardStreams()
6+
7+
8+
@decorators.plugin("AsyncTestPlugin", decorators.PLUGINTYPE_ASYNC)
9+
class AsyncTest(bakkesmod.BakkesModPlugin):
10+
def __init__(self):
11+
super().__init__()
12+
print("init class")
13+
14+
def __del__(self):
15+
print("del class")
16+
17+
@decorators.onLoad
18+
async def onLoad(self):
19+
print("onLoad class 1")
20+
await asyncio.sleep(3)
21+
print("onLoad class 2")
22+
23+
@decorators.onUnload
24+
def onUnload(self):
25+
print("onUnload class 3")

Examples/async_test.py

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,15 @@
11
import asyncio
2-
from bmasync import BMEventLoopPolicy
2+
from bmutils import logger, decorators
33

4-
loop = None
4+
logger.redirectStandardStreams()
55

66

7-
async def main():
8-
print('blieb')
9-
await asyncio.sleep(5)
10-
print('bloeb')
11-
12-
13-
def onLoad():
14-
asyncio.set_event_loop_policy(BMEventLoopPolicy())
15-
global loop
16-
loop = asyncio.new_event_loop()
17-
# loop.set_debug(True)
18-
asyncio.set_event_loop(loop)
19-
asyncio.ensure_future(main())
20-
loop.start()
7+
@decorators.bmasync
8+
async def onLoad():
9+
print("onLoad 1")
10+
await asyncio.sleep(3)
11+
print("onLoad 2")
2112

2213

2314
def onUnload():
24-
global loop
25-
if loop:
26-
loop.stop()
27-
loop = None
15+
print("onUnload 3")

Examples/bmutils/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from . import logger
2+
from . import bmasync
3+
from . import callbacks
4+
from . import decorators
5+
6+
__all__ = logger.__all__ + bmasync.__all__ + callbacks.__all__ + decorators.__all__

Examples/bmasync/__init__.py renamed to Examples/bmutils/bmasync.py

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,19 @@
33
import time
44
import heapq
55
import asyncio
6+
import logging
67
import traceback
78
import collections
89

9-
import logging
10-
1110
from bakkesmod import cvarManager, gameWrapper
1211

13-
__all__ = ["BMEventLoop", "BMEventLoopPolicy"]
12+
__all__ = ['BMEventLoop', 'BMEventLoopPolicy']
1413

1514
# Name the logger after the package.
16-
logger = logging.getLogger(__package__)
15+
_logger = logging.getLogger(__package__)
1716

1817
# Maximum timeout passed to select to avoid OS limitations
19-
MAXIMUM_SELECT_TIMEOUT = 24 * 3600
18+
_MAXIMUM_SELECT_TIMEOUT = 24 * 3600
2019

2120

2221
class BMEventLoop(asyncio.AbstractEventLoop):
@@ -32,9 +31,9 @@ def __init__(self):
3231

3332
def __repr__(self):
3433
return (
35-
f'<{self.__class__.__name__} running={self.is_running()} '
36-
f'closed={self.is_closed()} idle={self.is_idle()} '
37-
f'debug={self.get_debug()}>'
34+
f"<{self.__class__.__name__} running={self.is_running()} "
35+
f"closed={self.is_closed()} idle={self.is_idle()} "
36+
f"debug={self.get_debug()}>"
3837
)
3938

4039
def set_debug(self, debug):
@@ -60,14 +59,14 @@ def _debug_log(self, text):
6059
def _check_closed(self):
6160
"""Throws runtime error if the event is closed"""
6261
if self._closed:
63-
raise RuntimeError('Event loop is closed')
62+
raise RuntimeError("Event loop is closed")
6463

6564
def _wakeup(self):
6665
"""Will wake up the idle event loop."""
6766
self._check_closed()
6867
if not self.is_idle():
69-
raise RuntimeError('Event loop is not idle')
70-
self._debug_log('resume event loop')
68+
raise RuntimeError("Event loop is not idle")
69+
self._debug_log("resume event loop")
7170
gameWrapper.SetTimeout(lambda gw: self._run_once(), 0)
7271

7372
def _timer_handle_cancelled(self, handle):
@@ -80,20 +79,20 @@ def _run_once(self):
8079
"""Run one full iteration of the event loop.
8180
8281
This calls all currently ready callbacks, schedules the
83-
resulting callbacks, and finally schedules 'call_later'
82+
resulting callbacks, and finally schedules "call_later"
8483
callbacks.
8584
"""
8685
if self._stopping:
8786
self._running = False
88-
self._debug_log('stopped event loop')
87+
self._debug_log("stopped event loop")
8988
return
9089

91-
self._debug_log(f'_scheduled={self._scheduled}')
90+
self._debug_log(f"_scheduled={self._scheduled}")
9291

9392
# Remove delayed calls that were cancelled from head of queue.
9493
while self._scheduled and self._scheduled[0]._cancelled:
9594
handle = heapq.heappop(self._scheduled)
96-
self._debug_log(f'cancelled handle={handle}')
95+
self._debug_log(f"cancelled handle={handle}")
9796
handle._scheduled = False
9897

9998
timeout = None
@@ -102,82 +101,83 @@ def _run_once(self):
102101
elif self._scheduled:
103102
# Compute the desired timeout.
104103
when = self._scheduled[0]._when
105-
timeout = min(max(0, when - self.time()), MAXIMUM_SELECT_TIMEOUT)
104+
timeout = min(max(0, when - self.time()), _MAXIMUM_SELECT_TIMEOUT)
106105

107106
# Handle 'later' callbacks that are ready.
108107
end_time = self.time() + self._clock_resolution
109108
while self._scheduled:
110109
handle = self._scheduled[0]
111-
self._debug_log(f'_when={handle._when} >= end_time={end_time}')
110+
self._debug_log(f"_when={handle._when} >= end_time={end_time}")
112111
if handle._when >= end_time:
113112
break
114113
handle = heapq.heappop(self._scheduled)
115114
handle._scheduled = False
116115
self._ready.append(handle)
117116

118-
self._debug_log(f'_ready={self._ready}')
117+
self._debug_log(f"_ready={self._ready}")
119118

120119
# Call the callbacks that are ready.
121120
ntodo = len(self._ready)
122121
for i in range(ntodo):
123122
handle = self._ready.popleft()
124123
if handle._cancelled:
125-
self._debug_log(f'cancelled handle={handle}')
124+
self._debug_log(f"cancelled handle={handle}")
126125
continue
127-
self._debug_log(f'run handle={handle}')
126+
self._debug_log(f"run handle={handle}")
128127
handle._run()
129128
handle = None
130129

131130
if timeout is not None:
132-
self._debug_log(f'next tick in {timeout} seconds')
133-
gameWrapper.SetTimeout(lambda gw: self._run_once(), timeout)
131+
# self._debug_log(f"next tick in {timeout} seconds")
132+
# gameWrapper.SetTimeout(lambda gw: self._run_once(), timeout)
133+
gameWrapper.SetTimeout(lambda gw: self._run_once(), max(timeout, 1))
134134
else:
135-
self._debug_log('pause event loop')
135+
self._debug_log("pause event loop")
136136
self._idle = True
137137

138138
def start(self):
139139
"""Run the event loop until stop() is called.
140140
This function is non blocking."""
141-
self._debug_log('start')
141+
self._debug_log("start")
142142
self._check_closed()
143143
if self.is_running():
144-
raise RuntimeError('This event loop is already running')
144+
raise RuntimeError("This event loop is already running")
145145
self._running = True
146-
self._debug_log('started event loop')
146+
self._debug_log("started event loop")
147147
self._run_once()
148148

149149
def run_forever(self):
150150
"""Run the event loop until stop() is called."""
151-
self._debug_log('run_forever')
152-
raise NotImplementedError('run_forever')
151+
self._debug_log("run_forever")
152+
raise NotImplementedError("run_forever")
153153

154154
def run_until_complete(self, future):
155155
"""Run the event loop until a Future is done."""
156-
self._debug_log(f'run_until_complete, future={future}')
157-
raise NotImplementedError(f'run_until_complete, future={future}')
156+
self._debug_log(f"run_until_complete, future={future}")
157+
raise NotImplementedError(f"run_until_complete, future={future}")
158158

159159
def is_running(self):
160160
"""Return whether the event loop is currently running."""
161-
self._debug_log('is_running')
161+
self._debug_log("is_running")
162162
return self._running
163163

164164
def is_closed(self):
165165
"""Returns True if the event loop was closed."""
166-
self._debug_log('is_closed')
166+
self._debug_log("is_closed")
167167
return self._closed
168168

169169
def is_idle(self):
170170
"""Returns True if the event loop is idle."""
171-
self._debug_log('is_idle')
171+
self._debug_log("is_idle")
172172
return self._idle
173173

174174
def stop(self):
175175
"""Stop running the event loop.
176176
177-
Every callback already scheduled will still run. This simply informs
177+
Every callback already scheduled will still run. This simply informs
178178
run_forever to stop looping after a complete iteration.
179179
"""
180-
self._debug_log('stop')
180+
self._debug_log("stop")
181181
self._stopping = True
182182

183183
def close(self):
@@ -188,7 +188,7 @@ def close(self):
188188
189189
The event loop must not be running.
190190
"""
191-
self._debug_log('close')
191+
self._debug_log("close")
192192
if self.is_running():
193193
raise RuntimeError("Cannot close a running event loop")
194194
if self._closed:
@@ -199,8 +199,8 @@ def close(self):
199199

200200
async def shutdown_asyncgens(self):
201201
"""Shutdown all active asynchronous generators."""
202-
self._debug_log('shutdown_asyncgens')
203-
# We don't have any asynchronous generators.
202+
self._debug_log("shutdown_asyncgens")
203+
# We don"t have any asynchronous generators.
204204

205205
def call_exception_handler(self, context):
206206
"""Call the current event loop's exception handler.
@@ -224,10 +224,10 @@ def call_exception_handler(self, context):
224224
For custom exception handling, use the
225225
`set_exception_handler()` method.
226226
"""
227-
self._debug_log(f'call_exception_handler, context={context}')
227+
self._debug_log(f"call_exception_handler, context={context}")
228228
message = context.get('message')
229229
if not message:
230-
message = 'Unhandled exception in event loop'
230+
message = "Unhandled exception in event loop"
231231

232232
exception = context.get('exception')
233233
if exception is not None:
@@ -241,19 +241,19 @@ def call_exception_handler(self, context):
241241
continue
242242
value = context[key]
243243
if key == 'source_traceback':
244-
tb = ''.join(traceback.format_list(value))
245-
value = 'Object created at (most recent call last):\n'
244+
tb = "".join(traceback.format_list(value))
245+
value = "Object created at (most recent call last):\n"
246246
value += tb.rstrip()
247247
elif key == 'handle_traceback':
248-
tb = ''.join(traceback.format_list(value))
249-
value = 'Handle created at (most recent call last):\n'
248+
tb = "".join(traceback.format_list(value))
249+
value = "Handle created at (most recent call last):\n"
250250
value += tb.rstrip()
251251
else:
252252
value = repr(value)
253-
log_lines.append(f'{key}: {value}')
254-
255-
logger.error('\n'.join(log_lines), exc_info=exc_info)
253+
log_lines.append(f"{key}: {value}")
256254

255+
_logger.error("\n".join(log_lines), exc_info=exc_info)
256+
# Logger writes to stderr, so we steal it.
257257
sys.stderr.seek(0)
258258
for line in sys.stderr.read().split('\n'):
259259
cvarManager.log(f"[async] ERROR: {line}")
@@ -271,8 +271,8 @@ def call_soon(self, callback, *args, context=None):
271271
Any positional arguments after the callback will be passed to
272272
the callback when it is called.
273273
"""
274-
self._debug_log(f'call_soon, callback={callback}, args={args}, '
275-
'context={context}')
274+
self._debug_log(f"call_soon, callback={callback}, args={args}, "
275+
f"context={context}")
276276
self._check_closed()
277277
handle = asyncio.Handle(callback, args, self, context)
278278
self._ready.append(handle)
@@ -298,8 +298,8 @@ def call_later(self, delay, callback, *args, context=None):
298298
Any positional arguments after the callback will be passed to
299299
the callback when it is called.
300300
"""
301-
self._debug_log(f'call_later, delay={delay}, callback={callback}, '
302-
'args={args}, context={context}')
301+
self._debug_log(f"call_later, delay={delay}, callback={callback}, "
302+
f"args={args}, context={context}")
303303
return self.call_at(self.time() + delay, callback, *args,
304304
context=context)
305305

@@ -308,8 +308,8 @@ def call_at(self, when, callback, *args, context=None):
308308
309309
Absolute time corresponds to the event loop's time() method.
310310
"""
311-
self._debug_log(f'call_at, when={when}, callback={callback}, '
312-
'args={args}, context={context}')
311+
self._debug_log(f"call_at, when={when}, callback={callback}, "
312+
f"args={args}, context={context}")
313313
self._check_closed()
314314
timer = asyncio.TimerHandle(when, callback, args, self, context)
315315
heapq.heappush(self._scheduled, timer)
@@ -325,13 +325,13 @@ def create_task(self, coro):
325325
326326
Return a task object.
327327
"""
328-
self._debug_log(f'create_task, coro={coro}')
328+
self._debug_log(f"create_task, coro={coro}")
329329
self._check_closed()
330330
return asyncio.Task(coro, loop=self)
331331

332332
def create_future(self):
333333
"""Create a Future object attached to the loop."""
334-
self._debug_log('create_future')
334+
self._debug_log("create_future")
335335
return asyncio.Future(loop=self)
336336

337337

0 commit comments

Comments
 (0)