mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-12 07:23:45 +08:00
132 lines
4.5 KiB
Python
132 lines
4.5 KiB
Python
"""The map overlay is created only when the AA layout enables it, prepared outside the frame, drawn at its placement."""
|
|
import copy
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
from openpilot.starpilot.system.starport import projection_onroad as projection
|
|
from openpilot.starpilot.system.starport.projection_layout import default_layout_for_viewport
|
|
from openpilot.starpilot.system.starport.tests import test_projection_onroad_boundary as boundary
|
|
|
|
|
|
class FakeMap:
|
|
def __init__(self, *, fonts):
|
|
self.fonts = fonts
|
|
self.prepared, self.drawn, self.closed = [], [], False
|
|
|
|
def prepare(self, data, width, height):
|
|
self.prepared.append((data, width, height))
|
|
|
|
def draw(self, rect, opacity):
|
|
self.drawn.append((rect, opacity))
|
|
|
|
def close(self):
|
|
self.closed = True
|
|
|
|
|
|
class FakeFeed:
|
|
def __init__(self):
|
|
self.reads = []
|
|
self.destinations = []
|
|
|
|
def read(self, sm, *, navigation_requested=None, destination=None):
|
|
self.reads.append(sm)
|
|
self.destinations.append(destination)
|
|
return "map input"
|
|
|
|
|
|
class FakeLease:
|
|
def __init__(self):
|
|
self.touches, self.releases = 0, 0
|
|
|
|
def touch(self):
|
|
self.touches += 1
|
|
|
|
def release(self):
|
|
self.releases += 1
|
|
|
|
|
|
class TestProjectionMap(unittest.TestCase):
|
|
def setUp(self):
|
|
self.lease = FakeLease()
|
|
patcher = patch.object(projection, 'MapLeaseWriter', return_value=self.lease)
|
|
patcher.start()
|
|
self.addCleanup(patcher.stop)
|
|
|
|
def native(self):
|
|
native, events = boundary.TestProjectionOnroad().dependencies()
|
|
native.map_overlay, native.map_feed = FakeMap, FakeFeed
|
|
return native, events
|
|
|
|
def layout(self, **map_placement):
|
|
document = default_layout_for_viewport((2880, 1080))
|
|
document["widgets"]["nav_map"].update(map_placement)
|
|
return document
|
|
|
|
def test_disabled_map_builds_nothing(self):
|
|
native, _ = self.native()
|
|
view = projection.ProjectionOnroad(dependencies=native, viewport=(2880, 1080), customization=self.layout())
|
|
self.assertIsNone(view.map)
|
|
view.prepare()
|
|
view.close()
|
|
|
|
def test_enabled_map_prepares_onroad_and_draws_at_placement(self):
|
|
native, _ = self.native()
|
|
layout = self.layout(enabled=True, x=100, y=200, width=640, height=480, opacity=45)
|
|
view = projection.ProjectionOnroad(dependencies=native, viewport=(2880, 1080), customization=layout)
|
|
self.assertIsInstance(view.map, FakeMap)
|
|
self.assertIs(view.map.fonts, view.fonts)
|
|
self.assertEqual(view.onroad.map_layer, view._map_layer)
|
|
view.prepare()
|
|
self.assertEqual(view.map.prepared, [], "nothing to prepare while offroad")
|
|
native.ui_state.started = True
|
|
view.prepare()
|
|
self.assertEqual(view.map.prepared, [("map input", 640, 480)])
|
|
self.assertEqual(view.map_feed.reads, [native.ui_state.sm])
|
|
self.assertEqual(view.map_feed.destinations, [None], "no favorites: the feed keeps navigation's own name")
|
|
view._map_layer(None, None)
|
|
self.assertEqual(view.map.drawn, [((100, 200, 640, 480), 0.45)])
|
|
overlay = view.map
|
|
view.close()
|
|
self.assertTrue(overlay.closed)
|
|
|
|
def test_older_dependencies_without_a_map_still_work(self):
|
|
native, _ = self.native()
|
|
del native.map_overlay
|
|
view = projection.ProjectionOnroad(dependencies=native, viewport=(2880, 1080),
|
|
customization=self.layout(enabled=True))
|
|
self.assertIsNone(view.map)
|
|
native.ui_state.started = True
|
|
view.prepare()
|
|
view.close()
|
|
|
|
def test_layout_document_is_not_mutated(self):
|
|
native, _ = self.native()
|
|
layout = self.layout(enabled=True)
|
|
before = copy.deepcopy(layout)
|
|
view = projection.ProjectionOnroad(dependencies=native, viewport=(2880, 1080), customization=layout)
|
|
native.ui_state.started = True
|
|
view.prepare()
|
|
view.close()
|
|
self.assertEqual(layout, before)
|
|
|
|
def test_turning_the_map_off_frees_it_and_the_lease_until_it_returns(self):
|
|
native, _ = self.native()
|
|
layout = self.layout(enabled=True)
|
|
view = projection.ProjectionOnroad(dependencies=native, viewport=(2880, 1080), customization=layout)
|
|
native.ui_state.started = True
|
|
view.prepare()
|
|
self.assertEqual(self.lease.touches, 1)
|
|
overlay = view.map
|
|
off = copy.deepcopy(layout)
|
|
off["widgets"]["nav_map"]["enabled"] = False
|
|
view.apply_layout(off)
|
|
view.prepare()
|
|
self.assertTrue(overlay.closed)
|
|
self.assertIsNone(view.map)
|
|
self.assertIsNone(view.onroad.map_layer)
|
|
self.assertGreaterEqual(self.lease.releases, 1)
|
|
view.apply_layout(layout)
|
|
self.assertIsInstance(view.map, FakeMap)
|
|
self.assertIsNot(view.map, overlay)
|
|
view.close()
|