array2d.pyi 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. from typing import Callable, Literal, overload, Iterator, Self
  2. from vmath import vec2i
  3. Neighborhood = Literal['Moore', 'von Neumann']
  4. class array2d_like[T]:
  5. @property
  6. def n_cols(self) -> int: ...
  7. @property
  8. def n_rows(self) -> int: ...
  9. @property
  10. def width(self) -> int: ...
  11. @property
  12. def height(self) -> int: ...
  13. @property
  14. def shape(self) -> vec2i: ...
  15. @property
  16. def numel(self) -> int: ...
  17. @overload
  18. def is_valid(self, col: int, row: int) -> bool: ...
  19. @overload
  20. def is_valid(self, pos: vec2i) -> bool: ...
  21. def get[R](self, col: int, row: int, default: R = None) -> T | R:
  22. """Get the value at the given position.
  23. If the position is out of bounds, returns the default value.
  24. """
  25. def render(self) -> str: ...
  26. def all(self: array2d_like[bool]) -> bool: ...
  27. def any(self: array2d_like[bool]) -> bool: ...
  28. def map[R](self, f: Callable[[T], R]) -> array2d[R]: ...
  29. def apply(self, f: Callable[[T], T]) -> None: ...
  30. def zip_with[R, U](self, other: array2d_like[U], f: Callable[[T, U], R]) -> array2d[R]: ...
  31. def copy(self) -> 'array2d[T]': ...
  32. def tolist(self) -> list[list[T]]: ...
  33. def __le__(self, other: T | array2d_like[T]) -> array2d[bool]: ...
  34. def __lt__(self, other: T | array2d_like[T]) -> array2d[bool]: ...
  35. def __ge__(self, other: T | array2d_like[T]) -> array2d[bool]: ...
  36. def __gt__(self, other: T | array2d_like[T]) -> array2d[bool]: ...
  37. def __eq__(self, other: T | array2d_like[T]) -> array2d[bool]: ... # type: ignore
  38. def __ne__(self, other: T | array2d_like[T]) -> array2d[bool]: ... # type: ignore
  39. def __add__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  40. def __sub__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  41. def __mul__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  42. def __truediv__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  43. def __floordiv__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  44. def __mod__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  45. def __pow__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  46. def __and__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  47. def __or__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  48. def __xor__(self, other: T | array2d_like[T]) -> array2d[T]: ...
  49. def __invert__(self) -> array2d[T]: ...
  50. def __iter__(self) -> Iterator[tuple[vec2i, T]]: ...
  51. def __repr__(self) -> str: ...
  52. @overload
  53. def __getitem__(self, index: vec2i) -> T: ...
  54. @overload
  55. def __getitem__(self, index: tuple[int, int]) -> T: ...
  56. @overload
  57. def __getitem__(self, index: tuple[slice, slice]) -> array2d_view[T]: ...
  58. @overload
  59. def __getitem__(self, index: tuple[slice, int] | tuple[int, slice]) -> array2d_view[T]: ...
  60. @overload
  61. def __getitem__(self, mask: array2d_like[bool]) -> list[T]: ...
  62. @overload
  63. def __setitem__(self, index: vec2i, value: T): ...
  64. @overload
  65. def __setitem__(self, index: tuple[int, int], value: T): ...
  66. @overload
  67. def __setitem__(self, index: tuple[slice, slice], value: T | 'array2d_like[T]'): ...
  68. @overload
  69. def __setitem__(self, index: tuple[slice, int] | tuple[int, slice], value: T | 'array2d_like[T]'): ...
  70. @overload
  71. def __setitem__(self, mask: array2d_like[bool], value: T): ...
  72. # algorithms
  73. def count(self, value: T) -> int:
  74. """Count the number of cells with the given value."""
  75. def count_neighbors(self, value: T, neighborhood: Neighborhood) -> array2d[int]:
  76. """Count the number of neighbors with the given value for each cell."""
  77. def get_bounding_rect(self, value: T) -> tuple[int, int, int, int]:
  78. """Get the bounding rectangle of the given value.
  79. Returns a tuple `(x, y, width, height)` or raise `ValueError` if the value is not found.
  80. """
  81. def convolve(self: array2d_like[int], kernel: array2d_like[int], padding: int) -> array2d[int]:
  82. """Convolve the array with the given kernel."""
  83. def get_connected_components(self, value: T, neighborhood: Neighborhood) -> tuple[array2d[int], int]:
  84. """Get connected components of the grid via BFS algorithm.
  85. Returns the `visited` array and the number of connected components,
  86. where `0` means unvisited, and non-zero means the index of the connected component.
  87. """
  88. class array2d_view[T](array2d_like[T]):
  89. @property
  90. def origin(self) -> vec2i: ...
  91. class array2d[T](array2d_like[T]):
  92. def __new__(
  93. cls,
  94. n_cols: int,
  95. n_rows: int,
  96. default: T | Callable[[vec2i], T] | None = None
  97. ): ...
  98. @staticmethod
  99. def fromlist(data: list[list[T]]) -> array2d[T]: ...
  100. class chunked_array2d[T, TContext]:
  101. def __new__(
  102. cls,
  103. chunk_size: int,
  104. default: T = None,
  105. context_builder: Callable[[vec2i], TContext] | None = None,
  106. ): ...
  107. @property
  108. def chunk_size(self) -> int: ...
  109. @property
  110. def default(self) -> T: ...
  111. @property
  112. def context_builder(self) -> Callable[[vec2i], TContext] | None: ...
  113. def __getitem__(self, index: vec2i) -> T: ...
  114. def __setitem__(self, index: vec2i, value: T): ...
  115. def __delitem__(self, index: vec2i): ...
  116. def __iter__(self) -> Iterator[tuple[vec2i, TContext]]: ...
  117. def __len__(self) -> int: ...
  118. def clear(self) -> None: ...
  119. def copy(self) -> Self: ...
  120. def world_to_chunk(self, world_pos: vec2i) -> tuple[vec2i, vec2i]:
  121. """Converts world position to chunk position and local position."""
  122. def add_chunk(self, chunk_pos: vec2i) -> TContext: ...
  123. def remove_chunk(self, chunk_pos: vec2i) -> bool: ...
  124. def move_chunk(self, src_chunk_pos: vec2i, dst_chunk_pos: vec2i) -> bool: ...
  125. def get_context(self, chunk_pos: vec2i) -> TContext | None: ...
  126. def view(self) -> array2d_view[T]: ...
  127. def view_rect(self, pos: vec2i, width: int, height: int) -> array2d_view[T]: ...
  128. def view_chunk(self, chunk_pos: vec2i) -> array2d_view[T]: ...
  129. def view_chunks(self, chunk_pos: vec2i, width: int, height: int) -> array2d_view[T]: ...