Repository: ManimCommunity/manim
File: manim/renderer/shader.py (Python)

Code before:
        if self.parent is None:
            return self.normal_matrix[:3, :3]

        normal_matrices = [self.normal_matrix]
        current_object = self
        while current_object.parent is not None:
            normal_matrices.append(current_object.parent.model_matrix)
            current_object = current_object.parent
        return np.linalg.multi_dot(list(reversed(normal_matrices)))[:3, :3]

    def init_updaters(self) -> None:
        self.time_based_updaters: list[Callable] = []
        self.non_time_updaters: list[Callable] = []
        self.has_updaters = False
        self.updating_suspended = False

    def update(self, dt: float = 0) -> Self:
        if not self.has_updaters or self.updating_suspended:
            return self
        for updater in self.time_based_updaters:
            updater(self, dt)
        for updater in self.non_time_updaters:
            updater(self)
        return self

    def get_time_based_updaters(self) -> list[Callable]:
        return self.time_based_updaters

    def has_time_based_updater(self) -> bool:
        return len(self.time_based_updaters) > 0

    def get_updaters(self) -> list[Callable]:
        return self.time_based_updaters + self.non_time_updaters

    def add_updater(
        self,
        update_function: Callable,
        index: int | None = None,
        call_updater: bool = True,
    ) -> Self:
        if "dt" in inspect.signature(update_function).parameters:
            updater_list = self.time_based_updaters
        else:
            updater_list = self.non_time_updaters

        if index is None:
            updater_list.append(update_function)
        else:
            updater_list.insert(index, update_function)

        self.refresh_has_updater_status()

Review comment (suggestion):
```suggestion
    def get_time_based_updaters(self) -> list[MeshTimeBasedUpdater]:
```

Code after:
    def hierarchical_normal_matrix(self) -> MatrixMN:
        if self.parent is None:
            return self.normal_matrix[:3, :3]

        normal_matrices = [self.normal_matrix]
        current_object = self
        while current_object.parent is not None:
            normal_matrices.append(current_object.parent.model_matrix)
            current_object = current_object.parent
        return np.linalg.multi_dot(list(reversed(normal_matrices)))[:3, :3]

    def init_updaters(self) -> None:
        self.time_based_updaters: list[MeshTimeBasedUpdater] = []
        self.non_time_updaters: list[MeshNonTimeBasedUpdater] = []
        self.has_updaters = False
        self.updating_suspended = False

    def update(self, dt: float = 0) -> Self:
        if not self.has_updaters or self.updating_suspended:
            return self
        for time_based_updater in self.time_based_updaters:
            time_based_updater(self, dt)
        for non_time_based_updater in self.non_time_updaters:
            non_time_based_updater(self)
        return self

    def get_time_based_updaters(self) -> list[MeshTimeBasedUpdater]:
        return self.time_based_updaters

    def has_time_based_updater(self) -> bool:
        return len(self.time_based_updaters) > 0

    def get_updaters(self) -> list[MeshUpdater]:
        return self.time_based_updaters + self.non_time_updaters

    def add_updater(
        self,
        update_function: MeshUpdater,
        index: int | None = None,
        call_updater: bool = True,
    ) -> Self:
        if "dt" in inspect.signature(update_function).parameters:
            self._add_time_based_updater(update_function, index)  # type: ignore[arg-type]
        else:
            self._add_non_time_updater(update_function, index)  # type: ignore[arg-type]

        self.refresh_has_updater_status()
        if call_updater:
            self.update()
        return self