mirror of
https://codeberg.org/sunder/sunder.git
synced 2026-03-07 19:00:26 +00:00
81 lines
1.9 KiB
GDScript
81 lines
1.9 KiB
GDScript
class_name MotionService extends RefCounted
|
|
|
|
@export var RATE_HZ := 64
|
|
|
|
var running := false
|
|
|
|
var delta:float:
|
|
get: return 1.0 / RATE_HZ
|
|
set(value): pass
|
|
|
|
var _threads:Dictionary[int, Thread]
|
|
var _clock:Thread
|
|
var _semaphore:Semaphore
|
|
var _mutex:Mutex
|
|
|
|
var tick := 0:
|
|
set(value):
|
|
tick = value % RATE_HZ
|
|
|
|
func _init() -> void:
|
|
_clock = Thread.new()
|
|
_mutex = Mutex.new()
|
|
_semaphore = Semaphore.new()
|
|
#multiplayer.peer_connected.connect(_on_peer_connected)
|
|
#multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
|
|
|
func register(id:int) -> void:
|
|
if !running:
|
|
running = true
|
|
_clock.start(_loop)
|
|
prints("motion_service: starting clock")
|
|
prints("motion_service: register peer", id)
|
|
_threads[id] = Thread.new()
|
|
_threads[id].start(_worker.bind(id))
|
|
|
|
func unregister(id:int) -> void:
|
|
if running:
|
|
prints("motion_service: unregistering peer", id)
|
|
if _threads[id].is_alive():
|
|
_threads[id].wait_to_finish()
|
|
_threads.erase(id)
|
|
if len(_threads) == 0:
|
|
running = false
|
|
if _clock.is_alive():
|
|
_clock.wait_to_finish()
|
|
_clock = null
|
|
|
|
func _exit_tree() -> void:
|
|
if running:
|
|
for id:int in _threads.keys():
|
|
unregister(id)
|
|
|
|
func _loop() -> void:
|
|
var next_time:float = Time.get_ticks_msec() / 1000.
|
|
while running:
|
|
_semaphore.post(len(_threads))
|
|
_mutex.lock()
|
|
next_time += delta
|
|
_mutex.unlock()
|
|
var sleep_time:float = next_time - (Time.get_ticks_msec() / 1000.)
|
|
if sleep_time > 0:
|
|
# delay current thread
|
|
OS.delay_msec(int(sleep_time * 1000))
|
|
else:
|
|
_mutex.lock()
|
|
# we are behind; reset next_time to avoid drift
|
|
next_time = Time.get_ticks_msec() / 1000.
|
|
_mutex.unlock()
|
|
|
|
_mutex.lock()
|
|
tick += 1
|
|
_mutex.unlock()
|
|
|
|
func _worker(peer_id:int) -> void:
|
|
while running:
|
|
_semaphore.wait() # wait until posted
|
|
#prints("tick", tick, "for peer", peer_id)
|
|
|
|
#var player:Player = owner.players.get_node(str(peer_id))
|
|
#if player:
|
|
#player.send_position.rpc(player.global_position)
|