Last active
April 7, 2020 21:46
-
-
Save cgbeutler/e996652e5b28612d538be3eb941d47f3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Singleton Time | |
extends Node | |
## | |
# Set this class as a singleton in Godot named Time or similar. | |
# Setting it near the top will ensure it is processed before | |
# everything else, giving you consistent values for all nodes | |
# that use this class. | |
# this class has a global process and physics process count | |
# that is very useful when doing things less often. | |
# A wrapper has provided to make that even quicker: | |
# eg: if Time.process_every(5): do_thing_only_every_5_frames() | |
# There are two main timing objects: Stopwatch and TickTimer | |
# Stopwatches will increment at the beginning of the update | |
# frame and can be started, stopped and reset. It's value is | |
# a float of seconds since it was started. | |
# TickTag is a way of marking update frames. Useful for | |
# buffering values. Use tag_now() to update it's value, then | |
# current() or within(x) to check if the value is current or | |
# recent. | |
## | |
const TICK_MIN := -9223372036854775808 # int min | |
const TICK_MAX := 9223372036854775807 # int max | |
const TICK_START := TICK_MIN + 1000 # start global values 1000 more than tick tag values | |
var process :int = TICK_START | |
var physics_process :int = TICK_START | |
var process_stopwatches := [] | |
var physics_process_stopwatches := [] | |
var global_scale := 1.0 | |
func process_every( frames :int ): | |
return not process % frames | |
func physics_process_every( frames :int ): | |
return not physics_process % frames | |
func create_process_tick_tag() -> ProcessTickTag: | |
return ProcessTickTag.new(self) | |
func create_physics_process_tick_tag() -> PhysicsProcessTickTag: | |
return PhysicsProcessTickTag.new(self) | |
func create_process_stopwatch() -> Stopwatch: | |
var sw = Stopwatch.new() | |
process_stopwatches.append(weakref(sw)) | |
return sw | |
func create_physics_process_stopwatch() -> Stopwatch: | |
var sw = Stopwatch.new() | |
physics_process_stopwatches.append(weakref(sw)) | |
return sw | |
func _process( delta ): | |
process += 1 | |
var stopwatches_to_remove = [] | |
for i in range( process_stopwatches.size() ): | |
var stopwatch :Stopwatch = process_stopwatches[i].get_ref() | |
if stopwatch == null: | |
stopwatches_to_remove.append( i ) | |
elif stopwatch.running: | |
stopwatch.update( delta ) | |
if len(stopwatches_to_remove) > 0: | |
stopwatches_to_remove.invert() | |
for i in stopwatches_to_remove: | |
process_stopwatches.remove( i ) | |
func _physics_process( delta ): | |
physics_process += 1 | |
var stopwatches_to_remove = [] | |
for i in range( physics_process_stopwatches.size() ): | |
var stopwatch :Stopwatch = physics_process_stopwatches[i].get_ref() | |
if stopwatch == null: | |
stopwatches_to_remove.append( i ) | |
elif stopwatch.running: | |
stopwatch.update( delta ) | |
if len(stopwatches_to_remove) > 0: | |
for i in stopwatches_to_remove.invert(): | |
physics_process_stopwatches.remove( i ) | |
class Stopwatch: | |
var value :float = INF # Start maxed out, so no user things trigger without their say. | |
var running :bool = true | |
func reset( new_value :float = 0.0 ): | |
value = new_value | |
func stop(): | |
running = false | |
func resume(): | |
running = true | |
func update( delta :float ): | |
value += delta | |
class ProcessTickTag: | |
var value = TICK_MIN | |
var _time | |
func _init( time ): | |
_time = time | |
func tag_now(): | |
self.value = _time.process | |
func current() -> bool: | |
return self.value == _time.process | |
func within( frames : int ): | |
return (_time.process - self.value) <= frames | |
class PhysicsProcessTickTag: | |
var value = TICK_MIN | |
var _time | |
func _init( time ): | |
_time = time | |
func tag_now(): | |
self.value = _time.physics_process | |
func current() -> bool: | |
return self.value == _time.physics_process | |
func within( frames : int ): | |
return (_time.physics_process - self.value) <= frames |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment