Skip to content

Commit

Permalink
workaround to resolve promises, fix blocking when scene is loaded
Browse files Browse the repository at this point in the history
  • Loading branch information
leanmendoza committed Jan 16, 2024
1 parent 4fd4ab4 commit 507f3d8
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 2 deletions.
4 changes: 4 additions & 0 deletions godot/src/test/testing_api.gd
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ func async_take_and_compare_snapshot(
dcl_rpc_sender
)

var pending_promises := Global.content_provider.get_pending_promises()
if not pending_promises.is_empty():
await PromiseUtils.async_all(Global.content_provider.get_pending_promises())

# TODO: make this configurable
var hide_player := true

Expand Down
10 changes: 10 additions & 0 deletions rust/decentraland-godot-lib/src/content/content_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,16 @@ impl ContentProvider {
}
Variant::nil()
}

#[func]
pub fn get_pending_promises(&self) -> Array<Gd<Promise>> {
Array::from_iter(
self.cached
.iter()
.filter(|(_, entry)| !entry.promise.bind().is_resolved())
.map(|(_, entry)| entry.promise.clone()),
)
}
}

impl ContentProvider {
Expand Down
6 changes: 6 additions & 0 deletions rust/decentraland-godot-lib/src/dcl/js/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub fn ops() -> Vec<OpDecl> {
vec![
op_crdt_send_to_renderer::DECL,
op_crdt_recv_from_renderer::DECL,
op_run_async::DECL,
]
}

Expand Down Expand Up @@ -79,6 +80,11 @@ fn op_crdt_send_to_renderer(op_state: Rc<RefCell<OpState>>, messages: &[u8]) {
.expect("error sending scene response!!")
}

#[op(v8)]
async fn op_run_async(op_state: Rc<RefCell<OpState>>) {
let _ = op_state.borrow_mut();
}

#[op(v8)]
async fn op_crdt_recv_from_renderer(op_state: Rc<RefCell<OpState>>) -> Vec<Vec<u8>> {
let dying = op_state.borrow().borrow::<SceneDying>().0;
Expand Down
3 changes: 3 additions & 0 deletions rust/decentraland-godot-lib/src/dcl/js/js_modules/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports.run_async = async function () {
await Deno.core.ops.op_run_async();
}
21 changes: 19 additions & 2 deletions rust/decentraland-godot-lib/src/dcl/js/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,16 +254,32 @@ pub(crate) fn scene_thread(
Ok(script) => script,
};

let utils_script = rt.block_on(async {
runtime.execute_script("<loader>", ascii_str!("require (\"~utils.js\")"))
});
let utils_script = match utils_script {
Err(e) => {
tracing::error!("[scene thread {scene_id:?}] utils script load error: {}", e);
return;
}
Ok(script) => script,
};

let result =
rt.block_on(async { run_script(&mut runtime, &script, "onStart", |_| Vec::new()).await });
if let Err(e) = result {
tracing::error!("[scene thread {scene_id:?}] script load running: {}", e);
return;
}

rt.block_on(async {
let _ = runtime.run_event_loop(false).await;
// instead of using run_event_loop for polling, this is a workaround to resolve pending promises
let result = rt.block_on(async {
run_script(&mut runtime, &utils_script, "run_async", |_| Vec::new()).await
});
if let Err(e) = result {
tracing::error!("[scene thread {scene_id:?}] script load running: {}", e);
return;
}

let start_time = std::time::SystemTime::now();
let mut elapsed = Duration::default();
Expand Down Expand Up @@ -382,6 +398,7 @@ fn op_require(
match module_spec.as_str() {
// user module load
"~scene.js" => Ok(state.take::<SceneJsFileContent>().0),
"~utils.js" => Ok(include_str!("js_modules/utils.js").to_owned()),
// core module load
"~system/CommunicationsController" => {
Ok(include_str!("js_modules/CommunicationsController.js").to_owned())
Expand Down

0 comments on commit 507f3d8

Please sign in to comment.