Source code for rubato.utils.time

"""
A time class to monitor time and to call functions in the future.

Attributes:
    frames (int): The total number of elapsed frames since the start of the
        game.
"""
from typing import Callable
from pygame.time import Clock, get_ticks

clock = Clock()

frames = 0
frame_tasks = {}

tasks = {}
sorted_task_times = []  # of the call keys

fdt = 20  # fixed delta time storage


[docs]def fixed_delta_time(form: str = "milli") -> float: """ Gets the time since the fixed update frame. Args: form: The format the output should be (sec, milli). Defaults to milli. Raises: ValueError: The form is not "sec" or "milli". Returns: float: Time since the fixed update frame, in the given form. """ if form == "sec": return milli_to_sec(fdt) elif form == "milli": return fdt else: raise ValueError(f"Style {form} is not valid")
[docs]def delta_time(form: str = "milli") -> float: """ Gets the time since the last frame. Args: form: The format the output should be (sec, milli). Defaults to milli. Raises: ValueError: The form is not "sec" or "milli". Returns: float: Time since the last frame, in the given form. """ if form == "sec": return milli_to_sec(clock.get_time()) elif form == "milli": return clock.get_time() else: raise ValueError(f"Style {form} is not valid")
[docs]def now() -> int: """ Gets the time since the start of the game, in milliseconds. Returns: int: Time since the start of the game, in milliseconds. """ return get_ticks()
[docs]def delayed_call(time_delta: int, func: Callable): """ Calls the function func at a later Args: time_delta: The time from now (in milliseconds) to run the function at. func: The function to call. """ run_at = time_delta + now() if tasks.get(run_at): tasks[run_at].append(func) else: tasks[run_at] = [func] proper_index = _binary_search(sorted_task_times, 0, len(sorted_task_times) - 1, run_at) if proper_index < 0: # time stamp not currently in array proper_index = ~proper_index sorted_task_times.insert(proper_index, run_at)
# otherwise we do not want to re-add time stamp
[docs]def delayed_frames(frames_delta: int, func: Callable): """ Calls the function func at a later frame. Args: frames_delta: The number of frames to wait. func: The function to call """ frame_call = frames + frames_delta frame_tasks[frame_call] = frame_tasks.get(frame_call, []) + [func]
[docs]def milli_to_sec(milli: int) -> float: """ Converts milliseconds to seconds. Args: milli: A number in milliseconds. Returns: float: The converted number in seconds. """ return milli / 1000
[docs]def set_clock(new_clock: "Clock"): """ Allows you to set the clock object property to a Pygame Clock object. Args: clock: A pygame Clock object. """ global clock clock = new_clock
[docs]def process_calls(): """Processes the calls needed""" global frames frames += 1 if (ft := frame_tasks.get(frames, None)) is not None: for task in ft: task() del frame_tasks[frames] for task_time in sorted_task_times: if task_time <= now(): for func in tasks[task_time]: func() del tasks[task_time] sorted_task_times.remove(task_time) else: break
def _binary_search(arr: list, low: int, high: int, val: any) -> int: """ A binary search algorithm. Args: arr: Array to be find index of insertion. Array must be pre sorted. low: The low interval in which you want to find the position. high: The high interval in which you want to find the position. val: Value in the array of which you want to find the position. Returns: int: The index of value in the array if it exists, otherwise it bit inverts (unary operator) the index if the element is not in the array. """ # Check base case if high >= low: mid = (high + low) // 2 # If element is present at the middle itself if arr[mid] == val: return mid # If element is smaller than mid, then it can only # be present in left subarray elif arr[mid] > val: return _binary_search(arr, low, mid - 1, val) # Else the element can only be present in right subarray else: return _binary_search(arr, mid + 1, high, val) else: # Element is not present in the array if high < len(arr) - 1: return ~(high + 1) # this way it will be negative if it is not present else: return ~len(arr)