Skip to content

Commit 4e35ec8

Browse files
committed
Working towards BufferKeyMap implementation
Signed-off-by: Michael X. Grey <[email protected]>
1 parent 6e19af7 commit 4e35ec8

10 files changed

+278
-88
lines changed

macros/src/buffer.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub(crate) fn impl_joined_value(input_struct: &ItemStruct) -> Result<TokenStream
2525
}
2626
};
2727

28-
let buffer_clone_impl = if noncopy {
28+
let impl_buffer_clone = if noncopy {
2929
// Clone impl for structs with a buffer that is not copyable
3030
quote! {
3131
impl #impl_generics ::std::clone::Clone for #buffer_struct_ident #ty_generics #where_clause {
@@ -61,7 +61,7 @@ pub(crate) fn impl_joined_value(input_struct: &ItemStruct) -> Result<TokenStream
6161

6262
#buffer_struct
6363

64-
#buffer_clone_impl
64+
#impl_buffer_clone
6565

6666
impl #impl_generics #struct_ident #ty_generics #where_clause {
6767
fn select_buffers(

src/buffer.rs

+27-11
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ mod any_buffer;
3434
pub use any_buffer::*;
3535

3636
mod buffer_access_lifecycle;
37+
pub use buffer_access_lifecycle::BufferKeyLifecycle;
3738
pub(crate) use buffer_access_lifecycle::*;
3839

3940
mod buffer_key_builder;
@@ -134,12 +135,15 @@ pub struct BufferLocation {
134135
pub source: Entity,
135136
}
136137

137-
#[derive(Clone, Copy)]
138+
#[derive(Clone)]
138139
pub struct CloneFromBuffer<T: Clone> {
139140
pub(crate) location: BufferLocation,
140141
pub(crate) _ignore: std::marker::PhantomData<fn(T)>,
141142
}
142143

144+
//
145+
impl<T: Clone> Copy for CloneFromBuffer<T> {}
146+
143147
impl<T: Clone> CloneFromBuffer<T> {
144148
/// Get the entity ID of the buffer.
145149
pub fn id(&self) -> Entity {
@@ -157,6 +161,15 @@ impl<T: Clone> CloneFromBuffer<T> {
157161
}
158162
}
159163

164+
impl<T: Clone> From<CloneFromBuffer<T>> for Buffer<T> {
165+
fn from(value: CloneFromBuffer<T>) -> Self {
166+
Buffer {
167+
location: value.location,
168+
_ignore: Default::default(),
169+
}
170+
}
171+
}
172+
160173
/// Settings to describe the behavior of a buffer.
161174
#[derive(Default, Clone, Copy)]
162175
pub struct BufferSettings {
@@ -254,20 +267,23 @@ impl<T> BufferKey<T> {
254267
pub fn tag(&self) -> &BufferKeyTag {
255268
&self.tag
256269
}
270+
}
271+
272+
impl<T> BufferKeyLifecycle for BufferKey<T> {
273+
type TargetBuffer = Buffer<T>;
274+
275+
fn create_key(buffer: &Self::TargetBuffer, builder: &BufferKeyBuilder) -> Self {
276+
BufferKey {
277+
tag: builder.make_tag(buffer.id()),
278+
_ignore: Default::default(),
279+
}
280+
}
257281

258-
pub(crate) fn is_in_use(&self) -> bool {
282+
fn is_in_use(&self) -> bool {
259283
self.tag.is_in_use()
260284
}
261285

262-
// We do a deep clone of the key when distributing it to decouple the
263-
// lifecycle of the keys that we send out from the key that's held by the
264-
// accessor node.
265-
//
266-
// The key instance held by the accessor node will never be dropped until
267-
// the session is cleaned up, so the keys that we send out into the workflow
268-
// need to have their own independent lifecycles or else we won't detect
269-
// when the workflow has dropped them.
270-
pub(crate) fn deep_clone(&self) -> Self {
286+
fn deep_clone(&self) -> Self {
271287
Self {
272288
tag: self.tag.deep_clone(),
273289
_ignore: Default::default(),

src/buffer/any_buffer.rs

+16-5
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, BufferAccessMut, BufferAccessors, BufferError,
38-
BufferKey, BufferKeyTag, BufferLocation, BufferStorage, Bufferable, Buffered, Builder,
39-
DrainBuffer, Gate, GateState, InspectBuffer, Joined, ManageBuffer, NotifyBufferUpdate,
40-
OperationError, OperationResult, OperationRoster, OrBroken,
38+
BufferKey, BufferKeyBuilder, BufferKeyLifecycle, 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
@@ -198,12 +198,23 @@ impl AnyBufferKey {
198198
pub fn session(&self) -> Entity {
199199
self.tag.session
200200
}
201+
}
202+
203+
impl BufferKeyLifecycle for AnyBufferKey {
204+
type TargetBuffer = AnyBuffer;
205+
206+
fn create_key(buffer: &AnyBuffer, builder: &BufferKeyBuilder) -> Self {
207+
AnyBufferKey {
208+
tag: builder.make_tag(buffer.id()),
209+
interface: buffer.interface,
210+
}
211+
}
201212

202-
pub(crate) fn is_in_use(&self) -> bool {
213+
fn is_in_use(&self) -> bool {
203214
self.tag.is_in_use()
204215
}
205216

206-
pub(crate) fn deep_clone(&self) -> Self {
217+
fn deep_clone(&self) -> Self {
207218
Self {
208219
tag: self.tag.deep_clone(),
209220
interface: self.interface,

src/buffer/buffer_access_lifecycle.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use tokio::sync::mpsc::UnboundedSender as TokioSender;
2121

2222
use std::sync::Arc;
2323

24-
use crate::{emit_disposal, ChannelItem, Disposal, OperationRoster};
24+
use crate::{emit_disposal, BufferKeyBuilder, ChannelItem, Disposal, OperationRoster};
2525

2626
/// This is used as a field inside of [`crate::BufferKey`] which keeps track of
2727
/// when a key that was sent out into the world gets fully dropped from use. We
@@ -87,3 +87,29 @@ impl Drop for BufferAccessLifecycle {
8787
}
8888
}
8989
}
90+
91+
/// This trait is implemented by [`crate::BufferKey`]-like structs so their
92+
/// lifecycles can be managed.
93+
pub trait BufferKeyLifecycle {
94+
/// What kind of buffer this key can unlock.
95+
type TargetBuffer;
96+
97+
/// Create a new key of this type.
98+
fn create_key(buffer: &Self::TargetBuffer, builder: &BufferKeyBuilder) -> Self;
99+
100+
/// Check if the key is currently in use.
101+
fn is_in_use(&self) -> bool;
102+
103+
/// Create a deep clone of the key. The usage tracking of the clone will
104+
/// be unrelated to the usage tracking of the original.
105+
///
106+
/// We do a deep clone of the key when distributing it to decouple the
107+
/// lifecycle of the keys that we send out from the key that's held by the
108+
/// accessor node.
109+
//
110+
/// The key instance held by the accessor node will never be dropped until
111+
/// the session is cleaned up, so the keys that we send out into the workflow
112+
/// need to have their own independent lifecycles or else we won't detect
113+
/// when the workflow has dropped them.
114+
fn deep_clone(&self) -> Self;
115+
}

src/buffer/buffer_key_builder.rs

+3-11
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, BufferKeyTag, ChannelSender};
22+
use crate::{BufferAccessLifecycle, BufferKeyTag, ChannelSender};
2323

2424
pub struct BufferKeyBuilder {
2525
scope: Entity,
@@ -29,16 +29,8 @@ pub struct BufferKeyBuilder {
2929
}
3030

3131
impl BufferKeyBuilder {
32-
pub(crate) fn build<T>(&self, buffer: Entity) -> BufferKey<T> {
33-
BufferKey {
34-
tag: self.make_tag(buffer),
35-
_ignore: Default::default(),
36-
}
37-
}
38-
39-
// TODO(@mxgrey): Consider refactoring all the buffer key structs to use a
40-
// single inner struct like BufferKeyComponents
41-
pub(crate) fn make_tag(&self, buffer: Entity) -> BufferKeyTag {
32+
/// Make a [`BufferKeyTag`] that can be given to a [`crate::BufferKey`]-like struct.
33+
pub fn make_tag(&self, buffer: Entity) -> BufferKeyTag {
4234
BufferKeyTag {
4335
buffer,
4436
session: self.session,

0 commit comments

Comments
 (0)