laminar/infrastructure/
arranging.rs

1//! This module is about arranging items, over different streams, based on an certain algorithm.
2//!
3//! The above sentence contains a lot of important information, lets zoom in at the above sentence.
4//!
5//! ## Items
6//!
7//! By items, you can understand 'packets' and 'arranging' can be done based either with sequencing or ordering.
8//!
9//! ## Ordering VS Sequencing
10//! Let's define two concepts here:
11//! _"Sequencing: this is the process of only caring about the newest items."_ [1](https://dictionary.cambridge.org/dictionary/english/sequencing)
12//! _"Ordering: this is the process of putting something in a particular order."_ [2](https://dictionary.cambridge.org/dictionary/english/ordering)
13//!
14//! - Sequencing: Only the newest items will be passed trough e.g. `1,3,2,5,4` which results in `1,3,5`.
15//! - Ordering: All items are returned in order `1,3,2,5,4` which results in `1,2,3,4,5`.
16//!
17//! ## Arranging Streams
18//! What are these 'arranging streams'?
19//! You can see 'arranging streams' as something to arrange items that have no relationship at all with one another.
20//!
21//! ## Simple Example
22//! Think of a highway where you have several lanes where cars are driving.
23//! Because there are these lanes, cars can move on faster.
24//! For example, the cargo drivers drive on the right and the high-speed cars on the left.
25//! The cargo drivers have no influence on fast cars and vice versa.
26//!
27//! ## Real Example
28//! If a game developer wants to send data to a client, it may be that he wants to send data ordered, unordered or sequenced.
29//! Data might be the following:
30//! 1. Player movement, we want to order player movements because we don't care about old positions.
31//! 2. Bullet movement, we want to order bullet movement because we don't care about old positions of bullets.
32//! 3. Chat messages, we want to order chat messages because it is nice to see the text in the right order.
33//!
34//! Player movement and chat messages are totally unrelated to each other and you absolutely do not want that movement packets are interrupted when a chat message is not sent.
35//! With ordering, we can only return items when all packets up to the current package are received.
36//!
37//! So if a chat package is missing, the other packages will suffer from it.
38//! It would be nice if we could order player movements and chat messages separately. This is exactly what `ordering streams` are meant for.
39//! The game developer can indicate on which stream he can order his packets and how he wants to arrange them.
40//! For example, the game developer can say: "Let me set all chat messages to 'stream 1' and all motion packets to 'stream 2'.
41
42pub use self::ordering::{IterMut, OrderingStream, OrderingSystem};
43pub use self::sequencing::{SequencingStream, SequencingSystem};
44
45mod ordering;
46mod sequencing;
47
48/// A trait which can be implemented for arranging operations.
49pub trait Arranging {
50    type ArrangingItem;
51
52    /// Arrange the given item based on the given index.
53    /// If the `incoming_offset` somehow does not satisfies the arranging algorithm it returns `None`.
54    /// If the `incoming_offset` satisfies the arranging algorithm it returns `Some` with the passed item.
55    fn arrange(
56        &mut self,
57        incoming_index: u16,
58        item: Self::ArrangingItem,
59    ) -> Option<Self::ArrangingItem>;
60}
61
62/// An arranging system that has multiple streams on which you can arrange items.
63pub trait ArrangingSystem {
64    /// The type of stream that is used for arranging items.
65    type Stream;
66
67    /// Returns the number of streams currently created.
68    fn stream_count(&self) -> usize;
69    /// Try to get a `Stream` by `stream_id`. When the stream does not exist, it will be inserted by the given `stream_id` and returned.
70    fn get_or_create_stream(&mut self, stream_id: u8) -> &mut Self::Stream;
71}