Implement job assignment via WebSocket
This commit is contained in:
63
JobServer.gd
63
JobServer.gd
@@ -1,8 +1,59 @@
|
|||||||
extends HTTPRequest
|
extends HTTPRequest
|
||||||
|
|
||||||
func GetJob():
|
var socket = WebSocketPeer.new()
|
||||||
print("Fetching Job")
|
|
||||||
request("http://127.0.0.1:8000/template.json")
|
func InitWebsocket():
|
||||||
var res = await request_completed
|
print("Connecting websocket ")
|
||||||
var json = JSON.parse_string(res[3].get_string_from_utf8())
|
var i = 0
|
||||||
return json
|
while socket.get_ready_state() != WebSocketPeer.STATE_OPEN:
|
||||||
|
socket.connect_to_url($"/root/Main".websocket_url, TLSOptions.client_unsafe())
|
||||||
|
socket.poll()
|
||||||
|
|
||||||
|
|
||||||
|
socket.send_text(str({"register": 1}))
|
||||||
|
print("Connected")
|
||||||
|
while true:
|
||||||
|
await PollWebsocket()
|
||||||
|
|
||||||
|
|
||||||
|
func PollWebsocket():
|
||||||
|
var main = $"/root/Main"
|
||||||
|
socket.poll()
|
||||||
|
var state = socket.get_ready_state()
|
||||||
|
if state == WebSocketPeer.STATE_OPEN:
|
||||||
|
while socket.get_available_packet_count():
|
||||||
|
var packet = socket.get_packet()
|
||||||
|
var json = JSON.parse_string(packet.get_string_from_utf8())
|
||||||
|
print("Packet: ", packet.slice(0,5), "...")
|
||||||
|
if "welcome" in json:
|
||||||
|
print("Registered as client %s" % json["welcome"]["clientId"])
|
||||||
|
if "job" in json:
|
||||||
|
var job = json["job"]
|
||||||
|
print("Recevied Job ", job["jobId"])
|
||||||
|
main.rendering = true
|
||||||
|
var result = await $"../Renderer".RenderJob(job)
|
||||||
|
var response = {
|
||||||
|
"result": {
|
||||||
|
"jobId": job["jobId"],
|
||||||
|
"path": $"/root/Main".public_path + result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
socket.send_text(str(response))
|
||||||
|
print("Sent result ", result)
|
||||||
|
main.rendering = false
|
||||||
|
elif state == WebSocketPeer.STATE_CLOSING:
|
||||||
|
# Keep polling to achieve proper close.
|
||||||
|
pass
|
||||||
|
elif state == WebSocketPeer.STATE_CLOSED:
|
||||||
|
var code = socket.get_close_code()
|
||||||
|
var reason = socket.get_close_reason()
|
||||||
|
print("WebSocket closed with code: %d, reason %s. Clean: %s" % [code, reason, code != -1])
|
||||||
|
print("Attempting reconnect in 10")
|
||||||
|
set_process(false) # Stop processing.
|
||||||
|
await get_tree().create_timer(10).timeout
|
||||||
|
InitWebsocket()
|
||||||
|
|
||||||
|
func _process(_delta):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
20
Main.gd
Normal file
20
Main.gd
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
var config = ConfigFile.new()
|
||||||
|
|
||||||
|
var websocket_url
|
||||||
|
var public_path
|
||||||
|
var rendering = false
|
||||||
|
signal finished_rendering
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready():
|
||||||
|
config.load("res://config.cfg")
|
||||||
|
websocket_url = config.get_value("core", "websocket_url")
|
||||||
|
public_path = config.get_value("core", "public_path")
|
||||||
|
|
||||||
|
print("Starting render node")
|
||||||
|
$JobServer.InitWebsocket()
|
||||||
|
|
||||||
|
func FinishedRendering():
|
||||||
|
rendering = false
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
var counter = 1
|
var counter = 1
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready():
|
func _ready():
|
||||||
print("render ready")
|
pass
|
||||||
|
"""
|
||||||
var job = await $JobServer.GetJob()
|
var job = await $JobServer.GetJob()
|
||||||
var jobHash = str([job["size"], job["elements"]]).sha1_text()
|
var jobHash = str([job["size"], job["elements"]]).sha1_text()
|
||||||
print("Job hash %s" % jobHash)
|
print("Job hash %s" % jobHash)
|
||||||
@@ -13,20 +15,38 @@ func _ready():
|
|||||||
print("Skipping, file exists")
|
print("Skipping, file exists")
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
return
|
return
|
||||||
|
"""
|
||||||
|
|
||||||
|
#DisplayServer.window_set_size(Vector2(job["size"]["width"], job["size"]["height"]))
|
||||||
|
#await RenderComposition(job["elements"])
|
||||||
|
#await RenderingServer.frame_post_draw
|
||||||
|
|
||||||
|
# Get rendered image
|
||||||
|
#var img = get_viewport().get_texture().get_image()
|
||||||
|
|
||||||
|
#img.save_png(outFile)
|
||||||
|
#get_tree().quit()
|
||||||
|
|
||||||
|
func RenderJob(job):
|
||||||
|
print("Rendering ", job["jobId"])
|
||||||
|
var renderContainer = $"/root/Main/RenderContainer"
|
||||||
|
for node in renderContainer.get_children():
|
||||||
|
renderContainer.remove_child(node)
|
||||||
|
node.free()
|
||||||
|
print("Cleared Render container")
|
||||||
DisplayServer.window_set_size(Vector2(job["size"]["width"], job["size"]["height"]))
|
DisplayServer.window_set_size(Vector2(job["size"]["width"], job["size"]["height"]))
|
||||||
await RenderComposition(job["elements"])
|
await RenderComposition(job["elements"])
|
||||||
await RenderingServer.frame_post_draw
|
await RenderingServer.frame_post_draw
|
||||||
|
|
||||||
# Get rendered image
|
# Get rendered image
|
||||||
var img = get_viewport().get_texture().get_image()
|
var img = get_viewport().get_texture().get_image()
|
||||||
|
var outFile = "%s_%s.png" % [job["type"],job["jobId"]]
|
||||||
|
img.save_png("output/" + outFile)
|
||||||
|
|
||||||
img.save_png(outFile)
|
return outFile
|
||||||
#get_tree().quit()
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
func _process(delta):
|
func _process(_delta):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func run_test():
|
func run_test():
|
||||||
@@ -46,12 +66,12 @@ func RenderComposition(composition):
|
|||||||
func RenderImage(def):
|
func RenderImage(def):
|
||||||
var imageNode = TextureRect.new()
|
var imageNode = TextureRect.new()
|
||||||
var image = Image.new()
|
var image = Image.new()
|
||||||
image = await $Remote.GetRemoteImage(def["asset"])
|
image = await $"../Remote".GetRemoteImage(def["asset"])
|
||||||
var texture = ImageTexture.new()
|
var texture = ImageTexture.new()
|
||||||
texture = ImageTexture.create_from_image(image)
|
texture = ImageTexture.create_from_image(image)
|
||||||
texture.set_size_override(Vector2(def["width"], def["height"]))
|
texture.set_size_override(Vector2(def["width"], def["height"]))
|
||||||
imageNode.texture = texture
|
imageNode.texture = texture
|
||||||
$Placeholder.add_sibling(imageNode)
|
$"/root/Main/RenderContainer".add_child(imageNode)
|
||||||
|
|
||||||
func RenderLabel(def):
|
func RenderLabel(def):
|
||||||
var textNode = Label.new()
|
var textNode = Label.new()
|
||||||
@@ -72,11 +92,11 @@ func RenderLabel(def):
|
|||||||
var alignments = { "left": HORIZONTAL_ALIGNMENT_LEFT, "right": HORIZONTAL_ALIGNMENT_RIGHT, "center": HORIZONTAL_ALIGNMENT_CENTER, "fill": HORIZONTAL_ALIGNMENT_FILL }
|
var alignments = { "left": HORIZONTAL_ALIGNMENT_LEFT, "right": HORIZONTAL_ALIGNMENT_RIGHT, "center": HORIZONTAL_ALIGNMENT_CENTER, "fill": HORIZONTAL_ALIGNMENT_FILL }
|
||||||
textNode.horizontal_alignment = alignments[def["horizontalAlignment"]]
|
textNode.horizontal_alignment = alignments[def["horizontalAlignment"]]
|
||||||
|
|
||||||
get_tree().get_root().add_child(textNode)
|
$"/root/Main/RenderContainer".add_child(textNode)
|
||||||
|
|
||||||
func render():
|
func render():
|
||||||
print("Rendering frame %s" % counter)
|
print("Rendering frame %s" % counter)
|
||||||
var tstamp_label = $Placeholder/tstamp
|
var tstamp_label = $"../Placeholder/tstamp"
|
||||||
var tstamp = Time.get_ticks_usec()
|
var tstamp = Time.get_ticks_usec()
|
||||||
tstamp_label.text = str(tstamp) + "\n %s" % counter
|
tstamp_label.text = str(tstamp) + "\n %s" % counter
|
||||||
await RenderingServer.frame_post_draw
|
await RenderingServer.frame_post_draw
|
||||||
3
config.cfg
Normal file
3
config.cfg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[core]
|
||||||
|
websocket_url="ws://127.0.0.1:6980"
|
||||||
|
public_path="http://localhost:8899/"
|
||||||
14
node_2d.tscn
14
node_2d.tscn
@@ -1,12 +1,13 @@
|
|||||||
[gd_scene load_steps=5 format=3 uid="uid://dpcjcts1oj1xb"]
|
[gd_scene load_steps=6 format=3 uid="uid://8flqeh3gn68"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://render.gd" id="1_13t8u"]
|
[ext_resource type="Script" path="res://Renderer.gd" id="1_0maq1"]
|
||||||
|
[ext_resource type="Script" path="res://Main.gd" id="1_6qp7h"]
|
||||||
[ext_resource type="Texture2D" uid="uid://skthvfx7pq6m" path="res://_e2199ab5-ff42-4ddf-8540-1c16e2d7889f.jpeg" id="1_la77t"]
|
[ext_resource type="Texture2D" uid="uid://skthvfx7pq6m" path="res://_e2199ab5-ff42-4ddf-8540-1c16e2d7889f.jpeg" id="1_la77t"]
|
||||||
[ext_resource type="Script" path="res://JobServer.gd" id="3_mg2dt"]
|
[ext_resource type="Script" path="res://JobServer.gd" id="3_mg2dt"]
|
||||||
[ext_resource type="Script" path="res://RemoteLoader.gd" id="4_k4afm"]
|
[ext_resource type="Script" path="res://RemoteLoader.gd" id="4_k4afm"]
|
||||||
|
|
||||||
[node name="Node2D" type="Node2D"]
|
[node name="Main" type="Node2D"]
|
||||||
script = ExtResource("1_13t8u")
|
script = ExtResource("1_6qp7h")
|
||||||
|
|
||||||
[node name="JobServer" type="HTTPRequest" parent="."]
|
[node name="JobServer" type="HTTPRequest" parent="."]
|
||||||
script = ExtResource("3_mg2dt")
|
script = ExtResource("3_mg2dt")
|
||||||
@@ -19,3 +20,8 @@ visible = false
|
|||||||
position = Vector2(580.25, 314.25)
|
position = Vector2(580.25, 314.25)
|
||||||
scale = Vector2(0.532715, 0.532715)
|
scale = Vector2(0.532715, 0.532715)
|
||||||
texture = ExtResource("1_la77t")
|
texture = ExtResource("1_la77t")
|
||||||
|
|
||||||
|
[node name="Renderer" type="Node2D" parent="."]
|
||||||
|
script = ExtResource("1_0maq1")
|
||||||
|
|
||||||
|
[node name="RenderContainer" type="Node" parent="."]
|
||||||
|
|||||||
Reference in New Issue
Block a user