Source code for bascenev1lib.actor.onscreentimer

# Released under the MIT License. See LICENSE for details.
#
"""Defines Actor(s)."""
from __future__ import annotations

from typing import TYPE_CHECKING, override
import logging

import bascenev1 as bs

if TYPE_CHECKING:
    from typing import Any


[docs] class OnScreenTimer(bs.Actor): """A handy on-screen timer. Useful for time-based games where time increases. """ def __init__(self) -> None: super().__init__() self._starttime_ms: int | None = None self.node = bs.newnode( 'text', attrs={ 'v_attach': 'top', 'h_attach': 'center', 'h_align': 'center', 'color': (1, 1, 0.5, 1), 'flatness': 0.5, 'shadow': 0.5, 'position': (0, -70), 'scale': 1.4, 'text': '', }, ) self.inputnode = bs.newnode( 'timedisplay', attrs={'timemin': 0, 'showsubseconds': True} ) self.inputnode.connectattr('output', self.node, 'text')
[docs] def start(self) -> None: """Start the timer.""" tval = int(bs.time() * 1000.0) assert isinstance(tval, int) self._starttime_ms = tval self.inputnode.time1 = self._starttime_ms bs.getactivity().globalsnode.connectattr( 'time', self.inputnode, 'time2' )
[docs] def has_started(self) -> bool: """Return whether this timer has started yet.""" return self._starttime_ms is not None
[docs] def stop(self, endtime: int | float | None = None) -> None: """End the timer. If 'endtime' is not None, it is used when calculating the final display time; otherwise the current time is used. """ if endtime is None: endtime = bs.time() if self._starttime_ms is None: logging.warning( 'OnScreenTimer.stop() called without first calling start()' ) else: endtime_ms = int(endtime * 1000) self.inputnode.timemax = endtime_ms - self._starttime_ms
[docs] def getstarttime(self) -> float: """Return the scene-time when start() was called. Time will be returned in seconds if timeformat is SECONDS or milliseconds if it is MILLISECONDS. """ val_ms: Any if self._starttime_ms is None: print('WARNING: getstarttime() called on un-started timer') val_ms = int(bs.time() * 1000.0) else: val_ms = self._starttime_ms assert isinstance(val_ms, int) return 0.001 * val_ms
@property def starttime(self) -> float: """Shortcut for start time in seconds.""" return self.getstarttime()
[docs] @override def handlemessage(self, msg: Any) -> Any: # if we're asked to die, just kill our node/timer if isinstance(msg, bs.DieMessage): if self.node: self.node.delete()
# Docs-generation hack; import some stuff that we likely only forward-declared # in our actual source code so that docs tools can find it. from typing import (Coroutine, Any, Literal, Callable, Generator, Awaitable, Sequence, Self) import asyncio from concurrent.futures import Future from pathlib import Path from enum import Enum