Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sdk7 to sdk6 adaption layer #36

Merged
merged 7 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions godot/assets/sdk7-adaption-layer/index.js

Large diffs are not rendered by default.

38 changes: 22 additions & 16 deletions godot/src/logic/parcel_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -197,26 +197,32 @@ func load_scene(scene_entity_id: String, entity: Dictionary):
loaded_scenes[scene_entity_id] = {
"id": scene_entity_id, "entity": entity, "scene_number_id": -1
}
var metadata = entity.get("metadata", {})

var main_js_file_hash = entity.get("content", {}).get(
entity.get("metadata", {}).get("main", ""), null
)
if main_js_file_hash == null:
printerr("Scene ", scene_entity_id, " fail getting the main js file hash.")
return false

var is_sdk7 = metadata.get("runtimeVersion", null) == "7"
var main_js_request_id := -1
var local_main_js_path = "user://content/" + main_js_file_hash
var local_main_js_path = ""
var js_request_completed = true

if not FileAccess.file_exists(local_main_js_path) or main_js_file_hash.begins_with("b64"):
js_request_completed = false
var main_js_file_url: String = entity.baseUrl + main_js_file_hash
main_js_request_id = http_requester._requester.request_file(
MAIN_JS_FILE_REQUEST,
main_js_file_url,
local_main_js_path.replace("user:/", OS.get_user_data_dir())
)
print("is_sdk7 ", is_sdk7)
if is_sdk7:
var main_js_file_hash = entity.get("content", {}).get(metadata.get("main", ""), null)
if main_js_file_hash == null:
printerr("Scene ", scene_entity_id, " fail getting the main js file hash.")
return false

local_main_js_path = "user://content/" + main_js_file_hash

if not FileAccess.file_exists(local_main_js_path) or main_js_file_hash.begins_with("b64"):
js_request_completed = false
var main_js_file_url: String = entity.baseUrl + main_js_file_hash
main_js_request_id = http_requester._requester.request_file(
MAIN_JS_FILE_REQUEST,
main_js_file_url,
local_main_js_path.replace("user:/", OS.get_user_data_dir())
)
else:
local_main_js_path = "res://assets/sdk7-adaption-layer/index.js"

var req = {
"js_request_completed": js_request_completed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ layout_mode = 2
size_flags_horizontal = 3
tooltip_text = "Select scene to load"
focus_mode = 0
item_count = 6
item_count = 7
popup/item_0/text = "mannakia.dcl.eth"
popup/item_0/id = 0
popup/item_1/text = "http://127.0.0.1:8000"
Expand All @@ -110,6 +110,8 @@ popup/item_4/text = "https://peer-testing.decentraland.org"
popup/item_4/id = 4
popup/item_5/text = "https://sdk-team-cdn.decentraland.org/ipfs/streaming-world-main"
popup/item_5/id = 5
popup/item_6/text = "https://peer.decentraland.org"
popup/item_6/id = 6

[node name="HSeparator4" type="HSeparator" parent="VBoxContainer/ColorRect_Background/HBoxContainer/VBoxContainer_General"]
layout_mode = 2
Expand Down
4 changes: 3 additions & 1 deletion godot/src/ui/components/depr_panel_bottom_left.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ offset_right = 573.0
offset_bottom = 49.0
tooltip_text = "Select scene to load"
focus_mode = 0
item_count = 6
item_count = 7
popup/item_0/text = "mannakia.dcl.eth"
popup/item_0/id = 0
popup/item_1/text = "http://127.0.0.1:8000"
Expand All @@ -59,6 +59,8 @@ popup/item_4/text = "https://peer-testing.decentraland.org"
popup/item_4/id = 4
popup/item_5/text = "https://sdk-team-cdn.decentraland.org/ipfs/streaming-world-main"
popup/item_5/id = 5
popup/item_6/text = "https://peer.decentraland.org"
popup/item_6/id = 6

[node name="HSlider_SceneRadius" type="HSlider" parent="HFlowContainer/Panel_Realm"]
layout_mode = 0
Expand Down
17 changes: 16 additions & 1 deletion rust/decentraland-godot-lib/src/dcl/js/js_modules/Runtime.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
module.exports.getRealm = async function (body) { return {} }
module.exports.getWorldTime = async function (body) { return {} }
module.exports.readFile = async function (body) { return {} }

// sync implementation
module.exports.readFile = async function (body) {
// body.fileName

const fileBody = op_read_file(body.fileName);
if (!fileBody) {
throw new Error("File not found")
}

const response = {
content: fileBody,
hash: "string"
}
return response
}
module.exports.getSceneInformation = async function (body) { return {} }
14 changes: 12 additions & 2 deletions rust/decentraland-godot-lib/src/dcl/js/js_runtime.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use super::engine::{op_crdt_recv_from_renderer, op_crdt_send_to_renderer};
use super::{
engine::{op_crdt_recv_from_renderer, op_crdt_send_to_renderer},
runtime_mod::op_read_file,
};
use crate::dcl::{RendererResponse, SceneId, SceneResponse, SharedSceneCrdtState};
use std::{cell::RefCell, rc::Rc, time::Duration};
use std::{cell::RefCell, collections::HashMap, rc::Rc, time::Duration};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum SceneLogLevel {
Expand Down Expand Up @@ -33,6 +36,8 @@ pub struct JsRuntimeState {
pub main_code: String,
pub logs: Vec<SceneLogMessage>,
pub dying: bool,
pub content_mapping: HashMap<String, String>,
pub base_url: String,
}

pub fn init_v8() {
Expand Down Expand Up @@ -187,6 +192,11 @@ impl JsRuntime {
v8::FunctionTemplate::new(&mut scope, op_crdt_send_to_renderer).into(),
);

global.set(
v8::String::new(&mut scope, "op_read_file").unwrap().into(),
v8::FunctionTemplate::new(&mut scope, op_read_file).into(),
);

global.set(
v8::String::new(&mut scope, "op_crdt_recv_from_renderer")
.unwrap()
Expand Down
6 changes: 6 additions & 0 deletions rust/decentraland-godot-lib/src/dcl/js/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod engine;
pub mod js_runtime;
pub mod runtime_mod;

use self::js_runtime::{JsRuntime, JsRuntimeState};
use super::{
Expand All @@ -8,13 +9,16 @@ use super::{
};
use super::{RendererResponse, SceneId, SceneResponse};

use std::collections::HashMap;
use std::time::Duration;
use v8::Promise;

// main scene processing thread - constructs an isolate and runs the scene
pub(crate) fn scene_thread(
scene_id: SceneId,
scene_definition: SceneDefinition,
content_mapping: HashMap<String, String>,
base_url: String,
thread_sender_to_main: std::sync::mpsc::SyncSender<SceneResponse>,
thread_receive_from_main: tokio::sync::mpsc::Receiver<RendererResponse>,
scene_crdt: SharedSceneCrdtState,
Expand Down Expand Up @@ -72,6 +76,8 @@ pub(crate) fn scene_thread(
logs: Vec::new(),
main_code: file.unwrap().get_as_text().to_string(),
dying: false,
content_mapping,
base_url,
};

// Eval Init Code
Expand Down
73 changes: 73 additions & 0 deletions rust/decentraland-godot-lib/src/dcl/js/runtime_mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use std::time::{Duration, Instant};

use crate::http_request::{
http_requester::HttpRequester,
request_response::{RequestOption, ResponseEnum, ResponseType},
};

use super::js_runtime::JsRuntime;

pub fn op_read_file(
scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut ret: v8::ReturnValue,
) {
let state = JsRuntime::state_from(scope);
let state = state.borrow();
let mut http_requester = HttpRequester::new();
let file = args.get(0).to_rust_string_lossy(scope);
let file = state.content_mapping.get(&file);

if let Some(file_hash) = file {
let url = format!("{}{file_hash}", state.base_url);
http_requester.send_request(RequestOption::new(
0,
url,
reqwest::Method::GET,
ResponseType::AsBytes,
None,
None,
));

// wait until the request is done or timeout
let start_time = Instant::now();
loop {
if let Some(response) = http_requester.poll() {
if let Ok(response) = response {
if let Ok(ResponseEnum::Bytes(bytes)) = response.response_data {
let arr = slice_to_uint8array(scope, &bytes);
ret.set(arr.into());
}
}
break;
} else {
std::thread::sleep(Duration::from_millis(10));
}

if start_time.elapsed() > Duration::from_secs(10) {
break;
}
}
}
}

pub fn slice_to_uint8array<'a>(
scope: &mut v8::HandleScope<'a>,
buf: &[u8],
) -> v8::Local<'a, v8::Uint8Array> {
let buffer = if buf.is_empty() {
v8::ArrayBuffer::new(scope, 0)
} else {
let store: v8::UniqueRef<_> = v8::ArrayBuffer::new_backing_store(scope, buf.len());
// SAFETY: raw memory copy into the v8 ArrayBuffer allocated above
unsafe {
std::ptr::copy_nonoverlapping(
buf.as_ptr(),
store.data().unwrap().as_ptr() as *mut u8,
buf.len(),
)
}
v8::ArrayBuffer::with_backing_store(scope, &store.make_shared())
};
v8::Uint8Array::new(scope, buffer, 0, buf.len()).expect("Failed to create UintArray8")
}
4 changes: 4 additions & 0 deletions rust/decentraland-godot-lib/src/dcl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ impl DclScene {
pub fn spawn_new_js_dcl_scene(
id: SceneId,
scene_definition: SceneDefinition,
content_mapping: HashMap<String, String>,
base_url: String,
thread_sender_to_main: std::sync::mpsc::SyncSender<SceneResponse>,
) -> Self {
let (main_sender_to_thread, thread_receive_from_renderer) =
Expand All @@ -87,6 +89,8 @@ impl DclScene {
scene_thread(
id,
scene_definition,
content_mapping,
base_url,
thread_sender_to_main,
thread_receive_from_renderer,
thread_scene_crdt,
Expand Down
11 changes: 11 additions & 0 deletions rust/decentraland-godot-lib/src/scene_runner/scene_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,21 @@ impl SceneManager {
}
};

let base_url =
GodotString::from_variant(&content_mapping.get("base_url").unwrap()).to_string();
let content_dictionary = Dictionary::from_variant(&content_mapping.get("content").unwrap());

let content_mapping_hash_map: HashMap<String, String> = content_dictionary
.iter_shared()
.map(|(file_name, file_hash)| (file_name.to_string(), file_hash.to_string()))
.collect();

let new_scene_id = Scene::new_id();
let dcl_scene = DclScene::spawn_new_js_dcl_scene(
new_scene_id,
scene_definition.clone(),
content_mapping_hash_map,
base_url,
self.thread_sender_to_main.clone(),
);

Expand Down
Loading