Fixed some issues related to threading in game clock by using a queue

This commit is contained in:
2021-09-30 10:51:49 -05:00
parent 7bfc404413
commit fd6eb64232
10 changed files with 139 additions and 80 deletions

View File

@@ -1,13 +1,20 @@
module TAC
class PracticeGameClock
class ClockProxy
attr_reader :queue, :clock
def initialize(clock, jukebox)
@clock = clock
@jukebox = jukebox
@queue = []
@callbacks = {}
end
def enqueue(&block)
@queue << block
end
def register(callback, method)
@callbacks[callback] = method
end

View File

@@ -83,127 +83,143 @@ module TAC
end
def handle_start_clock(packet)
unless @host_is_a_connection
return if @host_is_a_connection
@proxy_object.enqueue do
@proxy_object.start_clock(packet.body.to_sym)
end
end
def handle_abort_clock(packet)
unless @host_is_a_connection
@proxy_object.abort_clock
end
return if @host_is_a_connection
@proxy_object.abort_clock
end
def handle_set_clock_title(packet)
unless @host_is_a_connection
title = packet.body
return if @host_is_a_connection
title = packet.body
@proxy_object.enqueue do
@proxy_object.set_clock_title(title)
end
end
def handle_get_clock_title(packet)
unless @host_is_a_connection
RemoteControl.server.active_client.puts(Packet.clock_title(@proxy_object.clock.title))
end
return if @host_is_a_connection
RemoteControl.server.active_client.puts(Packet.clock_title(@proxy_object.clock.title))
end
def handle_jukebox_previous_track(packet)
unless @host_is_a_connection
@proxy_object.jukebox_previous_track
return if @host_is_a_connection
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
@proxy_object.jukebox_previous_track
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
def handle_jukebox_next_track(packet)
unless @host_is_a_connection
@proxy_object.jukebox_next_track
return if @host_is_a_connection
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
@proxy_object.jukebox_next_track
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
def handle_jukebox_play(packet)
unless @host_is_a_connection
@proxy_object.jukebox_play
return if @host_is_a_connection
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
@proxy_object.jukebox_play
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
def handle_jukebox_pause(packet)
unless @host_is_a_connection
@proxy_object.jukebox_pause
return if @host_is_a_connection
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
@proxy_object.jukebox_pause
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
def handle_jukebox_stop(packet)
unless @host_is_a_connection
@proxy_object.jukebox_stop
return if @host_is_a_connection
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
@proxy_object.jukebox_stop
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_current_track(@proxy_object.jukebox_current_track))
end
def handle_jukebox_set_volume(packet)
unless @host_is_a_connection
float = packet.body.to_f
float = float.clamp(0.0, 1.0)
return if @host_is_a_connection
@proxy_object.jukebox_set_volume(float)
float = packet.body.to_f
float = float.clamp(0.0, 1.0)
float = @proxy_object.jukebox_volume
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_volume(float))
end
@proxy_object.jukebox_set_volume(float)
float = @proxy_object.jukebox_volume
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_volume(float))
end
def handle_jukebox_get_volume(packet)
unless @host_is_a_connection
float = @proxy_object.jukebox_volume
return if @host_is_a_connection
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_volume(float))
end
float = @proxy_object.jukebox_volume
RemoteControl.server.active_client.puts(PacketHandler.packet_jukebox_volume(float))
end
def handle_jukebox_volume(packet)
if @host_is_a_connection
float = packet.body.to_f
return unless @host_is_a_connection
float = packet.body.to_f
@proxy_object.enqueue do
@proxy_object.volume_changed(float)
end
end
def handle_jukebox_set_sound_effects(packet)
unless @host_is_a_connection
boolean = packet.body == "true"
return if @host_is_a_connection
boolean = packet.body == "true"
@proxy_object.enqueue do
@proxy_object.jukebox_set_sound_effects(boolean)
end
end
def handle_jukebox_current_track(packet)
if @host_is_a_connection
return unless @host_is_a_connection
@proxy_object.enqueue do
@proxy_object.track_changed(packet.body)
end
end
def handle_clock_time(packet)
if @host_is_a_connection
return unless @host_is_a_connection
@proxy_object.enqueue do
@proxy_object.clock_changed(packet.body)
end
end
def handle_randomizer_visible(packet)
boolean = packet.body == "true"
boolean = false if @proxy_object.is_a?(ClockProxy) && @proxy_object.clock.active?
@proxy_object.randomizer_changed(boolean)
unless @host_is_a_connection
# Send confirmation to client
RemoteControl.server.active_client.puts(PacketHandler.packet_randomizer_visible(boolean))
@proxy_object.enqueue do
@proxy_object.randomizer_changed(boolean)
end
return if @host_is_a_connection
# Send confirmation to client
RemoteControl.server.active_client.puts(PacketHandler.packet_randomizer_visible(boolean))
end
def handle_shutdown(packet)

View File

@@ -5,7 +5,8 @@ module TAC
TAG = "ClockNet|Server"
attr_reader :active_client,
:packets_sent, :packets_received, :data_sent, :data_received,
:client_last_packets_sent, :client_last_packets_received, :client_last_data_sent, :client_last_data_received
:client_last_packets_sent, :client_last_packets_received, :client_last_data_sent, :client_last_data_received,
:proxy_object
def initialize(hostname: "localhost", port: 4567, proxy_object: )
$server = self

View File

@@ -18,19 +18,19 @@ module TAC
# Blue: Right
# Red: Left
@ducks << Ducky.new(alliance: :blue, slot: 3, speed: 512, die_size: @size)
@ducks << Ducky.new(alliance: :red, slot: 1, speed: 512, die_size: @size)
@ducks << Ducky.new(window: window, alliance: :blue, slot: 3, speed: 512, die_size: @size)
@ducks << Ducky.new(window: window, alliance: :red, slot: 1, speed: 512, die_size: @size)
when 2, 5
#Blue and Red: Center
@ducks << Ducky.new(alliance: :blue, slot: 2, speed: 512, die_size: @size)
@ducks << Ducky.new(alliance: :red, slot: 2, speed: 512, die_size: @size)
@ducks << Ducky.new(window: window, alliance: :blue, slot: 2, speed: 512, die_size: @size)
@ducks << Ducky.new(window: window, alliance: :red, slot: 2, speed: 512, die_size: @size)
when 3, 6
# Blue: Left
# Red: Right
@ducks << Ducky.new(alliance: :blue, slot: 1, speed: 512, die_size: @size)
@ducks << Ducky.new(alliance: :red, slot: 3, speed: 512, die_size: @size)
@ducks << Ducky.new(window: window, alliance: :blue, slot: 1, speed: 512, die_size: @size)
@ducks << Ducky.new(window: window, alliance: :red, slot: 3, speed: 512, die_size: @size)
end
end
@@ -58,7 +58,7 @@ module TAC
def update
window.previous_state&.update_non_gui
@ducks.each { |o| o.update(window, @size) }
@ducks.each { |o| o.update(@size) }
@size = [window.width, window.height].min / 2.0
end
@@ -113,15 +113,17 @@ module TAC
SIZE = 0.20
HALF_SIZE = SIZE * 0.5
def initialize(alliance:, slot:, speed:, die_size:)
def initialize(window:, alliance:, slot:, speed:, die_size:)
@window = window
@alliance = alliance
@slot = slot
@speed = speed
@image = $window.get_image("#{ROOT_PATH}/media/openclipart_ducky.png")
@image = @window.get_image("#{ROOT_PATH}/media/openclipart_ducky.png")
@debug_text = Gosu::Font.new(28)
if @alliance == :blue
@position = CyberarmEngine::Vector.new($window.width, die_size)
@position = CyberarmEngine::Vector.new(@window.width, die_size)
else
@position = CyberarmEngine::Vector.new(-die_size, die_size + die_size * 0.40)
end
@@ -139,14 +141,14 @@ module TAC
end
end
def update(window, size)
center = window.width * 0.5 - size * 0.5
def update(size)
center = @window.width * 0.5 - size * 0.5
if @position.x > center
@position.x -= @speed * window.dt
@position.x -= @speed * @window.dt
@position.x = center if @position.x < center
elsif @position.x < center
@position.x += @speed * window.dt
@position.x += @speed * @window.dt
@position.x = center if @position.x > center
end
end

View File

@@ -178,7 +178,7 @@ module TAC
button get_image("#{ROOT_PATH}/media/icons/plus.png") do
@jukebox_volume += 0.1
@jukebox_volume = 0.1 if @jukebox_volume < 0.1
@jukebox_volume = 1.0 if @jukebox_volume > 1.0
RemoteControl.connection.puts(ClockNet::PacketHandler.packet_jukebox_set_volume(@jukebox_volume))
end
@@ -211,9 +211,7 @@ module TAC
stack width: 0.9, margin_left: 50, margin_top: 20 do
flow width: 1.0 do
title "Clock: "
@clock_label = title "0:123456789"
@clock_label.width
@clock_label.value = "0:00"
@clock_label = title "0:00"
end
flow width: 1.0 do
@@ -234,6 +232,10 @@ module TAC
def update
super
while (o = RemoteControl.connection.proxy_object.queue.shift)
o.call
end
return if RemoteControl.connection.connected?
# We've lost connection, unset window's connection object
@@ -252,7 +254,7 @@ module TAC
end
def volume_changed(float)
@volume.value = "#{float.round(1) * 100.0}%"
@volume.value = "#{(float.round(1) * 100.0).round}%"
end
def clock_changed(string)
@@ -260,7 +262,6 @@ module TAC
end
def randomizer_changed(boolean)
puts "Randomizer is visable? #{boolean}"
@randomizer_label.value = "Visible" if boolean
@randomizer_label.value = "Not Visible" unless boolean
end

View File

@@ -1,12 +1,19 @@
module TAC
class PracticeGameClock
class RemoteProxy
attr_reader :queue
def initialize(window)
@window = window
@queue = []
@callbacks = {}
end
def enqueue(&block)
@queue << block
end
def register(callback, method)
@callbacks[callback] = method
end

View File

@@ -5,12 +5,13 @@ module TAC
attr_reader :clock
def setup
window.show_cursor = true
@remote_control_mode = @options[:remote_control_mode]
window.show_cursor = !@remote_control_mode
@escape_counter = 0
@background_image = get_image("#{ROOT_PATH}/media/background.png")
# Preload duck image since Gosu and windows threads don't get along with OpenGL (image is blank if loaded in a threaded context)
get_image("#{ROOT_PATH}/media/openclipart_ducky.png")
@menu_background = 0xaa004000
@mouse = Mouse.new(window)
@clock = Clock.new
@@ -61,6 +62,7 @@ module TAC
else
@server&.close
@jukebox.stop
window.fullscreen = false
window.pop_state
end
@@ -172,8 +174,7 @@ module TAC
super
@clock.update
@mouse.update
@jukebox.update
@particle_emitters.each(&:update)
update_non_gui
if @last_clock_state != @clock.active?
@particle_emitters.each { |emitter| @clock.active? ? emitter.clock_active! : emitter.clock_inactive! }
@@ -213,6 +214,12 @@ module TAC
end
def update_non_gui
if @remote_control_mode
while (o = RemoteControl.server.proxy_object.queue.shift)
o.call
end
end
@particle_emitters.each(&:update)
@jukebox.update
end
@@ -251,7 +258,7 @@ module TAC
def randomizer_changed(boolean)
if boolean
push_state(Randomizer)
push_state(Randomizer) unless @clock.active?
else
pop_state if current_state.is_a?(Randomizer)
end