OverviewFilesCommitsIssuesDocsReleasesPeers

hypergodot2 commits / e653b61

initial example of hyper-sdk-rpc
e653b61c4fe217427d0ce799bee3a0d6dcd325e5
by Mauve Signweaver <contact@mauve.moe> · 2025-02-14T17:31:17.000Z

Changed files (7) +198 -0

.gitattributes +2 -0
……@@ -0,0 +1,2 @@
1# Normalize EOL for all files that Git considers text files.
2* text=auto eol=lf
.gitignore +3 -0
……@@ -0,0 +1,3 @@
1# Godot 4+ specific ignores
2.godot/
3/android/
example.gd +97 -0
……@@ -0,0 +1,97 @@
1extends Control
2
3@export var hostname: String = 'localhost'
4@export var port: int = 4772
5@export var protocol: String = 'tcp'
6
7signal rpc_response(response)
8
9const HYPER = "hyper://"
10
11var id = 0
12var socket = StreamPeerTCP.new()
13var buffer: PackedByteArray = PackedByteArray()
14var newline = "\n".unicode_at(0)
15
16# Called when the node enters the scene tree for the first time.
17func _ready() -> void:
18 connect_to_rpc()
19
20# Called every frame. 'delta' is the elapsed time since the previous frame.
21func _process(_delta: float) -> void:
22 socket.poll()
23 if socket.get_status() != StreamPeerTCP.STATUS_CONNECTED:
24 return
25 var available_bytes: int = socket.get_available_bytes()
26 if available_bytes <= 0:
27 return
28 var chunk = socket.get_partial_data(available_bytes)
29 if chunk[0] != OK:
30 printerr(chunk[0])
31 return
32 buffer.append_array(chunk[1])
33
34 while true:
35 var index = buffer.find(newline)
36 if index <= 0:
37 print("Temp Buffer",newline, buffer)
38 break
39 var line = buffer.slice(0, index).get_string_from_utf8()
40 buffer = buffer.slice(index+1)
41 var response = JSON.parse_string(line)
42 rpc_response.emit(response)
43
44func _on_line_edit_text_submitted(new_text: String) -> void:
45 print(new_text)
46 if !new_text.begins_with(HYPER):
47 printerr("Invalid hyper URL submitted")
48 return
49 var sections = new_text.substr(HYPER.length()).split("/")
50 var hostname = sections[0]
51 var path = "/" + "/".join(sections.slice(1))
52 if path.ends_with("/"):
53 var result = await send_rpc("sdk.getDrive(hostname).readdir(path)", {
54 hostname=HYPER+hostname,
55 path=path
56 })
57 if result.has("error"):
58 print(result["error"])
59 return
60 var paths = "- " + "\n- ".join(result["result"])
61 %OutputBox.text = paths
62 print(paths)
63
64 else:
65 var result = await send_rpc("sdk.getDrive(hostname).get(path)", {
66 hostname=HYPER+hostname,
67 path=path
68 })
69 if result.has("error"):
70 print(result["error"])
71 return
72 var content = PackedByteArray(result["result"]["data"]).get_string_from_utf8()
73 %OutputBox.text = content
74 print(content)
75
76func connect_to_rpc():
77 if socket.get_status() != socket.STATUS_CONNECTED:
78 socket.connect_to_host(hostname, port)
79
80func send_rpc(method: String, params):
81 print(method, params)
82 var next_id = id+1
83 id = next_id
84 var call = {
85 id = next_id,
86 method = method,
87 params = params,
88 }
89 var data = (JSON.stringify(call) + '\n').to_utf8_buffer()
90 socket.put_data(data)
91 var got_id = -1
92 var response = null
93 while got_id != next_id:
94 response = await rpc_response
95 print(response)
96 got_id = response["id"]
97 return response
example.tscn +42 -0
……@@ -0,0 +1,42 @@
1[gd_scene load_steps=2 format=3 uid="uid://cos218w6gyfpf"]
2
3[ext_resource type="Script" path="res://example.gd" id="1_v8epm"]
4
5[node name="Control" type="Control"]
6layout_mode = 3
7anchors_preset = 15
8anchor_right = 1.0
9anchor_bottom = 1.0
10grow_horizontal = 2
11grow_vertical = 2
12script = ExtResource("1_v8epm")
13
14[node name="VSplitContainer" type="VSplitContainer" parent="."]
15layout_mode = 1
16anchors_preset = 15
17anchor_right = 1.0
18anchor_bottom = 1.0
19grow_horizontal = 2
20grow_vertical = 2
21
22[node name="LineEdit" type="LineEdit" parent="VSplitContainer"]
23layout_mode = 2
24text = "hyper://agregore.mauve.moe/index.md"
25
26[node name="ScrollContainer" type="ScrollContainer" parent="VSplitContainer"]
27layout_mode = 2
28follow_focus = true
29horizontal_scroll_mode = 0
30vertical_scroll_mode = 2
31
32[node name="OutputBox" type="RichTextLabel" parent="VSplitContainer/ScrollContainer"]
33unique_name_in_owner = true
34layout_mode = 2
35size_flags_horizontal = 3
36focus_mode = 2
37text = "LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM LOREM IPSUM "
38fit_content = true
39threaded = true
40selection_enabled = true
41
42[connection signal="text_submitted" from="VSplitContainer/LineEdit" to="." method="_on_line_edit_text_submitted"]
icon.svg +1 -0
……@@ -0,0 +1 @@
1<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>
icon.svg.import +37 -0
……@@ -0,0 +1,37 @@
1[remap]
2
3importer="texture"
4type="CompressedTexture2D"
5uid="uid://b7efygpsot4m2"
6path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
7metadata={
8"vram_texture": false
9}
10
11[deps]
12
13source_file="res://icon.svg"
14dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
15
16[params]
17
18compress/mode=0
19compress/high_quality=false
20compress/lossy_quality=0.7
21compress/hdr_compression=1
22compress/normal_map=0
23compress/channel_pack=0
24mipmaps/generate=false
25mipmaps/limit=-1
26roughness/mode=0
27roughness/src_normal=""
28process/fix_alpha_border=true
29process/premult_alpha=false
30process/normal_map_invert_y=false
31process/hdr_as_srgb=false
32process/hdr_clamp_exposure=false
33process/size_limit=0
34detect_3d/compress_to=1
35svg/scale=1.0
36editor/scale_with_editor_scale=false
37editor/convert_colors_with_editor_theme=false
project.godot +16 -0
……@@ -0,0 +1,16 @@
1; Engine configuration file.
2; It's best edited using the editor UI and not directly,
3; since the parameters that go here are not all obvious.
4;
5; Format:
6; [section] ; section goes between []
7; param=value ; assign values to parameters
8
9config_version=5
10
11[application]
12
13config/name="hypergodot2"
14run/main_scene="res://example.tscn"
15config/features=PackedStringArray("4.3", "Forward Plus")
16config/icon="res://icon.svg"