Skip to content

Commit f1fbd9a

Browse files
authored
Merge pull request #31 from RLBot/context_managers
Add ContextManager pattern to MatchManager and RenderingManager plus default color
2 parents 00b3637 + df40102 commit f1fbd9a

File tree

6 files changed

+71
-36
lines changed

6 files changed

+71
-36
lines changed

rlbot/managers/match.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ def __init__(
3333
self.rlbot_interface: SocketRelay = SocketRelay("")
3434
self.rlbot_interface.packet_handlers.append(self._packet_reporter)
3535

36+
def __enter__(self) -> 'MatchManager':
37+
return self
38+
39+
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
40+
self.disconnect()
41+
3642
def ensure_server_started(self):
3743
"""
3844
Ensures that RLBotServer is running, starting it if it is not.

rlbot/managers/rendering.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import math
22
from collections.abc import Callable, Sequence
3+
from contextlib import contextmanager
34
from typing import Optional
45

56
from rlbot import flat
@@ -51,6 +52,8 @@ class Renderer:
5152
_group_id: Optional[int] = None
5253
_current_renders: list[flat.RenderMessage] = []
5354

55+
_default_color = white
56+
5457
_screen_width_factor = 1.0
5558
_screen_height_factor = 1.0
5659

@@ -72,6 +75,12 @@ def set_resolution(self, screen_width: float, screen_height: float):
7275
self._screen_width_factor = 1.0 / screen_width
7376
self._screen_height_factor = 1.0 / screen_height
7477

78+
def set_default_color(self, color: flat.Color):
79+
"""
80+
Set which color to use when no other color is provided.
81+
"""
82+
self._default_color = color
83+
7584
@staticmethod
7685
def create_color(red: int, green: int, blue: int, alpha: int = 255) -> flat.Color:
7786
return flat.Color(red, green, blue, alpha)
@@ -111,6 +120,30 @@ def team_color(team: int, alt_color: bool = False) -> flat.Color:
111120
def _get_group_id(group_id: str) -> int:
112121
return hash(str(group_id).encode("utf-8")) % MAX_INT
113122

123+
@contextmanager
124+
def context(self, group_id: str=DEFAULT_GROUP_ID, default_color=None):
125+
"""
126+
Starts rendering as a context usable in with-statements.
127+
After the with-statement the rendering is automatically ended.
128+
Note, the is not possible to have two nested renderings started.
129+
130+
Example:
131+
132+
```
133+
with renderer.context(default_color=renderer.red):
134+
renderer.draw_line_3d(car.pos, ball.pos)
135+
renderer.draw_line_3d(car.pos, goal.pos)
136+
renderer.draw_line_3d(ball.pos, goal.pos)
137+
```
138+
"""
139+
try:
140+
self.begin_rendering(group_id)
141+
if default_color:
142+
self.set_default_color(default_color)
143+
yield
144+
finally:
145+
self.end_rendering()
146+
114147
def begin_rendering(self, group_id: str = DEFAULT_GROUP_ID):
115148
"""
116149
Begins a new render group. All render messages added after this call will be part of this group.
@@ -189,29 +222,29 @@ def draw_line_3d(
189222
self,
190223
start: flat.RenderAnchor | flat.BallAnchor | flat.CarAnchor | flat.Vector3,
191224
end: flat.RenderAnchor | flat.BallAnchor | flat.CarAnchor | flat.Vector3,
192-
color: flat.Color,
225+
color: flat.Color | None = None,
193226
):
194227
"""
195228
Draws a line between two anchors in 3d space.
196229
"""
197-
self.draw(flat.Line3D(_get_anchor(start), _get_anchor(end), color))
230+
self.draw(flat.Line3D(_get_anchor(start), _get_anchor(end), color or self._default_color))
198231

199232
def draw_polyline_3d(
200233
self,
201234
points: Sequence[flat.Vector3],
202-
color: flat.Color,
235+
color: flat.Color | None = None,
203236
):
204237
"""
205238
Draws a line going through each of the provided points.
206239
"""
207-
self.draw(flat.PolyLine3D(points, color))
240+
self.draw(flat.PolyLine3D(points, color or self._default_color))
208241

209242
def draw_string_3d(
210243
self,
211244
text: str,
212245
anchor: flat.RenderAnchor | flat.BallAnchor | flat.CarAnchor | flat.Vector3,
213246
scale: float,
214-
foreground: flat.Color,
247+
foreground: flat.Color | None = None,
215248
background: flat.Color = flat.Color(a=0),
216249
h_align: flat.TextHAlign = flat.TextHAlign.Left,
217250
v_align: flat.TextVAlign = flat.TextVAlign.Top,
@@ -225,7 +258,7 @@ def draw_string_3d(
225258
text,
226259
_get_anchor(anchor),
227260
scale,
228-
foreground,
261+
foreground or self._default_color,
229262
background,
230263
h_align,
231264
v_align,
@@ -238,7 +271,7 @@ def draw_string_2d(
238271
x: float,
239272
y: float,
240273
scale: float,
241-
foreground: flat.Color,
274+
foreground: flat.Color | None = None,
242275
background: flat.Color = flat.Color(a=0),
243276
h_align: flat.TextHAlign = flat.TextHAlign.Left,
244277
v_align: flat.TextVAlign = flat.TextVAlign.Top,
@@ -255,7 +288,7 @@ def draw_string_2d(
255288
x * self._screen_width_factor,
256289
y * self._screen_height_factor,
257290
scale,
258-
foreground,
291+
foreground or self._default_color,
259292
background,
260293
h_align,
261294
v_align,
@@ -268,7 +301,7 @@ def draw_rect_2d(
268301
y: float,
269302
width: float,
270303
height: float,
271-
color: flat.Color,
304+
color: flat.Color | None = None,
272305
h_align: flat.TextHAlign = flat.TextHAlign.Left,
273306
v_align: flat.TextVAlign = flat.TextVAlign.Top,
274307
):
@@ -284,7 +317,7 @@ def draw_rect_2d(
284317
y * self._screen_height_factor,
285318
width * self._screen_width_factor,
286319
height * self._screen_height_factor,
287-
color,
320+
color or self._default_color,
288321
h_align,
289322
v_align,
290323
)
@@ -295,7 +328,7 @@ def draw_rect_3d(
295328
anchor: flat.RenderAnchor | flat.BallAnchor | flat.CarAnchor | flat.Vector3,
296329
width: float,
297330
height: float,
298-
color: flat.Color,
331+
color: flat.Color | None = None,
299332
h_align: flat.TextHAlign = flat.TextHAlign.Left,
300333
v_align: flat.TextVAlign = flat.TextVAlign.Top,
301334
):
@@ -310,7 +343,7 @@ def draw_rect_3d(
310343
_get_anchor(anchor),
311344
width * self._screen_width_factor,
312345
height * self._screen_height_factor,
313-
color,
346+
color or self._default_color,
314347
h_align,
315348
v_align,
316349
)

rlbot/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.0.0-beta.43"
1+
__version__ = "2.0.0-beta.44"

tests/render_test/render.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from email.policy import default
2+
13
from rlbot import flat
24
from rlbot.flat import BallAnchor, CarAnchor, Color, RenderAnchor, Vector3
35
from rlbot.managers import Script
@@ -30,12 +32,12 @@ def handle_packet(self, packet: flat.GamePacket):
3032

3133
self.do_render(radius)
3234

33-
self.renderer.begin_rendering('tick')
34-
hsv = self.renderer.create_color_hsv(packet.match_info.seconds_elapsed * 0.1, 1.0, 1.0)
35-
self.renderer.set_resolution(1920, 1080)
36-
self.renderer.draw_string_2d('HSV 300px 50px', 300, 50, 1.0, hsv)
37-
self.renderer.set_resolution(1, 1)
38-
self.renderer.end_rendering()
35+
with self.renderer.context('tick', self.renderer.red):
36+
self.renderer.set_resolution(1920, 1080)
37+
hsv = self.renderer.create_color_hsv(packet.match_info.seconds_elapsed * 0.1, 1.0, 1.0)
38+
self.renderer.draw_string_2d('HSV 300px 50px', 300, 50, 1.0, hsv)
39+
self.renderer.draw_string_2d('Red 330px 70px', 330, 70, 1.0) # Use default color
40+
self.renderer.set_resolution(1, 1)
3941

4042
def do_render(self, radius: float):
4143
self.renderer.begin_rendering()
@@ -75,7 +77,7 @@ def do_render(self, radius: float):
7577
)
7678

7779
self.renderer.draw_rect_2d(
78-
0.75, 0.75, 0.1, 0.1, Color(150, 30, 100), centered=False
80+
0.75, 0.75, 0.1, 0.1, Color(150, 30, 100)
7981
)
8082
self.renderer.draw_rect_2d(0.75, 0.75, 0.1, 0.1, self.renderer.black)
8183
for hkey, h in {

tests/run_match.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,10 @@
1010
RLBOT_SERVER_FOLDER = DIR / "../../core/RLBotCS/bin/Release/"
1111

1212
if __name__ == "__main__":
13-
match_manager = MatchManager(RLBOT_SERVER_FOLDER)
13+
with MatchManager(RLBOT_SERVER_FOLDER) as man:
14+
man.start_match(MATCH_CONFIG_PATH)
15+
assert man.packet is not None
1416

15-
match_manager.start_match(MATCH_CONFIG_PATH)
16-
assert match_manager.packet is not None
17-
18-
try:
1917
# wait for the match to end
20-
while match_manager.packet.match_info.match_phase != flat.MatchPhase.Ended:
18+
while man.packet.match_info.match_phase != flat.MatchPhase.Ended:
2119
sleep(1.0)
22-
finally:
23-
match_manager.shut_down()

tests/run_only.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@
1414
match_config_path = Path(sys.argv[1])
1515
assert match_config_path.exists(), f"Match config not found: {match_config_path}"
1616

17-
# start the match
18-
match_manager = MatchManager(RLBOT_SERVER_FOLDER)
19-
match_manager.start_match(match_config_path, False)
17+
with MatchManager(RLBOT_SERVER_FOLDER) as man:
18+
man.start_match(match_config_path, False)
2019

21-
# wait
22-
input("\nPress enter to end the match: ")
20+
# Wait for input
21+
input("\nPress enter to end the match: ")
2322

24-
# end the match and disconnect
25-
match_manager.stop_match()
26-
match_manager.disconnect()
23+
# End the match
24+
man.stop_match()

0 commit comments

Comments
 (0)