Skip to content

sonolus.script.stream

Stream

Bases: Record

Represents a stream.

Most users should use @streams to declare streams and stream groups rather than using this class directly.

If used directly, it is important that streams do not overlap. No other streams should have an offset in range(self.offset, self.offset + max(1, sizeof(self.element_type()))), or they will overlap and interfere with each other.

Usage

Declaring a stream:

@streams
class Streams:
    my_stream_1: Stream[Num]  # A stream of Num values
    my_stream_2: Stream[Vec2]  # A stream of Vec2 values

Directly creating a stream (advanced usage):

stream = Stream[Num](offset=0)

__contains__(item)

Check if the stream contains the key.

__getitem__(key)

Get the value corresponding to the key.

If the key is not in the stream, interpolates linearly between surrounding values. If the stream is empty, returns the zero value of the element type.

__setitem__(key, value)

Set the value corresponding to the key.

backing_size() classmethod

Return the number of underlying single-value streams backing this stream.

element_type() classmethod

Return the type of elements in this array type.

get_next(key)

Get the value corresponding to the next key.

If there is no next key, returns the value at the given key. Equivalent to self[self.next_key(key)].

get_next_inclusive(key)

Get the value corresponding to the next key, or the value at the given key if it is in the stream.

Equivalent to self[self.next_key_inclusive(key)].

get_previous(key)

Get the value corresponding to the previous key.

If there is no previous key, returns the value at the given key. Equivalent to self[self.previous_key(key)].

has_next_key(key)

Check if there is a next key after the given key in the stream.

has_previous_key(key)

Check if there is a previous key before the given key in the stream.

iter_items_from(start)

Iterate over the items in the stream in ascending order starting from the given key.

If the key is in the stream, it will be included in the iteration.

Usage:

stream = ...
for key, value in stream.iter_items_from(0):
    do_something(key, value)

iter_items_from_desc(start)

Iterate over the items in the stream in descending order starting from the given key.

If the key is in the stream, it will be included in the iteration.

Usage:

stream = ...
for key, value in stream.iter_items_from_desc(0):
    do_something(key, value)

iter_items_since_previous_frame()

Iterate over the items in the stream since the last frame.

This is a convenience method that iterates over the items in the stream occurring after the time of the previous frame and up to and including the current time.

Usage:

stream = ...
for key, value in stream.iter_items_since_previous_frame():
    do_something(key, value)

iter_keys_from(start)

Iterate over the keys in the stream in ascending order starting from the given key.

If the key is in the stream, it will be included in the iteration.

Usage:

stream = ...
for key in stream.iter_keys_from(0):
    do_something(key)

iter_keys_from_desc(start)

Iterate over the keys in the stream in descending order starting from the given key.

If the key is in the stream, it will be included in the iteration.

Usage:

stream = ...
for key in stream.iter_keys_from_desc(0):
    do_something(key)

iter_keys_since_previous_frame()

Iterate over the keys in the stream since the last frame.

This is a convenience method that iterates over the keys in the stream occurring after the time of the previous frame and up to and including the current time.

Usage:

stream = ...
for key in stream.iter_keys_since_previous_frame():
    do_something(key)

iter_values_from(start)

Iterate over the values in the stream in ascending order starting from the given key.

If the key is in the stream, it will be included in the iteration.

Usage:

stream = ...
for value in stream.iter_values_from(0):
    do_something(value)

iter_values_from_desc(start)

Iterate over the values in the stream in descending order starting from the given key.

If the key is in the stream, it will be included in the iteration.

Usage:

stream = ...
for value in stream.iter_values_from_desc(0):
    do_something(value)

iter_values_since_previous_frame()

Iterate over the values in the stream since the last frame.

This is a convenience method that iterates over the values in the stream occurring after the time of the previous frame and up to and including the current time.

Usage:

stream = ...
for value in stream.iter_values_since_previous_frame():
    do_something(value)

next_key(key)

Get the next key, or the key unchanged if it is the last key or the stream is empty.

If the key is in the stream and there is a next key, returns the next key.

next_key_inclusive(key)

Like next_key, but returns the key itself if it is in the stream.

next_key_or_default(key, default)

Get the next key, or the default value if there is no next key.

previous_key(key)

Get the previous key, or the key unchanged if it is the first key or the stream is empty.

If the key is in the stream and there is a previous key, returns the previous key.

previous_key_inclusive(key)

Like previous_key, but returns the key itself if it is in the stream.

previous_key_or_default(key, default)

Get the previous key, or the default value if there is no previous key.

StreamGroup

Bases: Record

Represents a group of streams.

Most users should use @streams to declare stream groups rather than using this class directly.

Usage

Declaring a stream group:

@streams
class Streams:
    my_group_1: StreamGroup[Num, 10]  # A group of 10 Num streams
    my_group_2: StreamGroup[Vec2, 5]  # A group of 5 Vec2 streams

__contains__(item)

Check if the group contains the stream with the given index.

__getitem__(index)

Get the stream at the given index.

backing_size() classmethod

Return the number of underlying single-value streams backing this stream.

element_type() classmethod

Return the type of elements in this group.

size() classmethod

Return the size of the group.

streams(cls)

Decorator to define streams and stream groups.

Streams and stream groups are declared by annotating class attributes with Stream or StreamGroup.

Other types are also supported in the form of data fields. They may be used to store additional data to export from Play to Watch mode.

In either case, data is write-only in Play mode and read-only in Watch mode.

This should only be used once in most projects, as multiple decorated classes will overlap with each other and interfere when both are used at the same time.

For backwards compatibility, new streams and stream groups should be added to the end of existing ones, and lengths and element types of existing streams and stream groups should not be changed. Otherwise, old replays may not work on new versions of the engine.

Usage
@streams
class Streams:
    stream_1: Stream[Num]  # A stream of Num values
    stream_2: Stream[Vec2]  # A stream of Vec2 values
    group_1: StreamGroup[Num, 10]  # A group of 10 Num streams
    group_2: StreamGroup[Vec2, 5]  # A group of 5 Vec2 streams

    data_field_1: Num  # A data field of type Num
    data_field_2: Vec2  # A data field of type Vec2