Skip to content

Commit c419ab3

Browse files
committed
Refactor buffer keys
Signed-off-by: Michael X. Grey <greyxmike@gmail.com>
1 parent bd32a47 commit c419ab3

File tree

4 files changed

+112
-132
lines changed

4 files changed

+112
-132
lines changed

src/buffer.rs

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl<T> Clone for Buffer<T> {
123123

124124
impl<T> Copy for Buffer<T> {}
125125

126-
/// Get the general identifying information for a buffer to locate it within the
126+
/// The general identifying information for a buffer to locate it within the
127127
/// world. This does not indicate anything about the type of messages that the
128128
/// buffer can contain.
129129
#[derive(Clone, Copy, Debug)]
@@ -227,38 +227,36 @@ impl Default for RetentionPolicy {
227227
/// [1]: crate::Chain::with_access
228228
/// [2]: crate::Bufferable::listen
229229
pub struct BufferKey<T> {
230-
buffer: Entity,
231-
session: Entity,
232-
accessor: Entity,
233-
lifecycle: Option<Arc<BufferAccessLifecycle>>,
230+
tag: BufferKeyTag,
234231
_ignore: std::marker::PhantomData<fn(T)>,
235232
}
236233

237234
impl<T> Clone for BufferKey<T> {
238235
fn clone(&self) -> Self {
239236
Self {
240-
buffer: self.buffer,
241-
session: self.session,
242-
accessor: self.accessor,
243-
lifecycle: self.lifecycle.as_ref().map(Arc::clone),
237+
tag: self.tag.clone(),
244238
_ignore: Default::default(),
245239
}
246240
}
247241
}
248242

249243
impl<T> BufferKey<T> {
250244
/// The buffer ID of this key.
251-
pub fn id(&self) -> Entity {
252-
self.buffer
245+
pub fn buffer(&self) -> Entity {
246+
self.tag.buffer
253247
}
254248

255249
/// The session that this key belongs to.
256250
pub fn session(&self) -> Entity {
257-
self.session
251+
self.tag.session
252+
}
253+
254+
pub(crate) fn tag(&self) -> &BufferKeyTag {
255+
&self.tag
258256
}
259257

260258
pub(crate) fn is_in_use(&self) -> bool {
261-
self.lifecycle.as_ref().is_some_and(|l| l.is_in_use())
259+
self.tag.is_in_use()
262260
}
263261

264262
// We do a deep clone of the key when distributing it to decouple the
@@ -270,6 +268,41 @@ impl<T> BufferKey<T> {
270268
// need to have their own independent lifecycles or else we won't detect
271269
// when the workflow has dropped them.
272270
pub(crate) fn deep_clone(&self) -> Self {
271+
Self {
272+
tag: self.tag.deep_clone(),
273+
_ignore: Default::default(),
274+
}
275+
}
276+
}
277+
278+
impl<T> std::fmt::Debug for BufferKey<T> {
279+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
280+
f.debug_struct("BufferKey")
281+
.field("message_type_name", &std::any::type_name::<T>())
282+
.field("tag", &self.tag)
283+
.finish()
284+
}
285+
}
286+
287+
/// The identifying information for a buffer key. This does not indicate
288+
/// anything about the type of messages that the buffer can contain.
289+
///
290+
/// This struct will be internal to the crate until we decide to make
291+
/// [`BufferAccessLifecycle`] a public struct.
292+
#[derive(Clone)]
293+
pub(crate) struct BufferKeyTag {
294+
pub buffer: Entity,
295+
pub session: Entity,
296+
pub accessor: Entity,
297+
pub lifecycle: Option<Arc<BufferAccessLifecycle>>,
298+
}
299+
300+
impl BufferKeyTag {
301+
pub fn is_in_use(&self) -> bool {
302+
self.lifecycle.as_ref().is_some_and(|l| l.is_in_use())
303+
}
304+
305+
pub fn deep_clone(&self) -> Self {
273306
let mut deep = self.clone();
274307
deep.lifecycle = self
275308
.lifecycle
@@ -279,6 +312,17 @@ impl<T> BufferKey<T> {
279312
}
280313
}
281314

315+
impl std::fmt::Debug for BufferKeyTag {
316+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
317+
f.debug_struct("BufferKeyTag")
318+
.field("buffer", &self.buffer)
319+
.field("session", &self.session)
320+
.field("accessor", &self.accessor)
321+
.field("in_use", &self.is_in_use())
322+
.finish()
323+
}
324+
}
325+
282326
/// This system parameter lets you get read-only access to a buffer that exists
283327
/// within a workflow. Use a [`BufferKey`] to unlock the access.
284328
///
@@ -293,9 +337,9 @@ where
293337

294338
impl<'w, 's, T: 'static + Send + Sync> BufferAccess<'w, 's, T> {
295339
pub fn get<'a>(&'a self, key: &BufferKey<T>) -> Result<BufferView<'a, T>, QueryEntityError> {
296-
let session = key.session;
340+
let session = key.session();
297341
self.query
298-
.get(key.buffer)
342+
.get(key.buffer())
299343
.map(|(storage, gate)| BufferView {
300344
storage,
301345
gate,
@@ -322,9 +366,9 @@ where
322366
T: 'static + Send + Sync,
323367
{
324368
pub fn get<'a>(&'a self, key: &BufferKey<T>) -> Result<BufferView<'a, T>, QueryEntityError> {
325-
let session = key.session;
369+
let session = key.session();
326370
self.query
327-
.get(key.buffer)
371+
.get(key.buffer())
328372
.map(|(storage, gate)| BufferView {
329373
storage,
330374
gate,
@@ -336,10 +380,10 @@ where
336380
&'a mut self,
337381
key: &BufferKey<T>,
338382
) -> Result<BufferMut<'w, 's, 'a, T>, QueryEntityError> {
339-
let buffer = key.buffer;
340-
let session = key.session;
341-
let accessor = key.accessor;
342-
self.query.get_mut(key.buffer).map(|(storage, gate)| {
383+
let buffer = key.buffer();
384+
let session = key.session();
385+
let accessor = key.tag.accessor;
386+
self.query.get_mut(key.buffer()).map(|(storage, gate)| {
343387
BufferMut::new(storage, gate, buffer, session, accessor, &mut self.commands)
344388
})
345389
}

src/buffer/any_buffer.rs

Lines changed: 23 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ use smallvec::SmallVec;
3535

3636
use crate::{
3737
add_listener_to_source, Accessed, Buffer, BufferAccessLifecycle, BufferAccessMut,
38-
BufferAccessors, BufferError, BufferKey, BufferLocation, BufferStorage, Bufferable, Buffered,
39-
Builder, DrainBuffer, Gate, GateState, InspectBuffer, Joined, ManageBuffer, NotifyBufferUpdate,
40-
OperationError, OperationResult, OperationRoster, OrBroken,
38+
BufferAccessors, BufferError, BufferKey, BufferKeyTag, BufferLocation, BufferStorage,
39+
Bufferable, Buffered, Builder, DrainBuffer, Gate, GateState, InspectBuffer, Joined,
40+
ManageBuffer, NotifyBufferUpdate, OperationError, OperationResult, OperationRoster, OrBroken,
4141
};
4242

4343
/// A [`Buffer`] whose message type has been anonymized. Joining with this buffer
@@ -138,10 +138,7 @@ impl<T: 'static + Send + Sync + Any> From<Buffer<T>> for AnyBuffer {
138138
/// [1]: bevy_ecs::prelude::World
139139
#[derive(Clone)]
140140
pub struct AnyBufferKey {
141-
pub(crate) buffer: Entity,
142-
pub(crate) session: Entity,
143-
pub(crate) accessor: Entity,
144-
pub(crate) lifecycle: Option<Arc<BufferAccessLifecycle>>,
141+
pub(crate) tag: BufferKeyTag,
145142
pub(crate) interface: &'static (dyn AnyBufferAccessInterface + Send + Sync),
146143
}
147144

@@ -150,10 +147,7 @@ impl AnyBufferKey {
150147
pub fn downcast<T: 'static>(&self) -> Option<BufferKey<T>> {
151148
if TypeId::of::<T>() == self.interface.message_type_id() {
152149
Some(BufferKey {
153-
buffer: self.buffer,
154-
session: self.session,
155-
accessor: self.accessor,
156-
lifecycle: self.lifecycle.clone(),
150+
tag: self.tag.clone(),
157151
_ignore: Default::default(),
158152
})
159153
} else {
@@ -163,39 +157,31 @@ impl AnyBufferKey {
163157

164158
/// The buffer ID of this key.
165159
pub fn id(&self) -> Entity {
166-
self.buffer
160+
self.tag.buffer
167161
}
168162

169163
/// The session that this key belongs to.
170164
pub fn session(&self) -> Entity {
171-
self.session
165+
self.tag.session
172166
}
173167

174-
fn deep_clone(&self) -> Self {
175-
let mut deep = self.clone();
176-
deep.lifecycle = self
177-
.lifecycle
178-
.as_ref()
179-
.map(|l| Arc::new(l.as_ref().clone()));
180-
deep
168+
fn is_in_use(&self) -> bool {
169+
self.tag.is_in_use()
181170
}
182171

183-
fn is_in_use(&self) -> bool {
184-
self.lifecycle.as_ref().is_some_and(|l| l.is_in_use())
172+
fn deep_clone(&self) -> Self {
173+
Self {
174+
tag: self.tag.deep_clone(),
175+
interface: self.interface,
176+
}
185177
}
186178
}
187179

188180
impl std::fmt::Debug for AnyBufferKey {
189181
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
190182
f.debug_struct("AnyBufferKey")
191-
.field("buffer", &self.buffer)
192-
.field("session", &self.session)
193-
.field("accessor", &self.accessor)
194-
.field(
195-
"in_use",
196-
&self.lifecycle.as_ref().is_some_and(|l| l.is_in_use()),
197-
)
198183
.field("message_type_name", &self.interface.message_type_name())
184+
.field("tag", &self.tag)
199185
.finish()
200186
}
201187
}
@@ -204,10 +190,7 @@ impl<T: 'static + Send + Sync + Any> From<BufferKey<T>> for AnyBufferKey {
204190
fn from(value: BufferKey<T>) -> Self {
205191
let interface = AnyBuffer::interface_for::<T>();
206192
AnyBufferKey {
207-
buffer: value.buffer,
208-
session: value.session,
209-
accessor: value.accessor,
210-
lifecycle: value.lifecycle.clone(),
193+
tag: value.tag,
211194
interface,
212195
}
213196
}
@@ -770,14 +753,14 @@ impl<'w, 's, T: 'static + Send + Sync + Any> AnyBufferAccessMut<'w, 's>
770753
) -> Result<AnyBufferMut<'w, 's, 'a>, BufferError> {
771754
let BufferAccessMut { query, commands } = self;
772755
let (storage, gate) = query
773-
.get_mut(key.buffer)
756+
.get_mut(key.tag.buffer)
774757
.map_err(|_| BufferError::BufferMissing)?;
775758
Ok(AnyBufferMut {
776759
storage: Box::new(storage),
777760
gate,
778-
buffer: key.buffer,
779-
session: key.session,
780-
accessor: Some(key.accessor),
761+
buffer: key.tag.buffer,
762+
session: key.tag.session,
763+
accessor: Some(key.tag.accessor),
781764
commands,
782765
modified: false,
783766
})
@@ -895,7 +878,7 @@ impl<T: 'static + Send + Sync + Any> AnyBufferAccessInterface for AnyBufferAcces
895878
world: &'a World,
896879
) -> Result<AnyBufferView<'a>, BufferError> {
897880
let buffer_ref = world
898-
.get_entity(key.buffer)
881+
.get_entity(key.tag.buffer)
899882
.ok_or(BufferError::BufferMissing)?;
900883
let storage = buffer_ref
901884
.get::<BufferStorage<T>>()
@@ -906,7 +889,7 @@ impl<T: 'static + Send + Sync + Any> AnyBufferAccessInterface for AnyBufferAcces
906889
Ok(AnyBufferView {
907890
storage: Box::new(storage),
908891
gate,
909-
session: key.session,
892+
session: key.tag.session,
910893
})
911894
}
912895

@@ -1001,12 +984,8 @@ impl Accessed for AnyBuffer {
1001984
}
1002985

1003986
fn create_key(&self, builder: &super::BufferKeyBuilder) -> Self::Key {
1004-
let components = builder.as_components(self.id());
1005987
AnyBufferKey {
1006-
buffer: components.buffer,
1007-
session: components.session,
1008-
accessor: components.accessor,
1009-
lifecycle: components.lifecycle,
988+
tag: builder.make_tag(self.id()),
1010989
interface: self.interface,
1011990
}
1012991
}

src/buffer/buffer_key_builder.rs

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use bevy_ecs::prelude::Entity;
1919

2020
use std::sync::Arc;
2121

22-
use crate::{BufferAccessLifecycle, BufferKey, ChannelSender};
22+
use crate::{BufferAccessLifecycle, BufferKey, BufferKeyTag, ChannelSender};
2323

2424
pub struct BufferKeyBuilder {
2525
scope: Entity,
@@ -28,37 +28,18 @@ pub struct BufferKeyBuilder {
2828
lifecycle: Option<(ChannelSender, Arc<()>)>,
2929
}
3030

31-
pub struct BufferKeyComponents {
32-
pub buffer: Entity,
33-
pub session: Entity,
34-
pub accessor: Entity,
35-
pub lifecycle: Option<Arc<BufferAccessLifecycle>>,
36-
}
37-
3831
impl BufferKeyBuilder {
3932
pub(crate) fn build<T>(&self, buffer: Entity) -> BufferKey<T> {
4033
BufferKey {
41-
buffer,
42-
session: self.session,
43-
accessor: self.accessor,
44-
lifecycle: self.lifecycle.as_ref().map(|(sender, tracker)| {
45-
Arc::new(BufferAccessLifecycle::new(
46-
self.scope,
47-
buffer,
48-
self.session,
49-
self.accessor,
50-
sender.clone(),
51-
tracker.clone(),
52-
))
53-
}),
34+
tag: self.make_tag(buffer),
5435
_ignore: Default::default(),
5536
}
5637
}
5738

5839
// TODO(@mxgrey): Consider refactoring all the buffer key structs to use a
5940
// single inner struct like BufferKeyComponents
60-
pub(crate) fn as_components(&self, buffer: Entity) -> BufferKeyComponents {
61-
BufferKeyComponents {
41+
pub(crate) fn make_tag(&self, buffer: Entity) -> BufferKeyTag {
42+
BufferKeyTag {
6243
buffer,
6344
session: self.session,
6445
accessor: self.accessor,

0 commit comments

Comments
 (0)