diff --git a/cursor/manager/internal/cursor_manager.py b/cursor/manager/internal/cursor_manager.py index 9cecbf7..3748b51 100644 --- a/cursor/manager/internal/cursor_manager.py +++ b/cursor/manager/internal/cursor_manager.py @@ -6,7 +6,7 @@ class CursorManager: - cursor_dict: dict[str, Cursor] + cursor_dict: dict[str, Cursor] = {} @staticmethod def create(conn_id: str): @@ -18,15 +18,41 @@ def remove(conn_id: str): if conn_id in CursorManager.cursor_dict: del CursorManager.cursor_dict[conn_id] + # range 안에 커서가 있는가 @staticmethod def exists_range(start: Point, end: Point) -> list[Cursor]: - # 일단 broadcast. 추후 고쳐야 함. - return list(CursorManager.cursor_dict.values()) + result = [] + for key in CursorManager.cursor_dict: + cur = CursorManager.cursor_dict[key] + if start.x > cur.position.x: + continue + if end.x < cur.position.x: + continue + if start.y < cur.position.y: + continue + if end.y > cur.position.y: + continue + result.append(cur) + return result + + # 커서 view에 tile이 포함되는가 @staticmethod def view_includes(p: Point) -> list[Cursor]: - # 일단 broadcast. 추후 고쳐야 함. - return list(CursorManager.cursor_dict.values()) + result = [] + for key in CursorManager.cursor_dict: + cur = CursorManager.cursor_dict[key] + if (cur.position.x - cur.width) > p.x: + continue + if (cur.position.x + cur.width) < p.x: + continue + if (cur.position.y - cur.height) > p.y: + continue + if (cur.position.y + cur.height) < p.y: + continue + result.append(cur) + + return result @EventBroker.add_receiver(NewConnEvent.NEW_CONN) @staticmethod diff --git a/cursor/manager/test/cursor_manager_test.py b/cursor/manager/test/cursor_manager_test.py index 998141f..66f29b3 100644 --- a/cursor/manager/test/cursor_manager_test.py +++ b/cursor/manager/test/cursor_manager_test.py @@ -1,4 +1,4 @@ -from cursor import Cursor +from cursor import Cursor, Color from cursor.manager import CursorManager from event import EventBroker from message import Message @@ -9,15 +9,23 @@ from warnings import warn +def get_cur(conn_id): + return Cursor( + conn_id=conn_id, + position=Point(0, 0), + pointer=None, + height=10, + width=10, + color=Color.BLUE + ) + + class CursorManagerTestCase(unittest.IsolatedAsyncioTestCase): def setUp(self): - self.curs_1 = Mock() - self.curs_2 = Mock() - self.curs_3 = Mock() CursorManager.cursor_dict = { - "example_1": self.curs_1, - "example_2": self.curs_2, - "example_3": self.curs_3 + "example_1": get_cur("example_1"), + "example_2": get_cur("example_2"), + "example_3": get_cur("example_3") } def tearDown(self): @@ -39,15 +47,11 @@ def test_remove(self): def test_exists_range(self): result = CursorManager.exists_range(Point(0, 0), Point(0, 0)) - warn("아직 구현 안됨") - # broadcast 기준 self.assertEqual(len(result), 3) def test_view_includes(self): result = CursorManager.view_includes(Point(0, 0)) - warn("아직 구현 안됨") - # broadcast 기준 self.assertEqual(len(result), 3) @@ -99,6 +103,7 @@ async def test_receive_new_conn_without_cursors(self): assert got.header["target_conns"][0] == expected_conn_id async def test_receive_new_conn_with_cursors(self): + # TODO: 쿼리 로직 바뀌면 이것도 같이 바꿔야 함. CursorManager.cursor_dict = { "some id": Cursor.create("some id")