| … | … | @@ -13,14 +13,15 @@ A Godot plugin and example project for loading assets from the [hypercore-protoc |
| 13 | 13 | |
| 14 | 14 | ## TODOs: |
| 15 | 15 | |
| 16 | - Folder sync (From `hyper://` to fs, from fs to `hyper://`) | |
| 17 | 16 | - Reuse `HyperGateway` instance between `HyperRequest` objects |
| 18 | - Listen for download progress (EventSource) | |
| 17 | - Example for saving data to hyper | |
| 18 | - Make FTP server that can be mounted as a network drive | |
| 19 | 19 | - Listen for changes (EventSource) |
| 20 | - Listen for download progress (EventSource) | |
| 20 | 21 | - Listen for / Publish extension messages (EventSource) |
| 21 | - Example for saving data to hyper | |
| 22 | 22 | - Examples for all the methods exposed by the gateway. |
| 23 | 23 | - Basic Multiplayer demo using extension messages |
| 24 | - Folder sync (From `hyper://` to fs, from fs to `hyper://`) | |
| 24 | 25 | |
| 25 | 26 | ## Supported APIs: |
| 26 | 27 |
| … | … | @@ -11,7 +11,7 @@ config_version=4 |
| 11 | 11 | [application] |
| 12 | 12 | |
| 13 | 13 | config/name="HyperGodot" |
| 14 | run/main_scene="res://src/HyperLoad.tscn" | |
| 14 | run/main_scene="res://src/HyperLoad/HyperLoad.tscn" | |
| 15 | 15 | config/icon="res://icon.png" |
| 16 | 16 | |
| 17 | 17 | [display] |
| … | … | @@ -0,0 +1,76 @@ |
| 1 | extends Node | |
| 2 | ||
| 3 | ||
| 4 | # Declare member variables here. Examples: | |
| 5 | # var a = 2 | |
| 6 | # var b = "text" | |
| 7 | ||
| 8 | signal starting_gateway() | |
| 9 | signal started_gateway(pid) | |
| 10 | ||
| 11 | export var processPID = 0 | |
| 12 | export var serverPrefix = "http://127.0.0.1:4973/hyper/" | |
| 13 | export var storageDirectory = 'user://gateway-data/' | |
| 14 | export var autoStart = false | |
| 15 | ||
| 16 | func _notification(what): | |
| 17 | if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST: | |
| 18 | cleanupGateway() | |
| 19 | pass | |
| 20 | ||
| 21 | # Called when the node enters the scene tree for the first time. | |
| 22 | func _ready(): | |
| 23 | if autoStart: ensureSetup() | |
| 24 | pass # Replace with function body. | |
| 25 | ||
| 26 | func cleanupGateway(): | |
| 27 | if processPID == 0: | |
| 28 | print('Gateway already closed ' + str(processPID)) | |
| 29 | return | |
| 30 | print('Cleaning up gateway ' + str(processPID)) | |
| 31 | OS.kill(processPID) | |
| 32 | pass | |
| 33 | ||
| 34 | func setupGateway(): | |
| 35 | emit_signal("starting_gateway") | |
| 36 | var executiblePath = getExecutiblePath() | |
| 37 | var executibleFile = File.new() | |
| 38 | ||
| 39 | executibleFile.open(executiblePath, File.READ) | |
| 40 | ||
| 41 | var path = executibleFile.get_path_absolute() | |
| 42 | executibleFile.close() | |
| 43 | ||
| 44 | var args = ["run", "--no-persist"] | |
| 45 | ||
| 46 | print("Starting gateway from " + path) | |
| 47 | ||
| 48 | # Start the hyper-gateway in a process | |
| 49 | processPID = OS.execute(path, args, false) | |
| 50 | ||
| 51 | # Sleep for a bit while the gateway loads | |
| 52 | # TODO: Find a better indicator like polling the HTTP server socket | |
| 53 | OS.delay_msec(2000) | |
| 54 | ||
| 55 | print("Started gateway at " + str(processPID)) | |
| 56 | emit_signal("started_gateway", processPID) | |
| 57 | pass | |
| 58 | ||
| 59 | func ensureSetup(): | |
| 60 | if processPID != 0: return | |
| 61 | setupGateway() | |
| 62 | pass | |
| 63 | ||
| 64 | func getExecutiblePath(): | |
| 65 | var name = OS.get_name() | |
| 66 | if name == 'X11': return "res://hyper-gateway/hyper-gateway-linux" | |
| 67 | if name == 'OSX': return "res://hyper-gateway/hyper-gateway-macos" | |
| 68 | if name == 'Windows': return "res://hyper-gateway/hyper-gateway-windows.exe" | |
| 69 | push_error("Can not start gateway, invalid operating system " + name) | |
| 70 | pass | |
| 71 | ||
| 72 | func defaultDirectory(): | |
| 73 | var dir = Directory.new() | |
| 74 | dir.open('user://gateway-data/') | |
| 75 | return dir.get_current_dir() | |
| 76 | pass |
| … | … | @@ -0,0 +1,6 @@ |
| 1 | [gd_scene load_steps=2 format=2] | |
| 2 | ||
| 3 | [ext_resource path="res://src/HyperGateway/HyperGateway.gd" type="Script" id=1] | |
| 4 | ||
| 5 | [node name="HyperGateway" type="Node"] | |
| 6 | script = ExtResource( 1 ) |
| … | … | @@ -1,83 +0,0 @@ |
| 1 | [gd_scene load_steps=6 format=2] | |
| 2 | ||
| 3 | [ext_resource path="res://src/URLBar.gd" type="Script" id=1] | |
| 4 | [ext_resource path="res://src/HyperRequest.gd" type="Script" id=2] | |
| 5 | [ext_resource path="res://src/StatusLabel.gd" type="Script" id=3] | |
| 6 | [ext_resource path="res://src/Output.gd" type="Script" id=4] | |
| 7 | [ext_resource path="res://src/ResizeRoot.gd" type="Script" id=5] | |
| 8 | ||
| 9 | [node name="Control" type="VBoxContainer"] | |
| 10 | script = ExtResource( 5 ) | |
| 11 | __meta__ = { | |
| 12 | "_edit_use_anchors_": false | |
| 13 | } | |
| 14 | ||
| 15 | [node name="Title" type="Label" parent="."] | |
| 16 | margin_right = 280.0 | |
| 17 | margin_bottom = 14.0 | |
| 18 | size_flags_horizontal = 4 | |
| 19 | text = "Enter your `hyper://` URL and press `Load`" | |
| 20 | align = 1 | |
| 21 | __meta__ = { | |
| 22 | "_edit_use_anchors_": false | |
| 23 | } | |
| 24 | ||
| 25 | [node name="HBoxContainer" type="HBoxContainer" parent="."] | |
| 26 | margin_top = 18.0 | |
| 27 | margin_right = 280.0 | |
| 28 | margin_bottom = 42.0 | |
| 29 | alignment = 1 | |
| 30 | ||
| 31 | [node name="URLBar" type="LineEdit" parent="HBoxContainer"] | |
| 32 | margin_right = 234.0 | |
| 33 | margin_bottom = 24.0 | |
| 34 | size_flags_horizontal = 3 | |
| 35 | text = "hyper://blog.mauve.moe/" | |
| 36 | caret_blink = true | |
| 37 | caret_blink_speed = 0.5 | |
| 38 | script = ExtResource( 1 ) | |
| 39 | __meta__ = { | |
| 40 | "_edit_use_anchors_": false | |
| 41 | } | |
| 42 | ||
| 43 | [node name="LoadButton" type="Button" parent="HBoxContainer"] | |
| 44 | margin_left = 238.0 | |
| 45 | margin_right = 280.0 | |
| 46 | margin_bottom = 24.0 | |
| 47 | text = "Load" | |
| 48 | __meta__ = { | |
| 49 | "_edit_use_anchors_": false | |
| 50 | } | |
| 51 | ||
| 52 | [node name="ScrollContainer" type="ScrollContainer" parent="."] | |
| 53 | margin_top = 46.0 | |
| 54 | margin_right = 280.0 | |
| 55 | margin_bottom = 58.0 | |
| 56 | size_flags_vertical = 3 | |
| 57 | scroll_horizontal_enabled = false | |
| 58 | ||
| 59 | [node name="Output" type="RichTextLabel" parent="ScrollContainer"] | |
| 60 | margin_right = 280.0 | |
| 61 | margin_bottom = 12.0 | |
| 62 | size_flags_horizontal = 3 | |
| 63 | size_flags_vertical = 3 | |
| 64 | script = ExtResource( 4 ) | |
| 65 | ||
| 66 | [node name="StatusLabel" type="Label" parent="."] | |
| 67 | margin_top = 62.0 | |
| 68 | margin_right = 280.0 | |
| 69 | margin_bottom = 76.0 | |
| 70 | text = "Status: Waiting" | |
| 71 | script = ExtResource( 3 ) | |
| 72 | __meta__ = { | |
| 73 | "_edit_use_anchors_": false | |
| 74 | } | |
| 75 | ||
| 76 | [node name="HyperLoad" type="HTTPRequest" parent="."] | |
| 77 | script = ExtResource( 2 ) | |
| 78 | ||
| 79 | [connection signal="text_entered" from="HBoxContainer/URLBar" to="HBoxContainer/URLBar" method="_on_URLBar_text_entered"] | |
| 80 | [connection signal="url" from="HBoxContainer/URLBar" to="HyperLoad" method="request"] | |
| 81 | [connection signal="pressed" from="HBoxContainer/LoadButton" to="HBoxContainer/URLBar" method="navigate"] | |
| 82 | [connection signal="request_completed" from="HyperLoad" to="StatusLabel" method="_on_HyperLoad_request_completed"] | |
| 83 | [connection signal="request_completed" from="HyperLoad" to="ScrollContainer/Output" method="_on_HyperLoad_request_completed"] |
| … | … | @@ -0,0 +1,92 @@ |
| 1 | [gd_scene load_steps=7 format=2] | |
| 2 | ||
| 3 | [ext_resource path="res://src/HyperLoad/URLBar.gd" type="Script" id=1] | |
| 4 | [ext_resource path="res://src/HyperRequest/HyperRequest.tscn" type="PackedScene" id=2] | |
| 5 | [ext_resource path="res://src/HyperLoad/StatusLabel.gd" type="Script" id=3] | |
| 6 | [ext_resource path="res://src/HyperLoad/Output.gd" type="Script" id=4] | |
| 7 | [ext_resource path="res://src/ResizeRoot.gd" type="Script" id=5] | |
| 8 | [ext_resource path="res://src/HyperGateway/HyperGateway.tscn" type="PackedScene" id=6] | |
| 9 | ||
| 10 | [node name="Control" type="VBoxContainer"] | |
| 11 | margin_right = 666.0 | |
| 12 | margin_bottom = 666.0 | |
| 13 | script = ExtResource( 5 ) | |
| 14 | __meta__ = { | |
| 15 | "_edit_use_anchors_": false | |
| 16 | } | |
| 17 | ||
| 18 | [node name="Title" type="Label" parent="."] | |
| 19 | margin_left = 193.0 | |
| 20 | margin_right = 473.0 | |
| 21 | margin_bottom = 14.0 | |
| 22 | size_flags_horizontal = 4 | |
| 23 | text = "Enter your `hyper://` URL and press `Load`" | |
| 24 | align = 1 | |
| 25 | __meta__ = { | |
| 26 | "_edit_use_anchors_": false | |
| 27 | } | |
| 28 | ||
| 29 | [node name="HBoxContainer" type="HBoxContainer" parent="."] | |
| 30 | margin_top = 18.0 | |
| 31 | margin_right = 666.0 | |
| 32 | margin_bottom = 42.0 | |
| 33 | alignment = 1 | |
| 34 | ||
| 35 | [node name="URLBar" type="LineEdit" parent="HBoxContainer"] | |
| 36 | margin_right = 620.0 | |
| 37 | margin_bottom = 24.0 | |
| 38 | size_flags_horizontal = 3 | |
| 39 | text = "hyper://blog.mauve.moe/" | |
| 40 | caret_blink = true | |
| 41 | caret_blink_speed = 0.5 | |
| 42 | script = ExtResource( 1 ) | |
| 43 | __meta__ = { | |
| 44 | "_edit_use_anchors_": false | |
| 45 | } | |
| 46 | ||
| 47 | [node name="LoadButton" type="Button" parent="HBoxContainer"] | |
| 48 | margin_left = 624.0 | |
| 49 | margin_right = 666.0 | |
| 50 | margin_bottom = 24.0 | |
| 51 | text = "Load" | |
| 52 | __meta__ = { | |
| 53 | "_edit_use_anchors_": false | |
| 54 | } | |
| 55 | ||
| 56 | [node name="ScrollContainer" type="ScrollContainer" parent="."] | |
| 57 | margin_top = 46.0 | |
| 58 | margin_right = 666.0 | |
| 59 | margin_bottom = 648.0 | |
| 60 | size_flags_vertical = 3 | |
| 61 | scroll_horizontal_enabled = false | |
| 62 | ||
| 63 | [node name="Output" type="RichTextLabel" parent="ScrollContainer"] | |
| 64 | margin_right = 666.0 | |
| 65 | margin_bottom = 602.0 | |
| 66 | size_flags_horizontal = 3 | |
| 67 | size_flags_vertical = 3 | |
| 68 | script = ExtResource( 4 ) | |
| 69 | ||
| 70 | [node name="StatusLabel" type="Label" parent="."] | |
| 71 | margin_top = 652.0 | |
| 72 | margin_right = 666.0 | |
| 73 | margin_bottom = 666.0 | |
| 74 | text = "Status: Waiting" | |
| 75 | script = ExtResource( 3 ) | |
| 76 | __meta__ = { | |
| 77 | "_edit_use_anchors_": false | |
| 78 | } | |
| 79 | ||
| 80 | [node name="HyperGateway" parent="." instance=ExtResource( 6 )] | |
| 81 | autoStart = true | |
| 82 | ||
| 83 | [node name="HyperRequest" parent="HyperGateway" instance=ExtResource( 2 )] | |
| 84 | ||
| 85 | [connection signal="text_entered" from="HBoxContainer/URLBar" to="HBoxContainer/URLBar" method="_on_URLBar_text_entered"] | |
| 86 | [connection signal="url" from="HBoxContainer/URLBar" to="HyperGateway/HyperRequest" method="request"] | |
| 87 | [connection signal="pressed" from="HBoxContainer/LoadButton" to="HBoxContainer/URLBar" method="navigate"] | |
| 88 | [connection signal="started_gateway" from="HyperGateway" to="StatusLabel" method="setGatewayLoaded"] | |
| 89 | [connection signal="starting_gateway" from="HyperGateway" to="StatusLabel" method="setGatewayLoading"] | |
| 90 | [connection signal="loading_data" from="HyperGateway/HyperRequest" to="StatusLabel" method="setLoading"] | |
| 91 | [connection signal="request_completed" from="HyperGateway/HyperRequest" to="ScrollContainer/Output" method="_on_HyperLoad_request_completed"] | |
| 92 | [connection signal="request_completed" from="HyperGateway/HyperRequest" to="StatusLabel" method="_on_HyperLoad_request_completed"] |
| … | … | @@ -0,0 +1,5 @@ |
| 1 | extends RichTextLabel | |
| 2 | ||
| 3 | func _on_HyperLoad_request_completed(result, response_code, headers, body): | |
| 4 | text = body.get_string_from_utf8() | |
| 5 | pass # Replace with function body. |
| … | … | @@ -0,0 +1,48 @@ |
| 1 | extends Label | |
| 2 | ||
| 3 | ||
| 4 | # Declare member variables here. Examples: | |
| 5 | # var a = 2 | |
| 6 | # var b = "text" | |
| 7 | ||
| 8 | ||
| 9 | # Called when the node enters the scene tree for the first time. | |
| 10 | func _ready(): | |
| 11 | pass # Replace with function body. | |
| 12 | ||
| 13 | # Called every frame. 'delta' is the elapsed time since the previous frame. | |
| 14 | #func _process(delta): | |
| 15 | # pass | |
| 16 | ||
| 17 | func setLoaded(): | |
| 18 | text = "Status: Loaded" | |
| 19 | pass # Replace with function body. | |
| 20 | ||
| 21 | func setLoading(url): | |
| 22 | text = "Status: Loading " + url | |
| 23 | pass # Replace with function body. | |
| 24 | ||
| 25 | ||
| 26 | func setError(error): | |
| 27 | text = "Status: Failed Load" + error | |
| 28 | pass # Replace with function body. | |
| 29 | ||
| 30 | ||
| 31 | func setGatewayLoading(): | |
| 32 | text = "Status: Starting Gateway" | |
| 33 | pass # Replace with function body. | |
| 34 | ||
| 35 | ||
| 36 | func setGatewayLoaded(pid): | |
| 37 | text = "Status: Gateway Loaded" | |
| 38 | pass # Replace with function body. | |
| 39 | ||
| 40 | ||
| 41 | func _on_HyperLoad_request_completed(result, response_code, headers, body): | |
| 42 | print("Response Code ", response_code) | |
| 43 | if response_code != 200: | |
| 44 | var message = body.get_string_from_utf8() | |
| 45 | print("Error message:", message) | |
| 46 | setError(message) | |
| 47 | else: setLoaded() | |
| 48 | pass # Replace with function body. |
| … | … | @@ -0,0 +1,29 @@ |
| 1 | extends LineEdit | |
| 2 | ||
| 3 | signal url(url) | |
| 4 | ||
| 5 | # Declare member variables here. Examples: | |
| 6 | # var a = 2 | |
| 7 | # var b = "text" | |
| 8 | ||
| 9 | ||
| 10 | # Called when the node enters the scene tree for the first time. | |
| 11 | func _ready(): | |
| 12 | pass # Replace with function body. | |
| 13 | ||
| 14 | ||
| 15 | # Called every frame. 'delta' is the elapsed time since the previous frame. | |
| 16 | #func _process(delta): | |
| 17 | # pass | |
| 18 | ||
| 19 | ||
| 20 | func navigate(): | |
| 21 | var url = text | |
| 22 | if url.begins_with("hyper://"): | |
| 23 | emit_signal("url", url) | |
| 24 | pass # Replace with function body. | |
| 25 | ||
| 26 | ||
| 27 | func _on_URLBar_text_entered(new_text): | |
| 28 | navigate() | |
| 29 | pass # Replace with function body. |
| … | … | @@ -0,0 +1,2 @@ |
| 1 | extends Tree | |
| 2 |
| … | … | @@ -0,0 +1,14 @@ |
| 1 | extends "res://src/HyperRequest/HyperRequest.gd" | |
| 2 | ||
| 3 | signal content(content) | |
| 4 | ||
| 5 | func getContent(path): | |
| 6 | request(path) | |
| 7 | pass | |
| 8 | ||
| 9 | func _on_GetContent_request_completed(result, response_code, headers, body): | |
| 10 | var content = body.get_string_from_utf8() | |
| 11 | ||
| 12 | if response_code != 200: return printerr(content) | |
| 13 | emit_signal("content", content) | |
| 14 | pass # Replace with function body. |
| … | … | @@ -0,0 +1,49 @@ |
| 1 | extends "res://src/ResizeRoot.gd" | |
| 2 | ||
| 3 | onready var fileContent = $HBoxContainer/VBoxContainer/FileContent | |
| 4 | onready var saver = $HyperGateway/SaveContent | |
| 5 | onready var loader = $HyperGateway/GetContent | |
| 6 | onready var filePathInput = $HBoxContainer/VBoxContainer/HBoxContainer/FilePathInput | |
| 7 | onready var fileLister = $HyperGateway/ListFiles | |
| 8 | onready var fileTree = $HBoxContainer/Files | |
| 9 | ||
| 10 | func _on_SaveButton_pressed(): | |
| 11 | saver.save(filePathInput.text, fileContent.text) | |
| 12 | pass | |
| 13 | ||
| 14 | func _on_LoadButton_pressed(): | |
| 15 | loader.getContent(filePathInput.text) | |
| 16 | pass # Replace with function body. | |
| 17 | ||
| 18 | func _on_GetContent_content(content): | |
| 19 | fileContent.text = content | |
| 20 | pass # Replace with function body. | |
| 21 | ||
| 22 | func _on_SaveContent_saved(): | |
| 23 | fileLister.list() | |
| 24 | pass # Replace with function body. | |
| 25 | ||
| 26 | func _on_ListFiles_files(files): | |
| 27 | fileTree.clear() | |
| 28 | if files.size() == 0: | |
| 29 | var root = fileTree.create_item() | |
| 30 | root.set_text(0, "No Files Found") | |
| 31 | return | |
| 32 | ||
| 33 | var root = fileTree.create_item() | |
| 34 | root.set_text(0, "hyper://notes/") | |
| 35 | for file in files: | |
| 36 | var child = fileTree.create_item(root) | |
| 37 | child.set_text(0, file) | |
| 38 | pass | |
| 39 | ||
| 40 | func _on_Files_item_selected(): | |
| 41 | var item = fileTree.get_selected() | |
| 42 | var text = item.get_text(0) | |
| 43 | var path = 'hyper://notes/' + text | |
| 44 | ||
| 45 | print('Loading', path) | |
| 46 | ||
| 47 | filePathInput.text = path | |
| 48 | loader.getContent(path) | |
| 49 | pass # Replace with function body. |
| … | … | @@ -0,0 +1,88 @@ |
| 1 | [gd_scene load_steps=7 format=2] | |
| 2 | ||
| 3 | [ext_resource path="res://src/HyperNotes/HyperNotes.gd" type="Script" id=1] | |
| 4 | [ext_resource path="res://src/HyperRequest/HyperRequest.tscn" type="PackedScene" id=3] | |
| 5 | [ext_resource path="res://src/HyperNotes/ListFiles.gd" type="Script" id=4] | |
| 6 | [ext_resource path="res://src/HyperGateway/HyperGateway.tscn" type="PackedScene" id=5] | |
| 7 | [ext_resource path="res://src/HyperNotes/GetContent.gd" type="Script" id=6] | |
| 8 | [ext_resource path="res://src/HyperNotes/SaveContent.gd" type="Script" id=8] | |
| 9 | ||
| 10 | [node name="Control" type="VBoxContainer"] | |
| 11 | anchor_right = 1.0 | |
| 12 | anchor_bottom = 1.0 | |
| 13 | script = ExtResource( 1 ) | |
| 14 | __meta__ = { | |
| 15 | "_edit_use_anchors_": false | |
| 16 | } | |
| 17 | ||
| 18 | [node name="StatusLabel" type="Label" parent="."] | |
| 19 | margin_right = 666.0 | |
| 20 | margin_bottom = 14.0 | |
| 21 | text = "Choose a file to edit, or enter a file name." | |
| 22 | ||
| 23 | [node name="HBoxContainer" type="HBoxContainer" parent="."] | |
| 24 | margin_top = 18.0 | |
| 25 | margin_right = 666.0 | |
| 26 | margin_bottom = 666.0 | |
| 27 | size_flags_horizontal = 3 | |
| 28 | size_flags_vertical = 3 | |
| 29 | ||
| 30 | [node name="Files" type="Tree" parent="HBoxContainer"] | |
| 31 | margin_right = 222.0 | |
| 32 | margin_bottom = 648.0 | |
| 33 | rect_min_size = Vector2( 222, 0 ) | |
| 34 | ||
| 35 | [node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] | |
| 36 | margin_left = 226.0 | |
| 37 | margin_right = 666.0 | |
| 38 | margin_bottom = 648.0 | |
| 39 | size_flags_horizontal = 3 | |
| 40 | ||
| 41 | [node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer/VBoxContainer"] | |
| 42 | margin_right = 440.0 | |
| 43 | margin_bottom = 24.0 | |
| 44 | ||
| 45 | [node name="FilePathInput" type="LineEdit" parent="HBoxContainer/VBoxContainer/HBoxContainer"] | |
| 46 | margin_right = 349.0 | |
| 47 | margin_bottom = 24.0 | |
| 48 | size_flags_horizontal = 3 | |
| 49 | text = "hyper://notes/note.txt" | |
| 50 | ||
| 51 | [node name="SaveButton" type="Button" parent="HBoxContainer/VBoxContainer/HBoxContainer"] | |
| 52 | margin_left = 353.0 | |
| 53 | margin_right = 394.0 | |
| 54 | margin_bottom = 24.0 | |
| 55 | text = "Save" | |
| 56 | ||
| 57 | [node name="LoadButton" type="Button" parent="HBoxContainer/VBoxContainer/HBoxContainer"] | |
| 58 | margin_left = 398.0 | |
| 59 | margin_right = 440.0 | |
| 60 | margin_bottom = 24.0 | |
| 61 | text = "Load" | |
| 62 | ||
| 63 | [node name="FileContent" type="TextEdit" parent="HBoxContainer/VBoxContainer"] | |
| 64 | margin_top = 28.0 | |
| 65 | margin_right = 440.0 | |
| 66 | margin_bottom = 648.0 | |
| 67 | size_flags_vertical = 3 | |
| 68 | ||
| 69 | [node name="HyperGateway" parent="." instance=ExtResource( 5 )] | |
| 70 | ||
| 71 | [node name="ListFiles" parent="HyperGateway" instance=ExtResource( 3 )] | |
| 72 | script = ExtResource( 4 ) | |
| 73 | ||
| 74 | [node name="GetContent" parent="HyperGateway" instance=ExtResource( 3 )] | |
| 75 | script = ExtResource( 6 ) | |
| 76 | ||
| 77 | [node name="SaveContent" parent="HyperGateway" instance=ExtResource( 3 )] | |
| 78 | script = ExtResource( 8 ) | |
| 79 | ||
| 80 | [connection signal="item_selected" from="HBoxContainer/Files" to="." method="_on_Files_item_selected"] | |
| 81 | [connection signal="pressed" from="HBoxContainer/VBoxContainer/HBoxContainer/SaveButton" to="." method="_on_SaveButton_pressed"] | |
| 82 | [connection signal="pressed" from="HBoxContainer/VBoxContainer/HBoxContainer/LoadButton" to="." method="_on_LoadButton_pressed"] | |
| 83 | [connection signal="files" from="HyperGateway/ListFiles" to="." method="_on_ListFiles_files"] | |
| 84 | [connection signal="request_completed" from="HyperGateway/ListFiles" to="HyperGateway/ListFiles" method="_on_ListFiles_request_completed"] | |
| 85 | [connection signal="content" from="HyperGateway/GetContent" to="." method="_on_GetContent_content"] | |
| 86 | [connection signal="request_completed" from="HyperGateway/GetContent" to="HyperGateway/GetContent" method="_on_GetContent_request_completed"] | |
| 87 | [connection signal="request_completed" from="HyperGateway/SaveContent" to="HyperGateway/SaveContent" method="_on_SaveContent_request_completed"] | |
| 88 | [connection signal="saved" from="HyperGateway/SaveContent" to="." method="_on_SaveContent_saved"] |
| … | … | @@ -0,0 +1,31 @@ |
| 1 | extends "res://src/HyperRequest/HyperRequest.gd" | |
| 2 | ||
| 3 | signal files(files) | |
| 4 | ||
| 5 | export var folder = 'hyper://notes/' | |
| 6 | ||
| 7 | func _ready(): | |
| 8 | list() | |
| 9 | pass # Replace with function body. | |
| 10 | ||
| 11 | func list(path=folder): | |
| 12 | request(path + "?noResolve") | |
| 13 | pass | |
| 14 | ||
| 15 | func _on_ListFiles_request_completed(result, response_code, headers, body): | |
| 16 | print('Loaded', response_code) | |
| 17 | ||
| 18 | if response_code != 200: return | |
| 19 | ||
| 20 | var content = body.get_string_from_utf8() | |
| 21 | ||
| 22 | print("Loaded directory listing", content) | |
| 23 | ||
| 24 | var json = JSON.parse(content) | |
| 25 | ||
| 26 | print("Loaded JSON", json) | |
| 27 | ||
| 28 | if json.error != OK: return printerr(json.error_string) | |
| 29 | ||
| 30 | emit_signal("files", json.result) | |
| 31 | pass # Replace with function body. |
| … | … | @@ -0,0 +1,20 @@ |
| 1 | extends "res://src/HyperRequest/HyperRequest.gd" | |
| 2 | ||
| 3 | signal saved | |
| 4 | ||
| 5 | func save(path, content): | |
| 6 | print("Saving", path, content) | |
| 7 | self.request( | |
| 8 | path, | |
| 9 | PoolStringArray(["Content-Type: text/plain"]), | |
| 10 | false, | |
| 11 | HTTPClient.METHOD_PUT, | |
| 12 | content | |
| 13 | ) | |
| 14 | pass | |
| 15 | ||
| 16 | ||
| 17 | func _on_SaveContent_request_completed(result, response_code, headers, body): | |
| 18 | if response_code == 200: emit_signal("saved") | |
| 19 | else: printerr(body.get_string_from_utf8()) | |
| 20 | pass # Replace with function body. |
| … | … | @@ -1,83 +0,0 @@ |
| 1 | extends HTTPRequest | |
| 2 | ||
| 3 | signal loaded_data(data) | |
| 4 | signal loading_data(url) | |
| 5 | signal failed_load(url, error) | |
| 6 | signal starting_gateway() | |
| 7 | signal started_gateway(pid) | |
| 8 | ||
| 9 | var processPID = 0 | |
| 10 | var storageDirectory = defaultDirectory() | |
| 11 | var serverPrefix = "http://127.0.0.1:4973/hyper/" | |
| 12 | ||
| 13 | # Called when the node enters the scene tree for the first time. | |
| 14 | func _ready(): | |
| 15 | pass # Replace with function body. | |
| 16 | ||
| 17 | func _notification(what): | |
| 18 | if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST: | |
| 19 | cleanupGateway() | |
| 20 | pass | |
| 21 | ||
| 22 | func cleanupGateway(): | |
| 23 | if processPID == 0: | |
| 24 | print('Gateway already closed ' + str(processPID)) | |
| 25 | return | |
| 26 | print('Cleaning up gateway ' + str(processPID)) | |
| 27 | OS.kill(processPID) | |
| 28 | pass | |
| 29 | ||
| 30 | func setupGateway(): | |
| 31 | emit_signal("starting_gateway") | |
| 32 | var executiblePath = getExecutiblePath() | |
| 33 | var executibleFile = File.new() | |
| 34 | ||
| 35 | executibleFile.open(executiblePath, File.READ) | |
| 36 | ||
| 37 | var path = executibleFile.get_path_absolute() | |
| 38 | executibleFile.close() | |
| 39 | ||
| 40 | var args = ["run", "--no-persist"] | |
| 41 | ||
| 42 | print("Starting gateway from " + path) | |
| 43 | ||
| 44 | # Start the hyper-gateway in a process | |
| 45 | processPID = OS.execute(path, args, false) | |
| 46 | ||
| 47 | # Sleep for a bit while the gateway loads | |
| 48 | # TODO: Find a better indicator like polling the HTTP server socket | |
| 49 | OS.delay_msec(2000) | |
| 50 | ||
| 51 | print("Started gateway at " + str(processPID)) | |
| 52 | emit_signal("started_gateway", processPID) | |
| 53 | pass | |
| 54 | ||
| 55 | func ensureSetup(): | |
| 56 | if processPID != 0: return | |
| 57 | setupGateway() | |
| 58 | pass | |
| 59 | ||
| 60 | func getExecutiblePath(): | |
| 61 | var name = OS.get_name() | |
| 62 | if name == 'X11': return "res://hyper-gateway/hyper-gateway-linux" | |
| 63 | if name == 'OSX': return "res://hyper-gateway/hyper-gateway-macos" | |
| 64 | if name == 'Windows': return "res://hyper-gateway/hyper-gateway-windows.exe" | |
| 65 | push_error("Can not start gateway, invalid operating system " + name) | |
| 66 | pass | |
| 67 | ||
| 68 | func defaultDirectory(): | |
| 69 | var dir = Directory.new() | |
| 70 | dir.open('user://gateway-data/') | |
| 71 | return dir.get_current_dir() | |
| 72 | pass | |
| 73 | ||
| 74 | # Called every frame. 'delta' is the elapsed time since the previous frame. | |
| 75 | #func _process(delta): | |
| 76 | # pass | |
| 77 | ||
| 78 | func request(url, custom_headers=PoolStringArray( ), ssl_validate_domain=false, method=0, request_data=""): | |
| 79 | assert(url.begins_with("hyper://")) | |
| 80 | ensureSetup() | |
| 81 | var toLoad = url.replace("hyper://", serverPrefix) | |
| 82 | .request(toLoad, custom_headers, ssl_validate_domain, method, request_data) | |
| 83 | pass |
| … | … | @@ -0,0 +1,17 @@ |
| 1 | extends HTTPRequest | |
| 2 | ||
| 3 | signal loading_data(url) | |
| 4 | ||
| 5 | export var serverPrefix = "http://127.0.0.1:4973/hyper/" | |
| 6 | ||
| 7 | func request( | |
| 8 | url, | |
| 9 | custom_headers=PoolStringArray( ), | |
| 10 | ssl_validate_domain=false, | |
| 11 | method=HTTPClient.METHOD_GET, request_data="" | |
| 12 | ): | |
| 13 | assert(url.begins_with("hyper://")) | |
| 14 | var toLoad = url.replace("hyper://", serverPrefix) | |
| 15 | emit_signal('loading_data', url) | |
| 16 | .request(toLoad, custom_headers, ssl_validate_domain, method, request_data) | |
| 17 | pass |
| … | … | @@ -0,0 +1,6 @@ |
| 1 | [gd_scene load_steps=2 format=2] | |
| 2 | ||
| 3 | [ext_resource path="res://src/HyperRequest/HyperRequest.gd" type="Script" id=1] | |
| 4 | ||
| 5 | [node name="HyperRequest" type="HTTPRequest"] | |
| 6 | script = ExtResource( 1 ) |
| … | … | @@ -1,5 +0,0 @@ |
| 1 | extends RichTextLabel | |
| 2 | ||
| 3 | func _on_HyperLoad_request_completed(result, response_code, headers, body): | |
| 4 | text = body.get_string_from_utf8() | |
| 5 | pass # Replace with function body. |
| … | … | @@ -1,11 +1,5 @@ |
| 1 | 1 | extends VBoxContainer |
| 2 | 2 | |
| 3 | ||
| 4 | # Declare member variables here. Examples: | |
| 5 | # var a = 2 | |
| 6 | # var b = "text" | |
| 7 | ||
| 8 | ||
| 9 | 3 | # Called when the node enters the scene tree for the first time. |
| 10 | 4 | func _ready(): |
| 11 | 5 | get_tree().get_root().connect("size_changed", self, "fitParent") |
| … | … | @@ -18,6 +12,3 @@ func fitParent(): |
| 18 | 12 | print(rootSize) |
| 19 | 13 | self.set_size(rootSize) |
| 20 | 14 | pass |
| 21 | # Called every frame. 'delta' is the elapsed time since the previous frame. | |
| 22 | #func _process(delta): | |
| 23 | # pass |
| … | … | @@ -1,48 +0,0 @@ |
| 1 | extends Label | |
| 2 | ||
| 3 | ||
| 4 | # Declare member variables here. Examples: | |
| 5 | # var a = 2 | |
| 6 | # var b = "text" | |
| 7 | ||
| 8 | ||
| 9 | # Called when the node enters the scene tree for the first time. | |
| 10 | func _ready(): | |
| 11 | pass # Replace with function body. | |
| 12 | ||
| 13 | # Called every frame. 'delta' is the elapsed time since the previous frame. | |
| 14 | #func _process(delta): | |
| 15 | # pass | |
| 16 | ||
| 17 | func setLoaded(): | |
| 18 | text = "Status: Loaded" | |
| 19 | pass # Replace with function body. | |
| 20 | ||
| 21 | func setLoading(url): | |
| 22 | text = "Status: Loading " + url | |
| 23 | pass # Replace with function body. | |
| 24 | ||
| 25 | ||
| 26 | func setError(error): | |
| 27 | text = "Status: Failed Load" + error | |
| 28 | pass # Replace with function body. | |
| 29 | ||
| 30 | ||
| 31 | func setGatewayLoading(): | |
| 32 | text = "Status: Starting Gateway" | |
| 33 | pass # Replace with function body. | |
| 34 | ||
| 35 | ||
| 36 | func setGatewayLoaded(pid): | |
| 37 | text = "Status: Gateway Loaded" | |
| 38 | pass # Replace with function body. | |
| 39 | ||
| 40 | ||
| 41 | func _on_HyperLoad_request_completed(result, response_code, headers, body): | |
| 42 | print("Response Code ", response_code) | |
| 43 | if response_code != 200: | |
| 44 | var message = body.get_string_from_utf8() | |
| 45 | print("Error message:", message) | |
| 46 | setError(message) | |
| 47 | else: setLoaded() | |
| 48 | pass # Replace with function body. |
| … | … | @@ -1,29 +0,0 @@ |
| 1 | extends LineEdit | |
| 2 | ||
| 3 | signal url(url) | |
| 4 | ||
| 5 | # Declare member variables here. Examples: | |
| 6 | # var a = 2 | |
| 7 | # var b = "text" | |
| 8 | ||
| 9 | ||
| 10 | # Called when the node enters the scene tree for the first time. | |
| 11 | func _ready(): | |
| 12 | pass # Replace with function body. | |
| 13 | ||
| 14 | ||
| 15 | # Called every frame. 'delta' is the elapsed time since the previous frame. | |
| 16 | #func _process(delta): | |
| 17 | # pass | |
| 18 | ||
| 19 | ||
| 20 | func navigate(): | |
| 21 | var url = text | |
| 22 | if url.begins_with("hyper://"): | |
| 23 | emit_signal("url", url) | |
| 24 | pass # Replace with function body. | |
| 25 | ||
| 26 | ||
| 27 | func _on_URLBar_text_entered(new_text): | |
| 28 | navigate() | |
| 29 | pass # Replace with function body. |