Skip to content

sonolus.script.containers

ArrayMap

Bases: Record

A map implemented as an array of key-value pairs with a fixed maximum capacity.

Usage
ArrayMap[K, V, Capacity].new()  # Create a new empty map

Examples:

map = ArrayMap[int, int, 10].new()
map[1] = 2
map[3] = 4
assert 1 in map
assert 2 not in map
assert map[3] == 4

__contains__(key: K) -> bool

Return whether the given key is present in the map.

Parameters:

Name Type Description Default
key K

The key to check for.

required

Returns:

Type Description
bool

True if the key is present, False otherwise.

__delitem__(key: K)

Remove the key-value pair associated with the given key.

Must be called with a key that is present in the map. If the key is not present, the current callback is terminated, even when runtime checks are disabled.

Parameters:

Name Type Description Default
key K

The key to remove.

required

__getitem__(key: K) -> V

Return the value associated with the given key.

Must be called with a key that is present in the map.

The returned value continues to be part of the map. Future modifications to the map will affect the returned value.

Note

Future modifications to the map may cause unexpected changes to the returned value. If the map may be modified in the future, it's recommended to make a copy of the value.

For example:

map = ArrayMap[int, Pair[int, int], 10].new()
map[1] = Pair(2, 3)
map[3] = Pair(4, 5)
map[5] = Pair(6, 7)
p = map[1]
map.pop(1)
# `p` may now read a different value: pop() swaps the last entry into the freed
# slot, so the storage `p` refers to no longer holds Pair(2, 3).

__iter__() -> SonolusIterator[K]

Return an iterator over the keys in the map.

__len__() -> int

Return the number of key-value pairs in the map.

__pos__() -> Self

Return a copy of the record.

__setitem__(key: K, value: V)

Associate the given key with the given value.

If the key is already present in the map, the value is updated, even if the map is full. Must not be called with a new key if the map is full.

Parameters:

Name Type Description Default
key K

The key to associate with the value.

required
value V

The value to associate with the key.

required

capacity() -> int classmethod

Return the maximum number of key-value pairs the map can hold.

clear()

Clear the map, removing all key-value pairs.

No behavior is guaranteed regarding the value of existing references to values in the map.

frozen(*args: P.args, **kwargs: P.kwargs) -> Self classmethod

Create a frozen record instance.

Numeric fields in the record will not be writable. However, nested values such as other records may remain mutable.

Parameters:

Name Type Description Default
*args P.args

Positional arguments for the record constructor.

()
**kwargs P.kwargs

Keyword arguments for the record constructor.

{}

Returns:

Type Description
Self

A frozen record instance.

is_full() -> bool

Return whether the map is full.

items() -> SonolusIterator[tuple[K, V]]

Return an iterator over the key-value pairs in the map.

keys() -> SonolusIterator[K]

Return an iterator over the keys in the map.

new() -> Self classmethod

Create a new empty map.

pop(key: K) -> V

Remove and return a copy of the value associated with the given key.

Must be called with a key that is present in the map. If the key is not present, the current callback is terminated, even when runtime checks are disabled.

Parameters:

Name Type Description Default
key K

The key to remove.

required

Returns:

Type Description
V

The value associated with the key.

type_var_value(var: TypeVar) -> Any classmethod

Return the value of a type variable.

Parameters:

Name Type Description Default
var TypeVar

The type variable to get the value of.

required

Returns:

Type Description
Any

The value of the type variable.

values() -> SonolusIterator[V]

Return an iterator over the values in the map.

ArrayPointer

Bases: Record, ArrayLike[T]

An array defined by a size and pointer to the first element.

Supports negative indexes.

This is intended to be created internally and improper use may result in hard to debug issues.

Usage
ArrayPointer[T](size: int, block: int, offset: int)

__contains__(value: Any) -> bool

Return whether any element in the array is equal to the given value.

Parameters:

Name Type Description Default
value Any

The value to check for.

required

__getitem__(item) -> T

Return the item at the given index, where a negative index counts from the end of the array.

__iter__() -> SonolusIterator[T]

Return an iterator over the array.

__len__() -> int

Return the number of elements in the array.

__pos__() -> Self

Return a copy of the record.

__reversed__()

Return a reversed view of the array.

__setitem__(key: int, value: T)

Set the value of the item at the given index.

Parameters:

Name Type Description Default
key int

The index of the item. A negative index counts from the end of the array.

required
value T

The value to set.

required

count(value: T) -> int

Return the number of elements in the array equal to the given value.

Parameters:

Name Type Description Default
value T

The value to count.

required

element_type() -> type[T] classmethod

Return the type of the elements in the array.

frozen(*args: P.args, **kwargs: P.kwargs) -> Self classmethod

Create a frozen record instance.

Numeric fields in the record will not be writable. However, nested values such as other records may remain mutable.

Parameters:

Name Type Description Default
*args P.args

Positional arguments for the record constructor.

()
**kwargs P.kwargs

Keyword arguments for the record constructor.

{}

Returns:

Type Description
Self

A frozen record instance.

get_unchecked(item: int) -> T

Get the element at the given index possibly without bounds checking or conversion of negative indexes.

The compiler may still determine that the index is out of bounds and throw an error, but it may skip these checks at runtime.

Parameters:

Name Type Description Default
item int

The index to get.

required

Returns:

Type Description
T

The element at the given index.

index(value: T, start: int = 0, stop: int | None = None) -> int

Return the index of the value in the array equal to the given value.

Parameters:

Name Type Description Default
value T

The value to search for.

required
start int

The index to start searching from.

0
stop int | None

The index to stop searching at. If None, search to the end of the array.

None

Returns:

Type Description
int

The index of the first matching occurrence, or -1 if the value is not found.

index_of_max(*, key: Callable[[T], Any] | None = None) -> int

Return the index of the maximum value in the array.

Parameters:

Name Type Description Default
key Callable[[T], Any] | None

A one-argument ordering function to use for comparison like the one used in max().

None

Returns:

Type Description
int

The index of the maximum value, or -1 if the array is empty.

index_of_min(*, key: Callable[[T], Any] | None = None) -> int

Return the index of the minimum value in the array.

Parameters:

Name Type Description Default
key Callable[[T], Any] | None

A one-argument ordering function to use for comparison like the one used in min().

None

Returns:

Type Description
int

The index of the minimum value, or -1 if the array is empty.

last_index(value: T) -> int

Return the last index of the value in the array equal to the given value.

Parameters:

Name Type Description Default
value T

The value to search for.

required

Returns:

Type Description
int

The index of the last matching occurrence, or -1 if the value is not found.

reverse()

Reverse the values in the array in place.

set_unchecked(key: int, value: T)

Set the element at the given index possibly without bounds checking or conversion of negative indexes.

The compiler may still determine that the index is out of bounds and throw an error, but it may skip these checks at runtime.

Parameters:

Name Type Description Default
key int

The index to set.

required
value T

The value to set.

required

shuffle()

Shuffle the values in the array in place.

sort(*, key: Callable[[T], Any] | None = None, reverse: bool = False)

Sort the values in the array in place.

Note

The sort is not guaranteed to be stable; the relative order of equal elements may not be preserved.

Parameters:

Name Type Description Default
key Callable[[T], Any] | None

A one-argument ordering function to use for comparison.

None
reverse bool

If True, sort in descending order, otherwise sort in ascending order.

False

swap(i: int, j: int)

Swap the values at the given positive indices.

Parameters:

Name Type Description Default
i int

The first index.

required
j int

The second index.

required

swap_unchecked(i: Num, j: Num)

Swap the values at the given indices possibly without bounds checking.

Parameters:

Name Type Description Default
i Num

The first index.

required
j Num

The second index.

required

type_var_value(var: TypeVar) -> Any classmethod

Return the value of a type variable.

Parameters:

Name Type Description Default
var TypeVar

The type variable to get the value of.

required

Returns:

Type Description
Any

The value of the type variable.

unchecked() -> ArrayLike[T]

Return a proxy object that may skip bounds checking and may not support negative indexes.

ArraySet

Bases: Record

A set implemented as an array with a fixed maximum capacity.

Usage
ArraySet[T, Capacity].new()  # Create a new empty set

Examples:

s = ArraySet[int, 10].new()
s.add(1)
s.add(2)
assert 1 in s
assert 3 not in s
s.remove(1)
assert 1 not in s

__contains__(value)

Return whether the given value is present in the set.

__iter__() -> SonolusIterator[T]

Return an iterator over the values in the set.

__len__()

Return the number of elements in the set.

__pos__() -> Self

Return a copy of the record.

add(value: T) -> bool

Add a copy of the given value to the set.

This has no effect and returns False if the value is already present or if the set is full.

Parameters:

Name Type Description Default
value T

The value to add.

required

Returns:

Type Description
bool

True if the value was added, False otherwise.

clear()

Clear the set, removing all elements.

frozen(*args: P.args, **kwargs: P.kwargs) -> Self classmethod

Create a frozen record instance.

Numeric fields in the record will not be writable. However, nested values such as other records may remain mutable.

Parameters:

Name Type Description Default
*args P.args

Positional arguments for the record constructor.

()
**kwargs P.kwargs

Keyword arguments for the record constructor.

{}

Returns:

Type Description
Self

A frozen record instance.

new() -> Self classmethod

Create a new empty set.

remove(value: T) -> bool

Remove the given value from the set.

This has no effect and returns False if the value is not present.

Parameters:

Name Type Description Default
value T

The value to remove.

required

Returns:

Type Description
bool

True if the value was removed, False otherwise.

type_var_value(var: TypeVar) -> Any classmethod

Return the value of a type variable.

Parameters:

Name Type Description Default
var TypeVar

The type variable to get the value of.

required

Returns:

Type Description
Any

The value of the type variable.

Box

Bases: Record

A box that contains a value.

This can be helpful for generic code that can handle both Num and non-Num types.

Usage
Box[T](value: T)

Examples:

box = Box(1)
box = Box[int](2)

x: T = ...
y: T = ...
box = Box(x)
box.value = y  # Works regardless of whether x is a Num, array, or record

value: T instance-attribute

The value contained in the box.

__pos__() -> Self

Return a copy of the record.

frozen(*args: P.args, **kwargs: P.kwargs) -> Self classmethod

Create a frozen record instance.

Numeric fields in the record will not be writable. However, nested values such as other records may remain mutable.

Parameters:

Name Type Description Default
*args P.args

Positional arguments for the record constructor.

()
**kwargs P.kwargs

Keyword arguments for the record constructor.

{}

Returns:

Type Description
Self

A frozen record instance.

type_var_value(var: TypeVar) -> Any classmethod

Return the value of a type variable.

Parameters:

Name Type Description Default
var TypeVar

The type variable to get the value of.

required

Returns:

Type Description
Any

The value of the type variable.

FrozenNumSet

Bases: Record

A fixed-size collection of numeric values, supporting membership testing with in.

Usage
FrozenNumSet.of(value_1, value_2, ...)  # Create a set from the given values

Examples:

s = FrozenNumSet.of(1, 2, 3)
assert 2 in s
assert 4 not in s

__contains__(value: Num) -> bool

Return whether the given value is present in the set.

__iter__() -> SonolusIterator[Num]

Return an iterator over the values in the set.

__len__() -> int

Return the number of values in the set.

__pos__() -> Self

Return a copy of the record.

frozen(*args: P.args, **kwargs: P.kwargs) -> Self classmethod

Create a frozen record instance.

Numeric fields in the record will not be writable. However, nested values such as other records may remain mutable.

Parameters:

Name Type Description Default
*args P.args

Positional arguments for the record constructor.

()
**kwargs P.kwargs

Keyword arguments for the record constructor.

{}

Returns:

Type Description
Self

A frozen record instance.

of(*values: Num) -> Self classmethod

Create a set containing the given values.

Duplicate values are kept rather than collapsed, so len and iteration report every value passed in. Membership testing is unaffected.

type_var_value(var: TypeVar) -> Any classmethod

Return the value of a type variable.

Parameters:

Name Type Description Default
var TypeVar

The type variable to get the value of.

required

Returns:

Type Description
Any

The value of the type variable.

Pair

Bases: Record

A generic pair of values.

Usage
Pair[T, U](first: T, second: U)

Examples:

pair = Pair(1, 2)
pair = Pair[int, Pair[int, int]](1, Pair(2, 3))

first: T instance-attribute

The first value.

second: U instance-attribute

The second value.

tuple: tuple[T, U] property

Return the pair as a tuple.

__ge__(other)

Return whether this pair is greater than or equal to the other, comparing first then second.

__gt__(other)

Return whether this pair is greater than the other, comparing first then second.

__le__(other)

Return whether this pair is less than or equal to the other, comparing first then second.

__lt__(other)

Return whether this pair is less than the other, comparing first then second.

__pos__() -> Self

Return a copy of the record.

frozen(*args: P.args, **kwargs: P.kwargs) -> Self classmethod

Create a frozen record instance.

Numeric fields in the record will not be writable. However, nested values such as other records may remain mutable.

Parameters:

Name Type Description Default
*args P.args

Positional arguments for the record constructor.

()
**kwargs P.kwargs

Keyword arguments for the record constructor.

{}

Returns:

Type Description
Self

A frozen record instance.

type_var_value(var: TypeVar) -> Any classmethod

Return the value of a type variable.

Parameters:

Name Type Description Default
var TypeVar

The type variable to get the value of.

required

Returns:

Type Description
Any

The value of the type variable.

VarArray

Bases: Record, ArrayLike[T]

An array with a variable size and fixed maximum capacity.

Supports negative indexes.

Usage
VarArray[T, Capacity].new()  # Create a new empty array

Examples:

array = VarArray[int, 10].new()
array.append(1)

__contains__(value: Any) -> bool

Return whether any element in the array is equal to the given value.

Parameters:

Name Type Description Default
value Any

The value to check for.

required

__delitem__(key: int)

Remove the element at the given index.

__getitem__(item) -> T

Return the element at the given index.

Supports negative indexes.

The returned value continues to be part of the array. Future modifications to the array will affect the returned value.

Note

Future modifications to the array may cause unexpected changes to the returned value. If the array may be modified in the future, it's recommended to make a copy of the value.

For example:

a = VarArray[Pair[int, int], 10].new()
a.append(Pair(1, 2))
a.append(Pair(3, 4))
a.append(Pair(5, 6))
p = a[1]
a.pop(0)  # Elements are shifted back
assert p == Pair(5, 6)  # The value of p has changed

__iadd__(other)

Append copies of the values in the given array to the end of the array.

__iter__() -> SonolusIterator[T]

Return an iterator over the array.

__len__() -> int

Return the number of elements in the array.

__pos__() -> Self

Return a copy of the record.

__reversed__()

Return a reversed view of the array.

__setitem__(key: int, value: T)

Update the element at the given index.

append(value: T)

Append a copy of the given value to the end of the array.

Must not be called if the array is full.

Parameters:

Name Type Description Default
value T

The value to append.

required

append_unchecked(value: T)

Append the given value to the end of the array without checking the capacity.

Use with caution as this may cause hard to debug issues if the array is full.

Parameters:

Name Type Description Default
value T

The value to append.

required

capacity() -> int classmethod

Return the maximum number of elements the array can hold.

clear()

Clear the array, removing all elements.

References to elements are not immediately changed, but future insertions may overwrite them.

count(value: T) -> int

Return the number of elements in the array equal to the given value.

Parameters:

Name Type Description Default
value T

The value to count.

required

extend(values: ArrayLike[T])

Append copies of the values in the given array to the end of the array.

Must not be called if there is not enough remaining capacity.

Parameters:

Name Type Description Default
values ArrayLike[T]

The values to append.

required

frozen(*args: P.args, **kwargs: P.kwargs) -> Self classmethod

Create a frozen record instance.

Numeric fields in the record will not be writable. However, nested values such as other records may remain mutable.

Parameters:

Name Type Description Default
*args P.args

Positional arguments for the record constructor.

()
**kwargs P.kwargs

Keyword arguments for the record constructor.

{}

Returns:

Type Description
Self

A frozen record instance.

get_unchecked(index: Num) -> T

Get the element at the given index possibly without bounds checking or conversion of negative indexes.

The compiler may still determine that the index is out of bounds and throw an error, but it may skip these checks at runtime.

Parameters:

Name Type Description Default
index Num

The index to get.

required

Returns:

Type Description
T

The element at the given index.

index(value: T, start: int = 0, stop: int | None = None) -> int

Return the index of the value in the array equal to the given value.

Parameters:

Name Type Description Default
value T

The value to search for.

required
start int

The index to start searching from.

0
stop int | None

The index to stop searching at. If None, search to the end of the array.

None

Returns:

Type Description
int

The index of the first matching occurrence, or -1 if the value is not found.

index_of_max(*, key: Callable[[T], Any] | None = None) -> int

Return the index of the maximum value in the array.

Parameters:

Name Type Description Default
key Callable[[T], Any] | None

A one-argument ordering function to use for comparison like the one used in max().

None

Returns:

Type Description
int

The index of the maximum value, or -1 if the array is empty.

index_of_min(*, key: Callable[[T], Any] | None = None) -> int

Return the index of the minimum value in the array.

Parameters:

Name Type Description Default
key Callable[[T], Any] | None

A one-argument ordering function to use for comparison like the one used in min().

None

Returns:

Type Description
int

The index of the minimum value, or -1 if the array is empty.

insert(index: int, value: T)

Insert a copy of the given value at the given index.

Preserves the relative order of the elements.

Must not be called if the array is full.

Parameters:

Name Type Description Default
index int

The index at which to insert the value. Must be in the range [0, size].

required
value T

The value to insert.

required

is_full() -> bool

Return whether the array is full.

last_index(value: T) -> int

Return the last index of the value in the array equal to the given value.

Parameters:

Name Type Description Default
value T

The value to search for.

required

Returns:

Type Description
int

The index of the last matching occurrence, or -1 if the value is not found.

new() -> Self classmethod

Create a new empty array.

pop(index: int | None = None) -> T

Remove and return a copy of the value at the given index.

Preserves the relative order of the elements.

Parameters:

Name Type Description Default
index int | None

The index of the value to remove. If None, the last element is removed.

None

remove(value: T) -> bool

Remove the first occurrence of the given value, returning whether the value was removed.

Preserves the relative order of the elements.

Parameters:

Name Type Description Default
value T

The value to remove.

required

Returns:

Type Description
bool

True if the value was removed, False otherwise.

reverse()

Reverse the values in the array in place.

set_add(value: T) -> bool

Add a copy of the given value if it is not already present, returning whether the value was added.

If the value is already present, the array is not modified. If the array is full, the value is not added.

Parameters:

Name Type Description Default
value T

The value to add.

required

Returns:

Type Description
bool

True if the value was added, False otherwise.

set_remove(value: T) -> bool

Remove the first occurrence of the given value, returning whether the value was removed.

Does not preserve the relative order of the elements.

Parameters:

Name Type Description Default
value T

The value to remove.

required

Returns:

Type Description
bool

True if the value was removed, False otherwise.

set_unchecked(index: Num, value: T)

Set the element at the given index possibly without bounds checking or conversion of negative indexes.

The compiler may still determine that the index is out of bounds and throw an error, but it may skip these checks at runtime.

Parameters:

Name Type Description Default
index Num

The index to set.

required
value T

The value to set.

required

shuffle()

Shuffle the values in the array in place.

sort(*, key: Callable[[T], Any] | None = None, reverse: bool = False)

Sort the values in the array in place.

Note

The sort is not guaranteed to be stable; the relative order of equal elements may not be preserved.

Parameters:

Name Type Description Default
key Callable[[T], Any] | None

A one-argument ordering function to use for comparison.

None
reverse bool

If True, sort in descending order, otherwise sort in ascending order.

False

swap(i: int, j: int)

Swap the values at the given positive indices.

Parameters:

Name Type Description Default
i int

The first index.

required
j int

The second index.

required

swap_unchecked(i: Num, j: Num)

Swap the values at the given indices possibly without bounds checking.

Parameters:

Name Type Description Default
i Num

The first index.

required
j Num

The second index.

required

type_var_value(var: TypeVar) -> Any classmethod

Return the value of a type variable.

Parameters:

Name Type Description Default
var TypeVar

The type variable to get the value of.

required

Returns:

Type Description
Any

The value of the type variable.

unchecked() -> ArrayLike[T]

Return a proxy object that may skip bounds checking and may not support negative indexes.

sort_linked_entities(head_ref: EntityRef[T], /, *, get_value: Callable[[T], Any], get_next_ref: Callable[[T], EntityRef[T]], get_prev_ref: Callable[[T], EntityRef[T]] | None = None) -> EntityRef[T]

Sort a linked list of entities using merge sort.

If get_prev_ref is provided, the backward links will be updated as well.

Usage
class MyArchetype(PlayArchetype):
    sort_key: int
    next: EntityRef[MyArchetype]

def sort_my_archetype(head: EntityRef[MyArchetype]) -> EntityRef[MyArchetype]:
    return sort_linked_entities(
        head,
        get_value=lambda e: e.sort_key,
        get_next_ref=lambda e: e.next,
    )

Parameters:

Name Type Description Default
head_ref EntityRef[T]

A reference to the head of the linked list.

required
get_value Callable[[T], Any]

A function that takes an entity and returns the value to sort by.

required
get_next_ref Callable[[T], EntityRef[T]]

A function that takes an entity and returns a reference to the next entity.

required
get_prev_ref Callable[[T], EntityRef[T]] | None

An optional function that takes an entity and returns a reference to the previous entity.

None

Returns:

Type Description
EntityRef[T]

A reference to the head of the sorted linked list.