Skip to content

Commit

Permalink
feat: add scenes rpcs thought tokio oneshot channels and change realm…
Browse files Browse the repository at this point in the history
… for restricted action api (#62)

* fix overlapping bug, when the camera mode area is removed (scene unload), now it triggers the overlapping correctly

* add rpcs and change_realm restricted action

* format

* add confirmation dialog to move realm

* format

* Update rust/decentraland-godot-lib/src/dcl/js/js_modules/RestrictedActions.js

Co-authored-by: Lean Mendoza <[email protected]>
Signed-off-by: Mateo Miccino <[email protected]>

---------

Signed-off-by: Mateo Miccino <[email protected]>
  • Loading branch information
kuruk-mm authored Oct 18, 2023
1 parent b613e04 commit e3e68ed
Show file tree
Hide file tree
Showing 21 changed files with 462 additions and 48 deletions.
8 changes: 6 additions & 2 deletions godot/src/logic/player/camera_mode_area_detector.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,27 @@ extends Area3D
signal block_camera_mode(mode: Global.CameraMode)
signal unblock_camera_mode

var overlapping_areas: Array[Area3D] = []


func _on_area_entered(area):
if area is DclCameraModeArea3D:
overlapping_areas.push_back(area)
check_areas()


func _on_area_exited(area):
if area is DclCameraModeArea3D:
overlapping_areas.erase(area)
check_areas()


func get_last_dcl_camera_mode_area_3d() -> DclCameraModeArea3D:
return get_overlapping_areas().back()
return overlapping_areas.back()


func check_areas():
if has_overlapping_areas():
if !overlapping_areas.is_empty():
var first_area = get_last_dcl_camera_mode_area_3d() # get first
if first_area != null:
block_camera_mode.emit(first_area.forced_camera_mode)
Expand Down
2 changes: 0 additions & 2 deletions godot/src/logic/player/camera_mode_area_detector.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,5 @@ script = ExtResource("1_wchgk")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("BoxShape3D_40kco")

[node name="RemoteTransform3D" type="RemoteTransform3D" parent="."]

[connection signal="area_entered" from="." to="." method="_on_area_entered"]
[connection signal="area_exited" from="." to="." method="_on_area_exited"]
6 changes: 6 additions & 0 deletions godot/src/ui/confirm_dialog/confirm_dialog.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
extends DclConfirmDialog


func _on_visibility_changed():
if is_visible():
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
70 changes: 70 additions & 0 deletions godot/src/ui/confirm_dialog/confirm_dialog.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
[gd_scene load_steps=3 format=3 uid="uid://rffmwq3dxlaq"]

[ext_resource type="FontFile" uid="uid://cmc7ku5u0efdy" path="res://assets/themes/fonts/lato_family/Lato-Bold.ttf" id="1_exitm"]
[ext_resource type="Script" path="res://src/ui/confirm_dialog/confirm_dialog.gd" id="1_yn6j0"]

[node name="ConfirmDialog" type="DclConfirmDialog"]
custom_minimum_size = Vector2(360, 280)
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -160.0
offset_top = -90.0
offset_right = 80.0
offset_bottom = 90.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 4
size_flags_vertical = 4
script = ExtResource("1_yn6j0")

[node name="VBoxContainer" type="VBoxContainer" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 10.0
offset_top = 10.0
offset_right = -10.0
offset_bottom = -10.0
grow_horizontal = 2
grow_vertical = 2

[node name="Title" type="Label" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 1
theme_override_fonts/font = ExtResource("1_exitm")
theme_override_font_sizes/font_size = 22
text = "Title"
horizontal_alignment = 1
clip_text = true

[node name="Description" type="Label" parent="VBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
text = "Description"
horizontal_alignment = 1
autowrap_mode = 2
clip_text = true

[node name="CenterContainer" type="CenterContainer" parent="VBoxContainer"]
layout_mode = 2

[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/CenterContainer"]
layout_mode = 2

[node name="OkButton" type="Button" parent="VBoxContainer/CenterContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "Yes"

[node name="RejectButton" type="Button" parent="VBoxContainer/CenterContainer/HBoxContainer"]
unique_name_in_owner = true
layout_mode = 2
text = "No"

[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
13 changes: 10 additions & 3 deletions godot/src/ui/explorer.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=17 format=3 uid="uid://deq5v42fmh0y7"]
[gd_scene load_steps=18 format=3 uid="uid://deq5v42fmh0y7"]

[ext_resource type="Script" path="res://src/ui/explorer.gd" id="1_5n8xk"]
[ext_resource type="Texture2D" uid="uid://by286h7kaeqr3" path="res://assets/empty-scenes/FloorBaseGrass_01/Floor_Grass01.png.png" id="2_7jksa"]
Expand All @@ -9,6 +9,7 @@
[ext_resource type="PackedScene" uid="uid://c6a0rjrc13kel" path="res://src/ui/components/line_edit_command/line_edit_command.tscn" id="9_5u55i"]
[ext_resource type="PackedScene" uid="uid://dmr0fcamx7t56" path="res://src/mobile/joystick/virtual_joystick.tscn" id="9_lxw33"]
[ext_resource type="PackedScene" uid="uid://wgrmvh6h51w3" path="res://src/ui/voice_chat.tscn" id="10_l3sp6"]
[ext_resource type="PackedScene" uid="uid://rffmwq3dxlaq" path="res://src/ui/confirm_dialog/confirm_dialog.tscn" id="10_sldb0"]
[ext_resource type="PackedScene" uid="uid://mc4jrvowdpxp" path="res://src/ui/components/pointer_tooltip/pointer_tooltip.tscn" id="11_qjs00"]

[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_xs7js"]
Expand All @@ -27,7 +28,7 @@ texture_filter = 0

[sub_resource type="Theme" id="Theme_1ufu0"]

[sub_resource type="ButtonGroup" id="ButtonGroup_gkn7s"]
[sub_resource type="ButtonGroup" id="ButtonGroup_osonw"]
resource_name = "Tabs"

[node name="explorer" type="Node3D"]
Expand Down Expand Up @@ -172,7 +173,13 @@ layout_mode = 2
[node name="Control_Menu" parent="UI" instance=ExtResource("5_mso44")]
visible = false
layout_mode = 1
group = SubResource("ButtonGroup_gkn7s")
group = SubResource("ButtonGroup_osonw")

[node name="ConfirmDialog" parent="UI" instance=ExtResource("10_sldb0")]
visible = false
layout_mode = 1
offset_left = -120.0
offset_right = 120.0

[node name="Timer_BroadcastPosition" type="Timer" parent="."]
wait_time = 0.1
Expand Down
1 change: 1 addition & 0 deletions rust/decentraland-godot-lib/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod rpc;
44 changes: 44 additions & 0 deletions rust/decentraland-godot-lib/src/common/rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std::sync::{Arc, RwLock};

#[derive(Debug, Clone)]
pub struct RpcResultSender<T>(Arc<RwLock<Option<tokio::sync::oneshot::Sender<T>>>>);

impl<T: 'static> RpcResultSender<T> {
pub fn new(sender: tokio::sync::oneshot::Sender<T>) -> Self {
Self(Arc::new(RwLock::new(Some(sender))))
}

pub fn send(&self, result: T) {
if let Ok(mut guard) = self.0.write() {
if let Some(response) = guard.take() {
let _ = response.send(result);
}
}
}

pub fn take(&self) -> tokio::sync::oneshot::Sender<T> {
self.0
.write()
.ok()
.and_then(|mut guard| guard.take())
.take()
.unwrap()
}
}

impl<T: 'static> From<tokio::sync::oneshot::Sender<T>> for RpcResultSender<T> {
fn from(value: tokio::sync::oneshot::Sender<T>) -> Self {
RpcResultSender::new(value)
}
}

#[derive(Debug)]
pub enum RpcCall {
ChangeRealm {
to: String,
message: Option<String>,
response: RpcResultSender<Result<(), String>>,
},
}

pub type RpcCalls = Vec<RpcCall>;
28 changes: 20 additions & 8 deletions rust/decentraland-godot-lib/src/dcl/js/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ use std::{

use deno_core::{op, Op, OpDecl, OpState};

use crate::dcl::{
crdt::{
message::{append_gos_component, process_many_messages, put_or_delete_lww_component},
SceneCrdtState,
use crate::{
common::rpc::RpcCalls,
dcl::{
crdt::{
message::{append_gos_component, process_many_messages, put_or_delete_lww_component},
SceneCrdtState,
},
js::{SceneDying, SceneMainCrdtFileContent},
serialization::{reader::DclReader, writer::DclWriter},
RendererResponse, SceneId, SceneResponse, SharedSceneCrdtState,
},
js::{SceneDying, SceneMainCrdtFileContent},
serialization::{reader::DclReader, writer::DclWriter},
RendererResponse, SceneId, SceneResponse, SharedSceneCrdtState,
};

use super::{SceneElapsedTime, SceneLogs};
Expand Down Expand Up @@ -57,9 +60,18 @@ fn op_crdt_send_to_renderer(op_state: Rc<RefCell<OpState>>, messages: &[u8]) {
op_state.put(mutex_scene_crdt_state);
op_state.put(scene_id);

let rpc_calls = std::mem::take(op_state.borrow_mut::<RpcCalls>());

let sender = op_state.borrow_mut::<std::sync::mpsc::SyncSender<SceneResponse>>();

sender
.send(SceneResponse::Ok(scene_id, dirty, logs.0, elapsed_time))
.send(SceneResponse::Ok(
scene_id,
dirty,
logs.0,
elapsed_time,
rpc_calls,
))
.expect("error sending scene response!!")
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
module.exports.movePlayerTo = async function (body) { return {} }
module.exports.teleportTo = async function (body) { return {} }
module.exports.triggerEmote = async function (body) { return {} }
module.exports.changeRealm = async function (body) { return {} }
module.exports.changeRealm = async function (body) {
const response = await Deno.core.ops.op_change_realm(body.realm, body.message)
return response
}
module.exports.openExternalUrl = async function (body) { return {} }
module.exports.openNftDialog = async function (body) { return {} }
module.exports.setCommunicationsAdapter = async function (body) { return {} }
17 changes: 15 additions & 2 deletions rust/decentraland-godot-lib/src/dcl/js/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
pub mod engine;
pub mod fetch;
pub mod restricted_actions;
pub mod runtime;
pub mod websocket;

use crate::common::rpc::RpcCalls;
use crate::wallet::Wallet;

use super::{
Expand Down Expand Up @@ -59,11 +61,12 @@ pub fn create_runtime() -> deno_core::JsRuntime {
// add core ops
ext = ext.ops(vec![op_require::DECL, op_log::DECL, op_error::DECL]);

let op_sets: [Vec<deno_core::OpDecl>; 4] = [
let op_sets: [Vec<deno_core::OpDecl>; 5] = [
engine::ops(),
runtime::ops(),
fetch::ops(),
websocket::ops(),
restricted_actions::ops(),
];

let mut op_map = HashMap::new();
Expand Down Expand Up @@ -114,6 +117,8 @@ pub(crate) fn scene_thread(
) {
let mut scene_main_crdt = None;
let main_crdt_file_path = scene_definition.main_crdt_path;

// on main.crdt detected
if !main_crdt_file_path.is_empty() {
let file = godot::engine::FileAccess::open(
godot::prelude::GodotString::from(main_crdt_file_path),
Expand All @@ -130,7 +135,13 @@ pub(crate) fn scene_thread(

let dirty = scene_crdt_state.take_dirty();
thread_sender_to_main
.send(SceneResponse::Ok(scene_id, dirty, Vec::new(), 0.0))
.send(SceneResponse::Ok(
scene_id,
dirty,
Vec::new(),
0.0,
RpcCalls::default(),
))
.expect("error sending scene response!!");

scene_main_crdt = Some(buf);
Expand Down Expand Up @@ -174,6 +185,8 @@ pub(crate) fn scene_thread(

state.borrow_mut().put(wallet);

state.borrow_mut().put(RpcCalls::default());

if let Some(scene_main_crdt) = scene_main_crdt {
state.borrow_mut().put(scene_main_crdt);
}
Expand Down
29 changes: 29 additions & 0 deletions rust/decentraland-godot-lib/src/dcl/js/restricted_actions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::{cell::RefCell, rc::Rc};

use deno_core::{op, Op, OpDecl, OpState};

use crate::common::rpc::{RpcCall, RpcCalls};

pub fn ops() -> Vec<OpDecl> {
vec![op_change_realm::DECL]
}

#[op]
async fn op_change_realm(
op_state: Rc<RefCell<OpState>>,
realm: String,
message: Option<String>,
) -> bool {
let (sx, rx) = tokio::sync::oneshot::channel::<Result<(), String>>();

op_state
.borrow_mut()
.borrow_mut::<RpcCalls>()
.push(RpcCall::ChangeRealm {
to: realm,
message,
response: sx.into(),
});

matches!(rx.await, Ok(Ok(_)))
}
3 changes: 2 additions & 1 deletion rust/decentraland-godot-lib/src/dcl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub mod crdt;
pub mod js;
pub mod serialization;

use crate::wallet::Wallet;
use crate::{common::rpc::RpcCalls, wallet::Wallet};

use self::{
components::{SceneComponentId, SceneEntityId},
Expand Down Expand Up @@ -59,6 +59,7 @@ pub enum SceneResponse {
(DirtyEntities, DirtyLwwComponents, DirtyGosComponents),
Vec<SceneLogMessage>,
f32,
RpcCalls,
),
RemoveGodotScene(SceneId, Vec<SceneLogMessage>),
}
Expand Down
Loading

0 comments on commit e3e68ed

Please sign in to comment.