makingthematrix / signals3

A lightweight event streaming library for Scala 3
GNU General Public License v3.0
13 stars 1 forks source link

Introduce `drop` and `take`, `FiniteSignal`, `FiniteStream`, and `ClosedSignal`, `ClosedStream` #6

Open makingthematrix opened 1 year ago

makingthematrix commented 1 year ago

This is going to be difficult, but probably very rewarding.

To make event streams and signals resemble standard collections even more, let's introduce the ability to drop events from the stream, and to close the stream after a certain number of events. For that I need two new concepts:

  1. An indexed event source - a trait that will keep track of the number of events emitted since the stream/signal creation.
  2. A closeable event source - a trait that, when mixed in with an event stream / signal, will tell the user if it's possible that the given stream / signal will still emit events.

Then, I can add two methods to the stream/signal classes:

  1. def drop[V](n: Int): Signal[V] with IndexedES (or just a subclass of Signal[V]) - a new signal with the original one as its parent, which will ignore n next events and start emitting events only after that.
  2. def take[V](n: Int): Signal[V] with CloseableES (or just a subclass of Signal[V]) - a new signal with the original one as its parent, which will emit only the next n events and close after that. A special case: take(0) will produce an empty signal (every const signal is closed).

There is a question how to mix the two and, in fact, how to mix it with other proxy signals. I think CloseableES can be a trait inherited from the very root - it's just that in many cases the signal is never closed (or always closed in the case of a const signal). drop can be a bit more tricky.

And then it will be in theory possible to split streams like this:

val stream: EventStream[E] = ...
stream match {
  case head :: tail => ...
}

where head is the already implemented Future[E] and tail will be stream.drop(1).

And:

stream match {
  case head@FiniteStream(3) ::: tail => ...
}

would mean that first three events of stream goes to the head stream, which then closes, and all the consecutive events go to tail.

makingthematrix commented 1 year ago

I'm taking it off from 1.1.0 because it will be big, and already the changes in 1.1.0 are huge. I need time to rethink this feature. 1.1.0 will go without it.