From 4fd4ab425e6e40523fe7aab5e319abdf2812c1a8 Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Tue, 16 Jan 2024 11:18:12 -0300 Subject: [PATCH] fix tooltip when IA_ANY is specified move memcpy to packed array to helper functions (fast_create_packed_byte_array_from_*) remove nop() mock ~system/CommunicationsController::sendBinary --- .../pointer_tooltip/tooltip_label.gd | 18 ++++++--- .../src/auth/dcl_player_identity.rs | 17 +------- .../src/av/video_context.rs | 16 ++------ .../src/content/audio.rs | 18 ++------- .../src/content/bytes.rs | 21 ++++++++++ .../src/content/gltf.rs | 6 +-- .../decentraland-godot-lib/src/content/mod.rs | 1 + .../src/content/texture.rs | 39 ++++++++++++++++--- .../src/content/thread_safety.rs | 3 -- .../js/js_modules/CommunicationsController.js | 3 +- rust/decentraland-godot-lib/src/dcl/js/mod.rs | 4 ++ .../src/godot_classes/dcl_ui_background.rs | 9 ++++- 12 files changed, 94 insertions(+), 61 deletions(-) create mode 100644 rust/decentraland-godot-lib/src/content/bytes.rs diff --git a/godot/src/ui/components/pointer_tooltip/tooltip_label.gd b/godot/src/ui/components/pointer_tooltip/tooltip_label.gd index b481c6c0..eaeb2722 100644 --- a/godot/src/ui/components/pointer_tooltip/tooltip_label.gd +++ b/godot/src/ui/components/pointer_tooltip/tooltip_label.gd @@ -14,11 +14,12 @@ func _ready(): func set_tooltip_data(text: String, action: String): var key: String - var index: int = InputMap.get_actions().find(action.to_lower(), 0) + var action_lower: String = action.to_lower() + var index: int = InputMap.get_actions().find(action_lower, 0) if label_text: - if index != -1: - action_to_trigger = action.to_lower() - show() + if index == -1 and action_lower == "ia_any": + key = "Any" + elif index != -1: var event = InputMap.action_get_events(InputMap.get_actions()[index])[0] if event is InputEventKey: key = char(event.unicode).to_upper() @@ -29,15 +30,22 @@ func set_tooltip_data(text: String, action: String): key = "Mouse Right Button" if event.button_index == 0: key = "Mouse Wheel Button" + + if not key.is_empty(): + show() + action_to_trigger = action_lower label_action.text = key label_text.text = text else: - action_to_trigger = "" hide() + action_to_trigger = "" printerr("Action doesn't exist ", action) func mobile_on_panel_container_gui_input(event): + if action_to_trigger.is_empty(): + return + if event is InputEventMouseButton: if event.pressed: Input.action_press(action_to_trigger) diff --git a/rust/decentraland-godot-lib/src/auth/dcl_player_identity.rs b/rust/decentraland-godot-lib/src/auth/dcl_player_identity.rs index 60b41ba6..87e18aea 100644 --- a/rust/decentraland-godot-lib/src/auth/dcl_player_identity.rs +++ b/rust/decentraland-godot-lib/src/auth/dcl_player_identity.rs @@ -5,6 +5,7 @@ use rand::thread_rng; use tokio::task::JoinHandle; use crate::comms::profile::{LambdaProfiles, UserProfile}; +use crate::content::bytes::fast_create_packed_byte_array_from_vec; use crate::dcl::scene_apis::RpcResultSender; use crate::godot_classes::promise::Promise; use crate::http_request::request_response::{RequestResponse, ResponseEnum}; @@ -388,21 +389,7 @@ impl DclPlayerIdentity { return; }; - // TODO: gdext should implement a packedByteArray constructor from &[u8] and not iteration - let body_payload = { - let byte_length = body_payload.len(); - let mut param = PackedByteArray::new(); - param.resize(byte_length); - let data_arr_ptr = param.as_mut_slice(); - - unsafe { - let dst_ptr = &mut data_arr_ptr[0] as *mut u8; - let src_ptr = &body_payload[0] as *const u8; - std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, byte_length); - } - param - }; - + let body_payload = fast_create_packed_byte_array_from_vec(&body_payload); let mut dict = Dictionary::default(); dict.set("content_type", content_type.to_variant()); dict.set("body_payload", body_payload.to_variant()); diff --git a/rust/decentraland-godot-lib/src/av/video_context.rs b/rust/decentraland-godot-lib/src/av/video_context.rs index bb5ce337..cecacb34 100644 --- a/rust/decentraland-godot-lib/src/av/video_context.rs +++ b/rust/decentraland-godot-lib/src/av/video_context.rs @@ -7,10 +7,12 @@ use ffmpeg_next::software::scaling::{context::Context, flag::Flags}; use ffmpeg_next::{decoder, format::context::Input, media::Type, util::frame, Packet}; use godot::engine::image::Format; use godot::engine::{Image, ImageTexture}; -use godot::prelude::{Gd, PackedByteArray, Vector2}; +use godot::prelude::{Gd, Vector2}; use thiserror::Error; use tracing::debug; +use crate::content::bytes::fast_create_packed_byte_array_from_slice; + use super::stream_processor::FfmpegContext; pub struct VideoInfo { @@ -150,17 +152,7 @@ impl FfmpegContext for VideoContext { // let data_arr = PackedByteArray::from(current_frame.data(0)); let raw_data = current_frame.data(0); - let byte_length = raw_data.len(); - let mut data_arr = PackedByteArray::new(); - data_arr.resize(raw_data.len()); - - let data_arr_ptr = data_arr.as_mut_slice(); - - unsafe { - let dst_ptr = &mut data_arr_ptr[0] as *mut u8; - let src_ptr = &raw_data[0] as *const u8; - std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, byte_length); - } + let data_arr = fast_create_packed_byte_array_from_slice(raw_data); let diff = self.last_frame_time.elapsed().as_secs_f32(); debug!( diff --git a/rust/decentraland-godot-lib/src/content/audio.rs b/rust/decentraland-godot-lib/src/content/audio.rs index 970dc0a8..775028b9 100644 --- a/rust/decentraland-godot-lib/src/content/audio.rs +++ b/rust/decentraland-godot-lib/src/content/audio.rs @@ -1,5 +1,5 @@ use godot::{ - builtin::{meta::ToGodot, PackedByteArray}, + builtin::meta::ToGodot, engine::{AudioStream, AudioStreamMp3, AudioStreamWav}, obj::Gd, }; @@ -8,6 +8,7 @@ use tokio::io::AsyncReadExt; use crate::godot_classes::promise::Promise; use super::{ + bytes::fast_create_packed_byte_array_from_vec, content_mapping::ContentMappingAndUrlRef, content_provider::ContentProviderContext, download::fetch_resource_or_wait, @@ -71,7 +72,7 @@ pub async fn load_audio( return; } - let Some(thread_safe_check) = GodotSingleThreadSafety::acquire_owned(&ctx).await else { + let Some(_thread_safe_check) = GodotSingleThreadSafety::acquire_owned(&ctx).await else { reject_promise( get_promise, "Error loading gltf when acquiring thread safety".to_string(), @@ -79,17 +80,7 @@ pub async fn load_audio( return; }; - let byte_length = bytes_vec.len(); - let mut bytes = PackedByteArray::new(); - bytes.resize(byte_length); - - let data_arr_ptr = bytes.as_mut_slice(); - unsafe { - let dst_ptr = &mut data_arr_ptr[0] as *mut u8; - let src_ptr = &bytes_vec[0] as *const u8; - std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, byte_length); - } - + let bytes = fast_create_packed_byte_array_from_vec(&bytes_vec); let audio_stream: Option> = match extension.as_str() { ".wav" => { let mut audio_stream = AudioStreamWav::new(); @@ -118,5 +109,4 @@ pub async fn load_audio( }; resolve_promise(get_promise, Some(audio_stream.to_variant())); - thread_safe_check.nop(); } diff --git a/rust/decentraland-godot-lib/src/content/bytes.rs b/rust/decentraland-godot-lib/src/content/bytes.rs new file mode 100644 index 00000000..9bb256c3 --- /dev/null +++ b/rust/decentraland-godot-lib/src/content/bytes.rs @@ -0,0 +1,21 @@ +use godot::builtin::PackedByteArray; + +// TODO: gdext should implement a packedByteArray constructor from &[u8] and not iteration +pub fn fast_create_packed_byte_array_from_slice(bytes_slice: &[u8]) -> PackedByteArray { + let byte_length = bytes_slice.len(); + let mut bytes = PackedByteArray::new(); + bytes.resize(byte_length); + + let data_arr_ptr = bytes.as_mut_slice(); + unsafe { + let dst_ptr = &mut data_arr_ptr[0] as *mut u8; + let src_ptr = &bytes_slice[0] as *const u8; + std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, byte_length); + } + + bytes +} + +pub fn fast_create_packed_byte_array_from_vec(bytes_vec: &Vec) -> PackedByteArray { + fast_create_packed_byte_array_from_slice(bytes_vec.as_slice()) +} diff --git a/rust/decentraland-godot-lib/src/content/gltf.rs b/rust/decentraland-godot-lib/src/content/gltf.rs index ffd5f644..25bb167d 100644 --- a/rust/decentraland-godot-lib/src/content/gltf.rs +++ b/rust/decentraland-godot-lib/src/content/gltf.rs @@ -127,7 +127,7 @@ pub async fn load_gltf( return; } - let Some(thread_safe_check) = GodotSingleThreadSafety::acquire_owned(&ctx).await else { + let Some(_thread_safe_check) = GodotSingleThreadSafety::acquire_owned(&ctx).await else { reject_promise( get_promise, "Error loading gltf when acquiring thread safety".to_string(), @@ -185,7 +185,6 @@ pub async fn load_gltf( create_colliders(node.clone().upcast()); resolve_promise(get_promise, Some(node.to_variant())); - thread_safe_check.nop(); } pub async fn apply_update_set_mask_colliders( @@ -197,7 +196,7 @@ pub async fn apply_update_set_mask_colliders( get_promise: impl Fn() -> Option>, ctx: ContentProviderContext, ) { - let Some(thread_safe_check) = GodotSingleThreadSafety::acquire_owned(&ctx).await else { + let Some(_thread_safe_check) = GodotSingleThreadSafety::acquire_owned(&ctx).await else { reject_promise( get_promise, "Error loading gltf when acquiring thread safety".to_string(), @@ -228,7 +227,6 @@ pub async fn apply_update_set_mask_colliders( } resolve_promise(get_promise, Some(gltf_node.to_variant())); - thread_safe_check.nop(); } async fn get_dependencies(file_path: &String) -> Result, anyhow::Error> { diff --git a/rust/decentraland-godot-lib/src/content/mod.rs b/rust/decentraland-godot-lib/src/content/mod.rs index 38dfe545..27234b5b 100644 --- a/rust/decentraland-godot-lib/src/content/mod.rs +++ b/rust/decentraland-godot-lib/src/content/mod.rs @@ -1,4 +1,5 @@ mod audio; +pub mod bytes; pub mod content_mapping; pub mod content_notificator; pub mod content_provider; diff --git a/rust/decentraland-godot-lib/src/content/texture.rs b/rust/decentraland-godot-lib/src/content/texture.rs index f14d7993..70d75eca 100644 --- a/rust/decentraland-godot-lib/src/content/texture.rs +++ b/rust/decentraland-godot-lib/src/content/texture.rs @@ -1,16 +1,18 @@ use godot::{ bind::GodotClass, builtin::{meta::ToGodot, GString}, - engine::{file_access::ModeFlags, global::Error, DirAccess, FileAccess, Image, ImageTexture}, + engine::{global::Error, DirAccess, Image, ImageTexture}, obj::Gd, }; +use tokio::io::AsyncReadExt; use crate::godot_classes::promise::Promise; use super::{ + bytes::fast_create_packed_byte_array_from_vec, content_provider::ContentProviderContext, download::fetch_resource_or_wait, - thread_safety::{reject_promise, resolve_promise}, + thread_safety::{reject_promise, resolve_promise, GodotSingleThreadSafety}, }; #[derive(GodotClass)] @@ -40,16 +42,41 @@ pub async fn load_png_texture( } } - let Some(file) = FileAccess::open(GString::from(&absolute_file_path), ModeFlags::READ) else { + let mut file = match tokio::fs::File::open(&absolute_file_path).await { + Ok(file) => file, + Err(err) => { + reject_promise( + get_promise, + format!( + "Error opening texture file {}: {:?}", + absolute_file_path, err + ), + ); + return; + } + }; + + let mut bytes_vec = Vec::new(); + if let Err(err) = file.read_to_end(&mut bytes_vec).await { + reject_promise( + get_promise, + format!( + "Error reading texture file {}: {:?}", + absolute_file_path, err + ), + ); + return; + } + + let Some(_thread_safe_check) = GodotSingleThreadSafety::acquire_owned(&ctx).await else { reject_promise( get_promise, - format!("Error opening png file {}", absolute_file_path), + "Error loading gltf when acquiring thread safety".to_string(), ); return; }; - let bytes = file.get_buffer(file.get_length() as i64); - drop(file); + let bytes = fast_create_packed_byte_array_from_vec(&bytes_vec); let mut image = Image::new(); let err = image.load_png_from_buffer(bytes); diff --git a/rust/decentraland-godot-lib/src/content/thread_safety.rs b/rust/decentraland-godot-lib/src/content/thread_safety.rs index b974fdcb..efb41dab 100644 --- a/rust/decentraland-godot-lib/src/content/thread_safety.rs +++ b/rust/decentraland-godot-lib/src/content/thread_safety.rs @@ -18,9 +18,6 @@ impl GodotSingleThreadSafety { set_thread_safety_checks_enabled(false); Some(Self { _guard: guard }) } - - pub fn nop(&self) { /* nop */ - } } impl Drop for GodotSingleThreadSafety { diff --git a/rust/decentraland-godot-lib/src/dcl/js/js_modules/CommunicationsController.js b/rust/decentraland-godot-lib/src/dcl/js/js_modules/CommunicationsController.js index 774e1598..c9a808a6 100644 --- a/rust/decentraland-godot-lib/src/dcl/js/js_modules/CommunicationsController.js +++ b/rust/decentraland-godot-lib/src/dcl/js/js_modules/CommunicationsController.js @@ -1 +1,2 @@ -module.exports.send = async function (body) { return {} } \ No newline at end of file +module.exports.send = async function (body) { return {} } +module.exports.sendBinary = async function (body) { return { data: [] } } \ No newline at end of file diff --git a/rust/decentraland-godot-lib/src/dcl/js/mod.rs b/rust/decentraland-godot-lib/src/dcl/js/mod.rs index 2de6356e..b8653db6 100644 --- a/rust/decentraland-godot-lib/src/dcl/js/mod.rs +++ b/rust/decentraland-godot-lib/src/dcl/js/mod.rs @@ -261,6 +261,10 @@ pub(crate) fn scene_thread( return; } + rt.block_on(async { + let _ = runtime.run_event_loop(false).await; + }); + let start_time = std::time::SystemTime::now(); let mut elapsed = Duration::default(); diff --git a/rust/decentraland-godot-lib/src/godot_classes/dcl_ui_background.rs b/rust/decentraland-godot-lib/src/godot_classes/dcl_ui_background.rs index 93b0134f..584ffe57 100644 --- a/rust/decentraland-godot-lib/src/godot_classes/dcl_ui_background.rs +++ b/rust/decentraland-godot-lib/src/godot_classes/dcl_ui_background.rs @@ -23,6 +23,7 @@ pub struct DclUiBackground { waiting_hash: GString, texture_loaded: bool, + first_texture_load_shot: bool, } #[godot_api] @@ -33,6 +34,7 @@ impl INode for DclUiBackground { current_value: PbUiBackground::default(), waiting_hash: GString::default(), texture_loaded: false, + first_texture_load_shot: false, } } @@ -100,7 +102,11 @@ impl DclUiBackground { .bind_mut() .get_texture_from_hash(self.waiting_hash.clone()) else { - tracing::error!("trying to set texture not found: {}", self.waiting_hash); + if self.first_texture_load_shot { + self.first_texture_load_shot = false; + } else { + tracing::error!("trying to set texture not found: {}", self.waiting_hash); + } return; }; self.texture_loaded = true; @@ -232,6 +238,7 @@ impl DclUiBackground { ); } + self.first_texture_load_shot = true; self.base.call_deferred("_on_texture_loaded".into(), &[]); } DclSourceTex::VideoTexture(_) => {