Skip to content

Commit 5dcae45

Browse files
committed
Implement AnyBufferView
Signed-off-by: Michael X. Grey <mxgrey@intrinsic.ai>
1 parent 0d1224f commit 5dcae45

File tree

2 files changed

+135
-66
lines changed

2 files changed

+135
-66
lines changed

src/buffer/any_buffer.rs

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,52 @@ impl<T: 'static + Send + Sync + Any> From<BufferKey<T>> for AnyBufferKey {
165165
}
166166
}
167167

168+
/// Similar to [`BufferView`][crate::BufferView], but this can be unlocked with
169+
/// an [`AnyBufferKey`], so it can work for any buffer whose message types
170+
/// support serialization and deserialization.
171+
pub struct AnyBufferView<'a> {
172+
storage: Box<dyn AnyBufferViewing + 'a>,
173+
gate: &'a GateState,
174+
session: Entity,
175+
}
176+
177+
impl<'a> AnyBufferView<'a> {
178+
/// Look at the oldest message in the buffer.
179+
pub fn oldest(&self) -> Option<AnyMessageRef<'_>> {
180+
self.storage.any_oldest(self.session)
181+
}
182+
183+
/// Look at the newest message in the buffer.
184+
pub fn newest(&self) -> Option<AnyMessageRef<'_>> {
185+
self.storage.any_newest(self.session)
186+
}
187+
188+
/// Borrow a message from the buffer. Index 0 is the oldest message in the buffer
189+
/// while the highest index is the newest message in the buffer.
190+
pub fn get(&self, index: usize) -> Option<AnyMessageRef<'_>> {
191+
self.storage.any_get(self.session, index)
192+
}
193+
194+
/// Get how many messages are in this buffer.
195+
pub fn len(&self) -> usize {
196+
self.storage.any_count(self.session)
197+
}
198+
199+
/// Check if the buffer is empty.
200+
pub fn is_empty(&self) -> bool {
201+
self.len() == 0
202+
}
203+
204+
/// Check whether the gate of this buffer is open or closed.
205+
pub fn gate(&self) -> Gate {
206+
self.gate
207+
.map
208+
.get(&self.session)
209+
.copied()
210+
.unwrap_or(Gate::Open)
211+
}
212+
}
213+
168214
/// Similar to [`BufferMut`][crate::BufferMut], but this can be unlocked with an
169215
/// [`AnyBufferKey`], so it can work for any buffer regardless of the data type
170216
/// inside.
@@ -198,7 +244,7 @@ impl<'w, 's, 'a> AnyBufferMut<'w, 's, 'a> {
198244
}
199245

200246
/// Borrow a message from the buffer. Index 0 is the oldest message in the buffer
201-
/// with the highest index being the newest message in the buffer.
247+
/// while the highest index is the newest message in the buffer.
202248
pub fn get(&self, index: usize) -> Option<AnyMessageRef<'_>> {
203249
self.storage.any_get(self.session, index)
204250
}
@@ -381,6 +427,15 @@ impl<'w, 's, 'a> Drop for AnyBufferMut<'w, 's, 'a> {
381427
/// This trait allows [`World`] to give you access to any buffer using an
382428
/// [`AnyBufferKey`].
383429
pub trait AnyBufferWorldAccess {
430+
/// Call this to get read-only access to any buffer.
431+
///
432+
/// For technical reasons this requires direct [`World`] access, but you can
433+
/// do other read-only queries on the world while holding onto the
434+
/// [`AnyBufferView`].
435+
fn any_buffer_view<'a>(
436+
&self,
437+
key: &AnyBufferKey,
438+
) -> Result<AnyBufferView<'_>, BufferError>;
384439

385440
/// Call this to get mutable access to any buffer.
386441
///
@@ -394,6 +449,13 @@ pub trait AnyBufferWorldAccess {
394449
}
395450

396451
impl AnyBufferWorldAccess for World {
452+
fn any_buffer_view<'a>(
453+
&self,
454+
key: &AnyBufferKey,
455+
) -> Result<AnyBufferView<'_>, BufferError> {
456+
key.interface.create_any_buffer_view(key, self)
457+
}
458+
397459
fn any_buffer_mut<U>(
398460
&mut self,
399461
key: &AnyBufferKey,
@@ -488,6 +550,28 @@ impl std::ops::RangeBounds<usize> for AnyRange {
488550

489551
pub type AnyMessageRef<'a> = &'a (dyn Any + 'static + Send + Sync);
490552

553+
impl<T: 'static + Send + Sync + Any> AnyBufferViewing for &'_ BufferStorage<T> {
554+
fn any_count(&self, session: Entity) -> usize {
555+
self.count(session)
556+
}
557+
558+
fn any_oldest<'a>(&'a self, session: Entity) -> Option<AnyMessageRef<'a>> {
559+
self.oldest(session).map(to_any_ref)
560+
}
561+
562+
fn any_newest<'a>(&'a self, session: Entity) -> Option<AnyMessageRef<'a>> {
563+
self.newest(session).map(to_any_ref)
564+
}
565+
566+
fn any_get<'a>(&'a self, session: Entity, index: usize) -> Option<AnyMessageRef<'a>> {
567+
self.get(session, index).map(to_any_ref)
568+
}
569+
570+
fn any_message_type(&self) -> TypeId {
571+
TypeId::of::<T>()
572+
}
573+
}
574+
491575
impl<T: 'static + Send + Sync + Any> AnyBufferViewing for Mut<'_, BufferStorage<T>> {
492576
fn any_count(&self, session: Entity) -> usize {
493577
self.count(session)
@@ -644,6 +728,12 @@ pub(crate) trait AnyBufferAccessInterface {
644728
session: Entity,
645729
) -> Result<AnyMessage, OperationError>;
646730

731+
fn create_any_buffer_view<'a>(
732+
&self,
733+
key: &AnyBufferKey,
734+
world: &'a World,
735+
) -> Result<AnyBufferView<'a>, BufferError>;
736+
647737
fn create_any_buffer_access_mut_state(
648738
&self,
649739
world: &mut World,
@@ -702,6 +792,21 @@ impl<T: 'static + Send + Sync + Any> AnyBufferAccessInterface for AnyBufferAcces
702792
entity_mut.pull_from_buffer::<T>(session).map(to_any_message)
703793
}
704794

795+
fn create_any_buffer_view<'a>(
796+
&self,
797+
key: &AnyBufferKey,
798+
world: &'a World,
799+
) -> Result<AnyBufferView<'a>, BufferError> {
800+
let buffer_ref = world.get_entity(key.buffer).ok_or(BufferError::BufferMissing)?;
801+
let storage = buffer_ref.get::<BufferStorage<T>>().ok_or(BufferError::BufferMissing)?;
802+
let gate = buffer_ref.get::<GateState>().ok_or(BufferError::BufferMissing)?;
803+
Ok(AnyBufferView {
804+
storage: Box::new(storage),
805+
gate,
806+
session: key.session
807+
})
808+
}
809+
705810
fn create_any_buffer_access_mut_state(
706811
&self,
707812
world: &mut World,
@@ -865,9 +970,7 @@ mod tests {
865970
In(key): In<AnyBufferKey>,
866971
world: &mut World,
867972
) -> usize {
868-
world.any_buffer_mut(&key, |access| {
869-
access.len()
870-
}).unwrap()
973+
world.any_buffer_view(&key).unwrap().len()
871974
}
872975

873976
#[test]

src/buffer/json_buffer.rs

Lines changed: 28 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use smallvec::SmallVec;
3737

3838
use crate::{
3939
AnyBufferAccessImpl, AnyBufferAccessInterface, AnyBuffer, AnyBufferKey,
40-
AnyRange, Buffer, BufferAccessors, BufferAccess, BufferKey, BufferKeyBuilder,
40+
AnyRange, Buffer, BufferAccessors, BufferKey, BufferKeyBuilder,
4141
BufferAccessLifecycle, BufferAccessMut, BufferError, BufferStorage, Builder,
4242
DrainBuffer, OperationError, OperationResult, InspectBuffer, ManageBuffer,
4343
Gate, GateState, NotifyBufferUpdate, Bufferable, Buffered, OrBroken, Joined,
@@ -177,7 +177,6 @@ impl From<JsonBufferKey> for AnyBufferKey {
177177
pub struct JsonBufferView<'a> {
178178
storage: Box<dyn JsonBufferViewing + 'a>,
179179
gate: &'a GateState,
180-
buffer: Entity,
181180
session: Entity,
182181
}
183182

@@ -412,15 +411,13 @@ pub trait JsonBufferWorldAccess {
412411
/// Call this to get read-only access to any buffer whose message type is
413412
/// serializable and deserializable.
414413
///
415-
/// Pass in a callback that will receive a [`JsonBufferView`] alongside a
416-
/// shared borrow of the [`World`]. Due to technical reasons this function
417-
/// needs to be called on a `&mut World`, but you can still view the world
418-
/// from inside the callback using the second argument.
419-
fn json_buffer_view<U>(
420-
&mut self,
414+
/// For technical reasons this requires direct [`World`] access, but you can
415+
/// do other read-only queries on the world while holding onto the
416+
/// [`JsonBufferView`].
417+
fn json_buffer_view(
418+
&self,
421419
key: &JsonBufferKey,
422-
f: impl FnOnce(JsonBufferView, &World) -> U,
423-
) -> Result<U, BufferError>;
420+
) -> Result<JsonBufferView<'_>, BufferError>;
424421

425422
/// Call this to get mutable access to any buffer whose message type is
426423
/// serializable and deserializable.
@@ -435,16 +432,11 @@ pub trait JsonBufferWorldAccess {
435432
}
436433

437434
impl JsonBufferWorldAccess for World {
438-
fn json_buffer_view<U>(
439-
&mut self,
435+
fn json_buffer_view(
436+
&self,
440437
key: &JsonBufferKey,
441-
f: impl FnOnce(JsonBufferView, &World) -> U,
442-
) -> Result<U, BufferError> {
443-
let interface = key.interface;
444-
let mut state = interface.create_json_buffer_access_state(self);
445-
let access = state.get_json_buffer_access(self);
446-
let buffer_view = access.as_json_buffer_view(key)?;
447-
Ok(f(buffer_view, &self))
438+
) -> Result<JsonBufferView<'_>, BufferError> {
439+
key.interface.create_json_buffer_view(key, self)
448440
}
449441

450442
fn json_buffer_mut<U>(
@@ -695,10 +687,11 @@ trait JsonBufferAccessInterface {
695687
session: Entity,
696688
) -> Result<JsonMessage, OperationError>;
697689

698-
fn create_json_buffer_access_state(
690+
fn create_json_buffer_view<'a>(
699691
&self,
700-
world: &mut World,
701-
) -> Box<dyn JsonBufferAccessState>;
692+
key: &JsonBufferKey,
693+
world: &'a World,
694+
) -> Result<JsonBufferView<'a>, BufferError>;
702695

703696
fn create_json_buffer_access_mut_state(
704697
&self,
@@ -764,11 +757,19 @@ impl<T: 'static + Send + Sync + Serialize + DeserializeOwned> JsonBufferAccessIn
764757
serde_json::to_value(value).or_broken()
765758
}
766759

767-
fn create_json_buffer_access_state(
760+
fn create_json_buffer_view<'a>(
768761
&self,
769-
world: &mut World,
770-
) -> Box<dyn JsonBufferAccessState> {
771-
Box::new(SystemState::<BufferAccess<T>>::new(world))
762+
key: &JsonBufferKey,
763+
world: &'a World,
764+
) -> Result<JsonBufferView<'a>, BufferError> {
765+
let buffer_ref = world.get_entity(key.buffer).ok_or(BufferError::BufferMissing)?;
766+
let storage = buffer_ref.get::<BufferStorage<T>>().ok_or(BufferError::BufferMissing)?;
767+
let gate = buffer_ref.get::<GateState>().ok_or(BufferError::BufferMissing)?;
768+
Ok(JsonBufferView {
769+
storage: Box::new(storage),
770+
gate,
771+
session: key.session,
772+
})
772773
}
773774

774775
fn create_json_buffer_access_mut_state(
@@ -779,19 +780,6 @@ impl<T: 'static + Send + Sync + Serialize + DeserializeOwned> JsonBufferAccessIn
779780
}
780781
}
781782

782-
trait JsonBufferAccessState {
783-
fn get_json_buffer_access<'s, 'w: 's>(&'s mut self, world: &'w World) -> Box<dyn JsonBufferAccess<'w, 's> + 's>;
784-
}
785-
786-
impl<T> JsonBufferAccessState for SystemState<BufferAccess<'static, 'static, T>>
787-
where
788-
T: 'static + Send + Sync + Serialize + DeserializeOwned,
789-
{
790-
fn get_json_buffer_access<'s, 'w: 's>(&'s mut self, world: &'w World) -> Box<dyn JsonBufferAccess<'w, 's> + 's> {
791-
Box::new(self.get(world))
792-
}
793-
}
794-
795783
trait JsonBufferAccessMutState {
796784
fn get_json_buffer_access_mut<'s, 'w: 's>(&'s mut self, world: &'w mut World) -> Box<dyn JsonBufferAccessMut<'w, 's> + 's>;
797785
}
@@ -805,26 +793,6 @@ where
805793
}
806794
}
807795

808-
trait JsonBufferAccess<'w, 's> {
809-
fn as_json_buffer_view<'a>(&'a self, key: &JsonBufferKey) -> Result<JsonBufferView<'a>, BufferError>;
810-
}
811-
812-
impl<'w, 's, T> JsonBufferAccess<'w, 's> for BufferAccess<'w, 's, T>
813-
where
814-
T: 'static + Send + Sync + Serialize + DeserializeOwned,
815-
{
816-
fn as_json_buffer_view<'a>(&'a self, key: &JsonBufferKey) -> Result<JsonBufferView<'a>, BufferError> {
817-
let BufferAccess { query } = self;
818-
let (storage, gate) = query.get(key.buffer).map_err(|_| BufferError::BufferMissing)?;
819-
Ok(JsonBufferView {
820-
storage: Box::new(storage),
821-
gate,
822-
buffer: key.buffer,
823-
session: key.session,
824-
})
825-
}
826-
}
827-
828796
trait JsonBufferAccessMut<'w, 's> {
829797
fn as_json_buffer_mut<'a>(&'a mut self, key: &JsonBufferKey) -> Result<JsonBufferMut<'w, 's ,'a>, BufferError>;
830798
}
@@ -1022,9 +990,7 @@ mod tests {
1022990
In(key): In<JsonBufferKey>,
1023991
world: &mut World,
1024992
) -> usize {
1025-
world.json_buffer_view(&key, |access, _| {
1026-
access.len()
1027-
}).unwrap()
993+
world.json_buffer_view(&key).unwrap().len()
1028994
}
1029995

1030996
#[test]

0 commit comments

Comments
 (0)