Skip to content

Commit

Permalink
Implement InstanceStorage optionally as sync godot-rust#18
Browse files Browse the repository at this point in the history
  • Loading branch information
TitanNano committed Apr 1, 2023
1 parent 08c6594 commit d142259
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 106 deletions.
1 change: 1 addition & 0 deletions godot-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ trace = []
codegen-fmt = ["godot-ffi/codegen-fmt"]
codegen-full = ["godot-codegen/codegen-full"]
double-precision = ["godot-codegen/double-precision"]
threads = []

[dependencies]
godot-ffi = { path = "../godot-ffi" }
Expand Down
4 changes: 2 additions & 2 deletions godot-core/src/obj/gd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ where
/// * If there is an ongoing function call from GDScript to Rust, which currently holds a `&mut T`
/// reference to the user instance. This can happen through re-entrancy (Rust -> GDScript -> Rust call).
// Note: possible names: write/read, hold/hold_mut, r/w, r/rw, ...
pub fn bind(&self) -> GdRef<T> {
pub fn bind(&self) -> GdRef<T, impl Deref<Target = T> + '_> {
GdRef::from_cell(self.storage().get())
}

Expand All @@ -151,7 +151,7 @@ where
/// * If another `Gd` smart pointer pointing to the same Rust instance has a live `GdRef` or `GdMut` guard bound.
/// * If there is an ongoing function call from GDScript to Rust, which currently holds a `&T` or `&mut T`
/// reference to the user instance. This can happen through re-entrancy (Rust -> GDScript -> Rust call).
pub fn bind_mut(&mut self) -> GdMut<T> {
pub fn bind_mut(&mut self) -> GdMut<T, impl Deref<Target = T> + DerefMut<Target = T> + '_> {
GdMut::from_cell(self.storage().get_mut())
}

Expand Down
44 changes: 32 additions & 12 deletions godot-core/src/obj/guards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,33 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

use std::cell;
use std::fmt::Debug;
use std::ops::{Deref, DerefMut};

/// Immutably/shared bound reference guard for a [`Gd`][crate::obj::Gd] smart pointer.
///
/// See [`Gd::bind`][crate::obj::Gd::bind] for usage.
#[derive(Debug)]
pub struct GdRef<'a, T> {
cell_ref: cell::Ref<'a, T>,
pub struct GdRef<T, C>
where
C: Deref<Target = T>,
{
cell_ref: C,
}

impl<'a, T> GdRef<'a, T> {
pub(crate) fn from_cell(cell_ref: cell::Ref<'a, T>) -> Self {
impl<T, C> GdRef<T, C>
where
C: Deref<Target = T>,
{
pub(crate) fn from_cell(cell_ref: C) -> Self {
Self { cell_ref }
}
}

impl<T> Deref for GdRef<'_, T> {
impl<T, C> Deref for GdRef<T, C>
where
C: Deref<Target = T>,
{
type Target = T;

fn deref(&self) -> &T {
Expand All @@ -38,25 +46,37 @@ impl<T> Deref for GdRef<'_, T> {
///
/// See [`Gd::bind_mut`][crate::obj::Gd::bind_mut] for usage.
#[derive(Debug)]
pub struct GdMut<'a, T> {
cell_ref: cell::RefMut<'a, T>,
pub struct GdMut<T, C>
where
C: DerefMut<Target = T> + Deref<Target = T>,
{
cell_ref: C,
}

impl<'a, T> GdMut<'a, T> {
pub(crate) fn from_cell(cell_ref: cell::RefMut<'a, T>) -> Self {
impl<T, C> GdMut<T, C>
where
C: DerefMut<Target = T> + Deref<Target = T>,
{
pub(crate) fn from_cell(cell_ref: C) -> Self {
Self { cell_ref }
}
}

impl<T> Deref for GdMut<'_, T> {
impl<T, C> Deref for GdMut<T, C>
where
C: DerefMut<Target = T> + Deref<Target = T>,
{
type Target = T;

fn deref(&self) -> &T {
self.cell_ref.deref()
}
}

impl<T> DerefMut for GdMut<'_, T> {
impl<T, C> DerefMut for GdMut<T, C>
where
C: DerefMut<Target = T>,
{
fn deref_mut(&mut self) -> &mut T {
self.cell_ref.deref_mut()
}
Expand Down
Loading

0 comments on commit d142259

Please sign in to comment.