Skip to content

Instantly share code, notes, and snippets.

@skinnyjames
Last active March 12, 2024 15:37
Show Gist options
  • Save skinnyjames/8e62413fdd1f428fe800c8e82b1441d2 to your computer and use it in GitHub Desktop.
Save skinnyjames/8e62413fdd1f428fe800c8e82b1441d2 to your computer and use it in GitHub Desktop.
test.cr
require "socket"
require "./format"
module Test
Log.setup do |log|
dispatcher = Log::DispatchMode::Direct
backend = Log::IOBackend.new(dispatcher: dispatcher, formatter: Format)
log.bind "*", :trace, backend
end
# structs
record Stop
record Command, data : String
record PartialCommand, data : String
# udp
def self.start_udp_server(socket, network_channel)
loop do
request = socket.receive
break if request == "stop_it"
network_channel.send request
end
end
# command
def self.start_command_server(io, command_channel)
command = Array(Char).new
loop do
char = io.raw {|a| a.read_char }
case char
when nil
break
when '\u{3}'
print "^C\r\n"
break
when '\u{4}'
print "\r\n"
break
# TODO: Arrow keys
when '\r'
command_channel.send Command.new(command.join)
command.clear
when '\u{7f}'
command_channel.send PartialCommand.new(command.join) if command.pop?
else
command << char
command_channel.send PartialCommand.new(command.join)
end
end
Log.trace {"stopped command fiber"}
end
# main loop
def self.main
# channels
network_channel = Channel({String, Socket::IPAddress}).new
command_channel = Channel(Command | PartialCommand).new
me = Socket::IPAddress.new("127.0.0.1", 1234)
socket = UDPSocket.new
socket.bind(me)
io = STDIN
termios = uninitialized LibC::Termios
ret = LibC.tcgetattr(io.fd, pointerof(termios))
puts termios.inspect
spawn start_udp_server(socket, network_channel)
spawn start_command_server(io, command_channel)
print "> "
loop do
current_input = ""
select
when request = network_channel.receive
print "\e[2K\r"
message, client_addr = request
Log.info { "Received message: \"#{message}\" from #{client_addr}" }
print "> #{current_input}"
when command = command_channel.receive
print "\e[2K\r"
case command
when Command
case command.data
when "stop"
Log.info { "Stopping server!" }
socket.send("stop_it", to: me)
LibC.tcsetattr(io.fd, LibC::TCSANOW, pointerof(termios))
io.close
break
when "hello"
Log.info { "world!" }
else
Log.error &.emit "Unknown command!"
end
current_input = ""
when PartialCommand
current_input = command.data
end
print "> #{current_input}"
end
end
puts "all done!"
end
end
Test.main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment