-
-
Notifications
You must be signed in to change notification settings - Fork 191
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
Add as_slice and as_mut_slice for Packed*Array #137
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for this 👍
I think slices should be safe, since packed arrays are unique (not ref-counted). Would need to spend some deeper thoughts on it though, e.g. if the CoW backing implementation has any impact.
Could you maybe add one test case for each method, in itest/rust/src/packed_array_test.rs
? It's enough to choose one concrete specialization, e.g. for i32
, no need for genericity.
bors try
tryBuild succeeded: |
Added some tests and safety comments. |
You say see: godotengine/godot#36492 (comment) does this cause any problems? |
Good catch! I only tested within rust. I'm not sure what happen when shared between rust and godot. I will make a test. |
itest/rust/src/packed_array_test.rs
Outdated
"arrays should share the same buffer" | ||
); | ||
|
||
// array2 should become a copy of array1 since rc > 1. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "RC > 1" is somewhat irrelevant, now that Godot 4 is released.
I would rather mention that as_mut_slice
triggers a copy-on-write.
Alright, added tests for when arrays are shared between rust and godot. Looks like packed array are always cow except when sharing between godot and godot. You can even make array behave like godot 3 used to by passing it to and from rust. |
Ah ok, that should probably be properly documented. It is a bit unintuitive that these are passed by value in rust but passed by reference in gdscript. |
Regarding merge conflicts, I made |
I agree, but this is on the godot side. As far as gdextension is concerned, it's all cow. This is what I've gathered:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates!
bors try
#[godot_api] | ||
impl PackedArrayTest { | ||
#[func] | ||
fn set_array(&mut self, array: PackedByteArray) { | ||
self.array = array; | ||
} | ||
|
||
#[func] | ||
fn get_array(&self) -> PackedByteArray { | ||
self.array.clone() | ||
} | ||
|
||
#[func] | ||
fn are_separate_buffer(&self, other: PackedByteArray) -> bool { | ||
self.array.as_slice().as_ptr() != other.as_slice().as_ptr() | ||
} | ||
|
||
#[func] | ||
fn do_mutable_access(&mut self) { | ||
self.array.as_mut_slice(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type is currently acting as an abstraction that makes the tests quite a bit harder to understand, because one array is encapsulated, while the other is not.
I would remove the setter/getter as well as any state (struct fields), and just provide two functions:
is_buffer_shared(&self, lhs: &PackedArray, rhs: &PackedArray)
- basically the opposite of
are_separate_buffer
, but doesn't use the double negation
- basically the opposite of
trigger_cow(&self, array: &mut PackedArray)
- same as
do_mutable_access
, but expressing the intent better
- same as
The receiver &self
is only necessary because #[func]
expects it, but you don't access the object's state. You also don't need to have a #[base]
field or a impl GodotExt
.
And if you have this abstraction, use it in Rust! 🙂
(see other comment)
array1.as_slice().as_ptr(), | ||
array2.as_slice().as_ptr(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you could use is_buffer_shared()
(see other comment).
Same for similar occurrences.
let array1 = PackedByteArray::from(&[1, 2]); | ||
let mut array2 = array1.clone(); | ||
let array3 = array1.to_variant(); | ||
let array4 = godot::engine::Image::create_from_data( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you name those more meaningfully?
array1 -> array
array2 -> cloned
array3 -> variant
array4 -> image_data
tryBuild succeeded: |
Why close? 🤔 |
307: Implement `PackedArray::as_slice()`, `as_slice_mut()` r=Bromeon a=Bromeon Resumes abandoned work of #137. Closes #306. Open points: 1. Test CoW across GDScript/Rust boundaries? 2. We now have `slice`, `as_slice` and `as_mut_slice`, where the first returns another array. I wonder if it would be clearer to name it `sub_array` or something instead of `slice`? bors try Co-authored-by: Jan Haller <bromeon@gmail.com>
307: Implement `PackedArray::as_slice()`, `as_slice_mut()` r=Bromeon a=Bromeon Resumes abandoned work of #137. Closes #306. Open points: 1. Test CoW across GDScript/Rust boundaries? 2. We now have `slice`, `as_slice` and `as_mut_slice`, where the first returns another array. I wonder if it would be clearer to name it `sub_array` or something instead of `slice`? bors try Co-authored-by: Jan Haller <bromeon@gmail.com>
307: Implement `PackedArray::as_slice()`, `as_slice_mut()` r=Bromeon a=Bromeon Resumes abandoned work of #137. Closes #306. Open points: 1. Test CoW across GDScript/Rust boundaries? 2. We now have `slice`, `as_slice` and `as_mut_slice`, where the first returns another array. I wonder if it would be clearer to name it `sub_array` or something instead of `slice`? bors try Co-authored-by: Jan Haller <bromeon@gmail.com>
307: Implement `PackedArray::as_slice()`, `as_slice_mut()` r=Bromeon a=Bromeon Resumes abandoned work of #137. Closes #306. Open points: 1. Test CoW across GDScript/Rust boundaries? 2. We now have `slice`, `as_slice` and `as_mut_slice`, where the first returns another array. I wonder if it would be clearer to name it `sub_array` or something instead of `slice`? bors try Co-authored-by: Jan Haller <bromeon@gmail.com>
307: Implement `PackedArray::as_slice()`, `as_slice_mut()` r=Bromeon a=Bromeon Resumes abandoned work of #137. Closes #306. Open points: 1. Test CoW across GDScript/Rust boundaries? 2. We now have `slice`, `as_slice` and `as_mut_slice`, where the first returns another array. I wonder if it would be clearer to name it `sub_array` or something instead of `slice`? bors try Co-authored-by: Jan Haller <bromeon@gmail.com>
307: Implement `PackedArray::as_slice()`, `as_slice_mut()` r=Bromeon a=Bromeon Resumes abandoned work of #137. Closes #306. Open points: 1. Test CoW across GDScript/Rust boundaries? 2. We now have `slice`, `as_slice` and `as_mut_slice`, where the first returns another array. I wonder if it would be clearer to name it `sub_array` or something instead of `slice`? bors try Co-authored-by: Jan Haller <bromeon@gmail.com>
Piggyback off of
ptr
/ptr_mut
.