Skip to content

Commit 0d1224f

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

File tree

2 files changed

+154
-7
lines changed

2 files changed

+154
-7
lines changed

src/buffer/any_buffer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,11 @@ impl<'w, 's, 'a> Drop for AnyBufferMut<'w, 's, 'a> {
381381
/// This trait allows [`World`] to give you access to any buffer using an
382382
/// [`AnyBufferKey`].
383383
pub trait AnyBufferWorldAccess {
384+
385+
/// Call this to get mutable access to any buffer.
386+
///
387+
/// Pass in a callback that will receive a [`AnyBufferMut`], allowing it to
388+
/// view and modify the contents of the buffer.
384389
fn any_buffer_mut<U>(
385390
&mut self,
386391
key: &AnyBufferKey,

src/buffer/json_buffer.rs

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

3838
use crate::{
3939
AnyBufferAccessImpl, AnyBufferAccessInterface, AnyBuffer, AnyBufferKey,
40-
AnyRange, Buffer, BufferAccessors, BufferKey, BufferKeyBuilder, BufferAccessLifecycle,
41-
BufferAccessMut, BufferError, BufferStorage, Builder, DrainBuffer, OperationError,
42-
OperationResult, InspectBuffer, ManageBuffer, Gate, GateState,
43-
NotifyBufferUpdate, Bufferable, Buffered, OrBroken, Joined, Accessed,
44-
add_listener_to_source,
40+
AnyRange, Buffer, BufferAccessors, BufferAccess, BufferKey, BufferKeyBuilder,
41+
BufferAccessLifecycle, BufferAccessMut, BufferError, BufferStorage, Builder,
42+
DrainBuffer, OperationError, OperationResult, InspectBuffer, ManageBuffer,
43+
Gate, GateState, NotifyBufferUpdate, Bufferable, Buffered, OrBroken, Joined,
44+
Accessed, add_listener_to_source,
4545
};
4646

4747
/// A [`Buffer`] whose message type has been anonymized, but which is known to
@@ -171,6 +171,52 @@ impl From<JsonBufferKey> for AnyBufferKey {
171171
}
172172
}
173173

174+
/// Similar to [`BufferView`][crate::BufferView], but this can be unlocked with
175+
/// a [`JsonBufferKey`], so it can work for any buffer whose message types
176+
/// support serialization and deserialization.
177+
pub struct JsonBufferView<'a> {
178+
storage: Box<dyn JsonBufferViewing + 'a>,
179+
gate: &'a GateState,
180+
buffer: Entity,
181+
session: Entity,
182+
}
183+
184+
impl<'a> JsonBufferView<'a> {
185+
/// Get a serialized copy of the oldest message in the buffer.
186+
pub fn oldest(&self) -> JsonMessageViewResult {
187+
self.storage.json_oldest(self.session)
188+
}
189+
190+
/// Get a serialized copy of the newest message in the buffer.
191+
pub fn newest(&self) -> JsonMessageViewResult {
192+
self.storage.json_newest(self.session)
193+
}
194+
195+
/// Get a serialized copy of a message in the buffer.
196+
pub fn get(&self, index: usize) -> JsonMessageViewResult {
197+
self.storage.json_get(self.session, index)
198+
}
199+
200+
/// Get how many messages are in this buffer.
201+
pub fn len(&self) -> usize {
202+
self.storage.json_count(self.session)
203+
}
204+
205+
/// Check if the buffer is empty.
206+
pub fn is_empty(&self) -> bool {
207+
self.len() == 0
208+
}
209+
210+
/// Check whether the gate of this buffer is open or closed.
211+
pub fn gate(&self) -> Gate {
212+
self.gate
213+
.map
214+
.get(&self.session)
215+
.copied()
216+
.unwrap_or(Gate::Open)
217+
}
218+
}
219+
174220
/// Similar to [`BufferMut`][crate::BufferMut], but this can be unlocked with a
175221
/// [`JsonBufferKey`], so it can work for any buffer whose message types support
176222
/// serialization and deserialization.
@@ -184,7 +230,7 @@ pub struct JsonBufferMut<'w, 's, 'a> {
184230
modified: bool,
185231
}
186232

187-
impl<'w, 's, 'a> JsonBufferMut<'w, 's, 'a> {
233+
impl<'w, 's, 'a> JsonBufferMut<'w, 's, 'a> {
188234
/// Same as [BufferMut::allow_closed_loops][1].
189235
///
190236
/// [1]: crate::BufferMut::allow_closed_loops
@@ -363,6 +409,24 @@ impl<'w, 's, 'a> Drop for JsonBufferMut<'w, 's, 'a> {
363409
}
364410

365411
pub trait JsonBufferWorldAccess {
412+
/// Call this to get read-only access to any buffer whose message type is
413+
/// serializable and deserializable.
414+
///
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,
421+
key: &JsonBufferKey,
422+
f: impl FnOnce(JsonBufferView, &World) -> U,
423+
) -> Result<U, BufferError>;
424+
425+
/// Call this to get mutable access to any buffer whose message type is
426+
/// serializable and deserializable.
427+
///
428+
/// Pass in a callback that will receive a [`JsonBufferMut`], allowing it to
429+
/// view and modify the contents of the buffer.
366430
fn json_buffer_mut<U>(
367431
&mut self,
368432
key: &JsonBufferKey,
@@ -371,6 +435,18 @@ pub trait JsonBufferWorldAccess {
371435
}
372436

373437
impl JsonBufferWorldAccess for World {
438+
fn json_buffer_view<U>(
439+
&mut self,
440+
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))
448+
}
449+
374450
fn json_buffer_mut<U>(
375451
&mut self,
376452
key: &JsonBufferKey,
@@ -486,6 +562,27 @@ trait JsonBufferManagement: JsonBufferViewing {
486562
fn json_drain<'a>(&'a mut self, session: Entity, range: AnyRange) -> Box<dyn DrainJsonBufferInterface + 'a>;
487563
}
488564

565+
impl<T> JsonBufferViewing for &'_ BufferStorage<T>
566+
where
567+
T: 'static + Send + Sync + Serialize + DeserializeOwned,
568+
{
569+
fn json_count(&self, session: Entity) -> usize {
570+
self.count(session)
571+
}
572+
573+
fn json_oldest<'a>(&'a self, session: Entity) -> JsonMessageViewResult {
574+
self.oldest(session).map(serde_json::to_value).transpose()
575+
}
576+
577+
fn json_newest<'a>(&'a self, session: Entity) -> JsonMessageViewResult {
578+
self.newest(session).map(serde_json::to_value).transpose()
579+
}
580+
581+
fn json_get<'a>(&'a self, session: Entity, index: usize) ->JsonMessageViewResult {
582+
self.get(session, index).map(serde_json::to_value).transpose()
583+
}
584+
}
585+
489586
impl<T> JsonBufferViewing for Mut<'_, BufferStorage<T>>
490587
where
491588
T: 'static + Send + Sync + Serialize + DeserializeOwned,
@@ -598,6 +695,11 @@ trait JsonBufferAccessInterface {
598695
session: Entity,
599696
) -> Result<JsonMessage, OperationError>;
600697

698+
fn create_json_buffer_access_state(
699+
&self,
700+
world: &mut World,
701+
) -> Box<dyn JsonBufferAccessState>;
702+
601703
fn create_json_buffer_access_mut_state(
602704
&self,
603705
world: &mut World,
@@ -662,6 +764,13 @@ impl<T: 'static + Send + Sync + Serialize + DeserializeOwned> JsonBufferAccessIn
662764
serde_json::to_value(value).or_broken()
663765
}
664766

767+
fn create_json_buffer_access_state(
768+
&self,
769+
world: &mut World,
770+
) -> Box<dyn JsonBufferAccessState> {
771+
Box::new(SystemState::<BufferAccess<T>>::new(world))
772+
}
773+
665774
fn create_json_buffer_access_mut_state(
666775
&self,
667776
world: &mut World,
@@ -670,6 +779,19 @@ impl<T: 'static + Send + Sync + Serialize + DeserializeOwned> JsonBufferAccessIn
670779
}
671780
}
672781

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+
673795
trait JsonBufferAccessMutState {
674796
fn get_json_buffer_access_mut<'s, 'w: 's>(&'s mut self, world: &'w mut World) -> Box<dyn JsonBufferAccessMut<'w, 's> + 's>;
675797
}
@@ -683,6 +805,26 @@ where
683805
}
684806
}
685807

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+
686828
trait JsonBufferAccessMut<'w, 's> {
687829
fn as_json_buffer_mut<'a>(&'a mut self, key: &JsonBufferKey) -> Result<JsonBufferMut<'w, 's ,'a>, BufferError>;
688830
}
@@ -880,7 +1022,7 @@ mod tests {
8801022
In(key): In<JsonBufferKey>,
8811023
world: &mut World,
8821024
) -> usize {
883-
world.json_buffer_mut(&key, |access| {
1025+
world.json_buffer_view(&key, |access, _| {
8841026
access.len()
8851027
}).unwrap()
8861028
}

0 commit comments

Comments
 (0)