Skip to content

_Event

Bases: abc.ABC

Abstract base class representing an event.

Source code in pyflp/_event.py
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
class _Event(abc.ABC):
    """Abstract base class representing an event."""

    @property
    @abc.abstractmethod
    def size(self) -> int:
        """Raw event size in bytes."""

    @property
    def index(self) -> int:
        """Zero based index of instance w.r.t factory."""
        return self._index

    @property
    def data(self) -> bytes:
        return self._data

    @abc.abstractmethod
    def dump(self, new_data: Any) -> None:
        """Converts Python types into bytes objects and stores it."""

    def to_raw(self) -> bytes:
        """Used by Project.save(). Overriden by `_VariabledSizedEvent`."""
        return int.to_bytes(self.id_, 1, "little") + self.data

    def __repr__(self) -> str:
        cls = type(self).__name__
        sid = str(self.id_)
        iid = int(self.id_)
        if isinstance(self.id_, enum.IntEnum):
            return f"{cls!r} id={sid!r}, {iid!r}"
        return f"{cls!r} id={iid!r}"

    def __eq__(self, o: object) -> bool:
        if not isinstance(o, type(self)):
            raise TypeError(
                f"Cannot compare equality between an 'Event' and {type(o)!r}"
            )
        return self.id_ == o.id_ and self.data == o.data

    def __ne__(self, o: object) -> bool:
        if not isinstance(o, type(self)):
            raise TypeError(
                f"Cannot compare inequality between an 'Event' and {type(o)!r}"
            )
        return self.id_ != o.id_ or self.data != o.data

    def __init__(self, index: int, id: EventIDType, data: bytes) -> None:
        """
        Args:
            id (EventID): An event ID from **0** to **255**.
            data (bytes): A `bytes` object.
        """
        self.id_ = id
        self._data = data
        self._index = index
        super().__init__()

id_ = id instance-attribute

__eq__(o)

Source code in pyflp/_event.py
61
62
63
64
65
66
def __eq__(self, o: object) -> bool:
    if not isinstance(o, type(self)):
        raise TypeError(
            f"Cannot compare equality between an 'Event' and {type(o)!r}"
        )
    return self.id_ == o.id_ and self.data == o.data

__init__(index, id, data)

Parameters:

Name Type Description Default
id EventID

An event ID from 0 to 255.

required
data bytes

A bytes object.

required
Source code in pyflp/_event.py
75
76
77
78
79
80
81
82
83
84
def __init__(self, index: int, id: EventIDType, data: bytes) -> None:
    """
    Args:
        id (EventID): An event ID from **0** to **255**.
        data (bytes): A `bytes` object.
    """
    self.id_ = id
    self._data = data
    self._index = index
    super().__init__()

__ne__(o)

Source code in pyflp/_event.py
68
69
70
71
72
73
def __ne__(self, o: object) -> bool:
    if not isinstance(o, type(self)):
        raise TypeError(
            f"Cannot compare inequality between an 'Event' and {type(o)!r}"
        )
    return self.id_ != o.id_ or self.data != o.data

__repr__()

Source code in pyflp/_event.py
53
54
55
56
57
58
59
def __repr__(self) -> str:
    cls = type(self).__name__
    sid = str(self.id_)
    iid = int(self.id_)
    if isinstance(self.id_, enum.IntEnum):
        return f"{cls!r} id={sid!r}, {iid!r}"
    return f"{cls!r} id={iid!r}"

data() property

Source code in pyflp/_event.py
41
42
43
@property
def data(self) -> bytes:
    return self._data

dump(new_data) abstractmethod

Converts Python types into bytes objects and stores it.

Source code in pyflp/_event.py
45
46
47
@abc.abstractmethod
def dump(self, new_data: Any) -> None:
    """Converts Python types into bytes objects and stores it."""

index() property

Zero based index of instance w.r.t factory.

Source code in pyflp/_event.py
36
37
38
39
@property
def index(self) -> int:
    """Zero based index of instance w.r.t factory."""
    return self._index

size() property abstractmethod

Raw event size in bytes.

Source code in pyflp/_event.py
31
32
33
34
@property
@abc.abstractmethod
def size(self) -> int:
    """Raw event size in bytes."""

to_raw()

Used by Project.save(). Overriden by _VariabledSizedEvent.

Source code in pyflp/_event.py
49
50
51
def to_raw(self) -> bytes:
    """Used by Project.save(). Overriden by `_VariabledSizedEvent`."""
    return int.to_bytes(self.id_, 1, "little") + self.data

ByteEvent

Bases: _Event

Represents a byte-sized event.

Source code in pyflp/_event.py
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
class _ByteEvent(_Event):
    """Represents a byte-sized event."""

    @property
    def size(self) -> int:
        return 2

    def dump(self, new_data: Union[bytes, int, bool]) -> None:
        """Dumps a single byte of data; either a bool, int or a bytes object to event data.

        Args:
            new_data (Union[bytes, int, bool]): The data to be dumped into the event.

        Raises:
            ValueError: If `new_data` is a bytes object and its size isn't equal to 1.
            OverflowError: When an integer is too big to be accumulated in 1 byte.
            TypeError: When `new_data` isn't a bool, int or a bytes object.
        """

        if isinstance(new_data, bool):
            data = 1 if new_data else 0
            self._data = data.to_bytes(1, "little")
        elif isinstance(new_data, bytes):
            if len(new_data) != 1:
                raise ValueError(
                    f"Expected a bytes object of 1 byte length; got {new_data!r}"
                )
            self._data = new_data
        elif isinstance(new_data, int):
            if new_data != abs(new_data) and new_data not in range(-128, 128):
                raise OverflowError(
                    f"Expected a value of -128 to 127; got {new_data!r}"
                )
            elif new_data > 255:
                raise OverflowError(f"Expected a value from 0 to 255; got {new_data!r}")
            self._data = new_data.to_bytes(1, "little")
        else:
            raise TypeError(
                f"Expected a bytes, bool or an int object; got {type(new_data)!r}"
            )

    def to_uint8(self) -> int:
        return Byte.unpack(self.data)[0]

    def to_int8(self) -> int:
        return SByte.unpack(self.data)[0]

    def to_bool(self) -> bool:
        return self.to_int8() != 0

    def __repr__(self) -> str:
        i8 = self.to_int8()
        u8 = self.to_uint8()
        if i8 == u8:
            msg = f"B={u8!r}"
        else:
            msg = f"b={i8!r}, B={u8!r}"
        return f"<{super().__repr__()!r}, {msg!r}>"

    def __init__(self, index: int, id: EventIDType, data: bytes):
        """
        Args:
            id (EventID): An event ID from **0** to **63**.
            data (bytes): A 1 byte sized `bytes` object.

        Raises:
            ValueError: When `id` is not in range of 0-63.
            TypeError: When size of `data` is not 1.
        """
        if not (id < WORD and id >= BYTE):
            raise ValueError(f"Exepcted 0-63; got {id!r}")
        dl = len(data)
        if dl != 1:
            raise TypeError(f"Unexpected data size; expected 1, got {dl!r}")
        super().__init__(index, id, data)

__init__(index, id, data)

Parameters:

Name Type Description Default
id EventID

An event ID from 0 to 63.

required
data bytes

A 1 byte sized bytes object.

required

Raises:

Type Description
ValueError

When id is not in range of 0-63.

TypeError

When size of data is not 1.

Source code in pyflp/_event.py
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
def __init__(self, index: int, id: EventIDType, data: bytes):
    """
    Args:
        id (EventID): An event ID from **0** to **63**.
        data (bytes): A 1 byte sized `bytes` object.

    Raises:
        ValueError: When `id` is not in range of 0-63.
        TypeError: When size of `data` is not 1.
    """
    if not (id < WORD and id >= BYTE):
        raise ValueError(f"Exepcted 0-63; got {id!r}")
    dl = len(data)
    if dl != 1:
        raise TypeError(f"Unexpected data size; expected 1, got {dl!r}")
    super().__init__(index, id, data)

__repr__()

Source code in pyflp/_event.py
160
161
162
163
164
165
166
167
def __repr__(self) -> str:
    i8 = self.to_int8()
    u8 = self.to_uint8()
    if i8 == u8:
        msg = f"B={u8!r}"
    else:
        msg = f"b={i8!r}, B={u8!r}"
    return f"<{super().__repr__()!r}, {msg!r}>"

dump(new_data)

Dumps a single byte of data; either a bool, int or a bytes object to event data.

Parameters:

Name Type Description Default
new_data Union[bytes, int, bool]

The data to be dumped into the event.

required

Raises:

Type Description
ValueError

If new_data is a bytes object and its size isn't equal to 1.

OverflowError

When an integer is too big to be accumulated in 1 byte.

TypeError

When new_data isn't a bool, int or a bytes object.

Source code in pyflp/_event.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
def dump(self, new_data: Union[bytes, int, bool]) -> None:
    """Dumps a single byte of data; either a bool, int or a bytes object to event data.

    Args:
        new_data (Union[bytes, int, bool]): The data to be dumped into the event.

    Raises:
        ValueError: If `new_data` is a bytes object and its size isn't equal to 1.
        OverflowError: When an integer is too big to be accumulated in 1 byte.
        TypeError: When `new_data` isn't a bool, int or a bytes object.
    """

    if isinstance(new_data, bool):
        data = 1 if new_data else 0
        self._data = data.to_bytes(1, "little")
    elif isinstance(new_data, bytes):
        if len(new_data) != 1:
            raise ValueError(
                f"Expected a bytes object of 1 byte length; got {new_data!r}"
            )
        self._data = new_data
    elif isinstance(new_data, int):
        if new_data != abs(new_data) and new_data not in range(-128, 128):
            raise OverflowError(
                f"Expected a value of -128 to 127; got {new_data!r}"
            )
        elif new_data > 255:
            raise OverflowError(f"Expected a value from 0 to 255; got {new_data!r}")
        self._data = new_data.to_bytes(1, "little")
    else:
        raise TypeError(
            f"Expected a bytes, bool or an int object; got {type(new_data)!r}"
        )

size() property

Source code in pyflp/_event.py
113
114
115
@property
def size(self) -> int:
    return 2

to_bool()

Source code in pyflp/_event.py
157
158
def to_bool(self) -> bool:
    return self.to_int8() != 0

to_int8()

Source code in pyflp/_event.py
154
155
def to_int8(self) -> int:
    return SByte.unpack(self.data)[0]

to_uint8()

Source code in pyflp/_event.py
151
152
def to_uint8(self) -> int:
    return Byte.unpack(self.data)[0]

_WordEvent

Bases: _Event

Represents a 2 byte event.

Source code in pyflp/_event.py
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
class _WordEvent(_Event):
    """Represents a 2 byte event."""

    @property
    def size(self) -> int:
        return 3

    def dump(self, new_data: Union[bytes, int]) -> None:
        """Dumps 2 bytes of data; either an int or a bytes object to event data.

        Args:
            new_data (Union[bytes, int]): The data to be dumped into the event.

        Raises:
            ValueError: If `new_data` is a bytes object and its size isn't 2.
            OverflowError: When `new_data` cannot be accumulated in 2 bytes.
            TypeError: When `new_data` isn't an int or a bytes object.
        """
        word = new_data
        if isinstance(word, bytes):
            if len(word) != 2:
                raise ValueError(
                    f"Expected a bytes object of 2 bytes length; got {word!r}"
                )
            self._data = word
        elif isinstance(word, int):
            if word != abs(word) and word not in range(-32768, 32768):
                raise OverflowError(f"Expected a value -32768 to 32767; got {word!r}")
            elif word > 65535:
                raise OverflowError(f"Expected a value of 0 to 65535; got {word!r}")
            self._data = word.to_bytes(2, "little")
        else:
            raise TypeError(f"Expected a bytes or an int object; got {type(word)!r}")

    def to_uint16(self) -> int:
        return int.from_bytes(self.data, "little")

    def to_int16(self) -> int:
        return int.from_bytes(self.data, "little", signed=True)

    def __repr__(self) -> str:
        h = self.to_int16()
        H = self.to_uint16()  # noqa
        if h == H:
            msg = f"H={H!r}"
        else:
            msg = f"h={h!r}, H={H!r}"
        return f"<{super().__repr__()!r}, {msg!r}>"

    def __init__(self, index: int, id: EventIDType, data: bytes) -> None:
        """
        Args:
            id (EventID): An event ID from **64** to **127**.
            data (bytes): A `bytes` object of size 2.

        Raises:
            ValueError: When `id` is not in range of 64-127.
            TypeError: When size of `data` is not 2.
        """
        if id not in range(WORD, DWORD):
            raise ValueError(f"Exepcted 64-127; got {id!r}")
        if len(data) != 2:
            raise TypeError(
                f"Expected a data of 2 bytes; got a data of size {len(data)!r} instead"
            )
        super().__init__(index, id, data)

__init__(index, id, data)

Parameters:

Name Type Description Default
id EventID

An event ID from 64 to 127.

required
data bytes

A bytes object of size 2.

required

Raises:

Type Description
ValueError

When id is not in range of 64-127.

TypeError

When size of data is not 2.

Source code in pyflp/_event.py
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
def __init__(self, index: int, id: EventIDType, data: bytes) -> None:
    """
    Args:
        id (EventID): An event ID from **64** to **127**.
        data (bytes): A `bytes` object of size 2.

    Raises:
        ValueError: When `id` is not in range of 64-127.
        TypeError: When size of `data` is not 2.
    """
    if id not in range(WORD, DWORD):
        raise ValueError(f"Exepcted 64-127; got {id!r}")
    if len(data) != 2:
        raise TypeError(
            f"Expected a data of 2 bytes; got a data of size {len(data)!r} instead"
        )
    super().__init__(index, id, data)

__repr__()

Source code in pyflp/_event.py
227
228
229
230
231
232
233
234
def __repr__(self) -> str:
    h = self.to_int16()
    H = self.to_uint16()  # noqa
    if h == H:
        msg = f"H={H!r}"
    else:
        msg = f"h={h!r}, H={H!r}"
    return f"<{super().__repr__()!r}, {msg!r}>"

dump(new_data)

Dumps 2 bytes of data; either an int or a bytes object to event data.

Parameters:

Name Type Description Default
new_data Union[bytes, int]

The data to be dumped into the event.

required

Raises:

Type Description
ValueError

If new_data is a bytes object and its size isn't 2.

OverflowError

When new_data cannot be accumulated in 2 bytes.

TypeError

When new_data isn't an int or a bytes object.

Source code in pyflp/_event.py
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
def dump(self, new_data: Union[bytes, int]) -> None:
    """Dumps 2 bytes of data; either an int or a bytes object to event data.

    Args:
        new_data (Union[bytes, int]): The data to be dumped into the event.

    Raises:
        ValueError: If `new_data` is a bytes object and its size isn't 2.
        OverflowError: When `new_data` cannot be accumulated in 2 bytes.
        TypeError: When `new_data` isn't an int or a bytes object.
    """
    word = new_data
    if isinstance(word, bytes):
        if len(word) != 2:
            raise ValueError(
                f"Expected a bytes object of 2 bytes length; got {word!r}"
            )
        self._data = word
    elif isinstance(word, int):
        if word != abs(word) and word not in range(-32768, 32768):
            raise OverflowError(f"Expected a value -32768 to 32767; got {word!r}")
        elif word > 65535:
            raise OverflowError(f"Expected a value of 0 to 65535; got {word!r}")
        self._data = word.to_bytes(2, "little")
    else:
        raise TypeError(f"Expected a bytes or an int object; got {type(word)!r}")

size() property

Source code in pyflp/_event.py
190
191
192
@property
def size(self) -> int:
    return 3

to_int16()

Source code in pyflp/_event.py
224
225
def to_int16(self) -> int:
    return int.from_bytes(self.data, "little", signed=True)

to_uint16()

Source code in pyflp/_event.py
221
222
def to_uint16(self) -> int:
    return int.from_bytes(self.data, "little")

_DWordEvent

Bases: _Event

Represents a 4 byte event.

Source code in pyflp/_event.py
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
class _DWordEvent(_Event):
    """Represents a 4 byte event."""

    DWORD_MAX = 4_294_967_295
    INT_MIN = -2_147_483_648
    INT_MAX = 2_147_483_647

    @property
    def size(self) -> int:
        return 5

    def dump(self, new_data: Union[bytes, int]) -> None:
        """Dumps 4 bytes of data; either an int or a bytes object to event data.

        Args:
            new_data (Union[bytes, int]): The data to be dumped into the event.

        Raises:
            ValueError: If `new_data` is a bytes object and its size isn't 4.
            OverflowError: When an integer is too big to be accumulated in 4 bytes.
            TypeError: When `new_data` isn't an int or a bytes object.
        """

        dword = new_data
        if isinstance(dword, bytes):
            if len(dword) != 4:
                raise ValueError(
                    f"Expected a bytes object of 4 bytes length; got {dword!r}"
                )
            self._data = dword
        elif isinstance(dword, int):
            if dword != abs(dword) and dword not in range(
                self.INT_MIN, self.INT_MAX + 1
            ):
                raise OverflowError(
                    f"Expected a value of {self.INT_MIN!r} "
                    f"to {self.INT_MAX!r}; got {dword!r}"
                )
            elif dword > self.DWORD_MAX:
                raise OverflowError(
                    f"Expected a value of 0 to {self.DWORD_MAX!r}; got {dword!r}"
                )
            self._data = dword.to_bytes(4, "little")
        else:
            raise TypeError(f"Expected a bytes or an int object; got {type(dword)!r}")

    def to_uint32(self) -> int:
        """Deserializes `self.data` as a 32-bit unsigned integer as an `int`."""
        return UInt.unpack(self.data)[0]

    def to_int32(self) -> int:
        """Deserializes `self.data` as a 32-bit signed integer as an `int`."""
        return Int.unpack(self.data)[0]

    def __repr__(self) -> str:
        i32 = self.to_int32()
        u32 = self.to_uint32()
        if i32 == u32:
            msg = f"I={u32!r}"
        else:
            msg = f"i={i32!r}, I={u32!r}"
        return f"<{super().__repr__()!r}, {msg!r}>"

    def __init__(self, index: int, id: EventIDType, data: bytes) -> None:
        """
        Args:
            id (EventID): An event ID from **128** to **191**.
            data (bytes): A `bytes` object of size 4.

        Raises:
            ValueError: When `id` is not in range of 128-191.
            TypeError: When size of `data` is not 4.
        """
        if id not in range(DWORD, TEXT):
            raise ValueError(f"Exepcted 128-191; got {id!r}")
        dl = len(data)
        if dl != 4:
            raise TypeError(f"Unexpected data size; expected 4, got {dl!r}")
        super().__init__(index, id, data)

DWORD_MAX = 4294967295 class-attribute

INT_MAX = 2147483647 class-attribute

INT_MIN = -2147483648 class-attribute

__init__(index, id, data)

Parameters:

Name Type Description Default
id EventID

An event ID from 128 to 191.

required
data bytes

A bytes object of size 4.

required

Raises:

Type Description
ValueError

When id is not in range of 128-191.

TypeError

When size of data is not 4.

Source code in pyflp/_event.py
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
def __init__(self, index: int, id: EventIDType, data: bytes) -> None:
    """
    Args:
        id (EventID): An event ID from **128** to **191**.
        data (bytes): A `bytes` object of size 4.

    Raises:
        ValueError: When `id` is not in range of 128-191.
        TypeError: When size of `data` is not 4.
    """
    if id not in range(DWORD, TEXT):
        raise ValueError(f"Exepcted 128-191; got {id!r}")
    dl = len(data)
    if dl != 4:
        raise TypeError(f"Unexpected data size; expected 4, got {dl!r}")
    super().__init__(index, id, data)

__repr__()

Source code in pyflp/_event.py
309
310
311
312
313
314
315
316
def __repr__(self) -> str:
    i32 = self.to_int32()
    u32 = self.to_uint32()
    if i32 == u32:
        msg = f"I={u32!r}"
    else:
        msg = f"i={i32!r}, I={u32!r}"
    return f"<{super().__repr__()!r}, {msg!r}>"

dump(new_data)

Dumps 4 bytes of data; either an int or a bytes object to event data.

Parameters:

Name Type Description Default
new_data Union[bytes, int]

The data to be dumped into the event.

required

Raises:

Type Description
ValueError

If new_data is a bytes object and its size isn't 4.

OverflowError

When an integer is too big to be accumulated in 4 bytes.

TypeError

When new_data isn't an int or a bytes object.

Source code in pyflp/_event.py
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
def dump(self, new_data: Union[bytes, int]) -> None:
    """Dumps 4 bytes of data; either an int or a bytes object to event data.

    Args:
        new_data (Union[bytes, int]): The data to be dumped into the event.

    Raises:
        ValueError: If `new_data` is a bytes object and its size isn't 4.
        OverflowError: When an integer is too big to be accumulated in 4 bytes.
        TypeError: When `new_data` isn't an int or a bytes object.
    """

    dword = new_data
    if isinstance(dword, bytes):
        if len(dword) != 4:
            raise ValueError(
                f"Expected a bytes object of 4 bytes length; got {dword!r}"
            )
        self._data = dword
    elif isinstance(dword, int):
        if dword != abs(dword) and dword not in range(
            self.INT_MIN, self.INT_MAX + 1
        ):
            raise OverflowError(
                f"Expected a value of {self.INT_MIN!r} "
                f"to {self.INT_MAX!r}; got {dword!r}"
            )
        elif dword > self.DWORD_MAX:
            raise OverflowError(
                f"Expected a value of 0 to {self.DWORD_MAX!r}; got {dword!r}"
            )
        self._data = dword.to_bytes(4, "little")
    else:
        raise TypeError(f"Expected a bytes or an int object; got {type(dword)!r}")

size() property

Source code in pyflp/_event.py
262
263
264
@property
def size(self) -> int:
    return 5

to_int32()

Deserializes self.data as a 32-bit signed integer as an int.

Source code in pyflp/_event.py
305
306
307
def to_int32(self) -> int:
    """Deserializes `self.data` as a 32-bit signed integer as an `int`."""
    return Int.unpack(self.data)[0]

to_uint32()

Deserializes self.data as a 32-bit unsigned integer as an int.

Source code in pyflp/_event.py
301
302
303
def to_uint32(self) -> int:
    """Deserializes `self.data` as a 32-bit unsigned integer as an `int`."""
    return UInt.unpack(self.data)[0]

_ColorEvent

Bases: _DWordEvent

Represents a 4 byte event which stores a color.

Source code in pyflp/_event.py
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
class _ColorEvent(_DWordEvent):
    """Represents a 4 byte event which stores a color."""

    def dump(self, new_color: colour.Color) -> None:
        """Dumps a `colour.Color` to event data.

        Args:
            new_color (colour.Color): The color to be dumped into the event.

        Raises:
            TypeError: When `new_color` isn't a `colour.Color` object."""

        if not isinstance(new_color, colour.Color):
            raise TypeError(f"Expected a colour.Color; got {type(new_color)!r}")
        self._data = bytes((int(c * 255) for c in new_color.rgb)) + b"\x00"

    def to_color(self) -> colour.Color:
        r, g, b = (c / 255 for c in self.data[:3])
        return colour.Color(rgb=(r, g, b))

dump(new_color)

Dumps a colour.Color to event data.

Parameters:

Name Type Description Default
new_color colour.Color

The color to be dumped into the event.

required

Raises:

Type Description
TypeError

When new_color isn't a colour.Color object.

Source code in pyflp/_event.py
339
340
341
342
343
344
345
346
347
348
349
350
def dump(self, new_color: colour.Color) -> None:
    """Dumps a `colour.Color` to event data.

    Args:
        new_color (colour.Color): The color to be dumped into the event.

    Raises:
        TypeError: When `new_color` isn't a `colour.Color` object."""

    if not isinstance(new_color, colour.Color):
        raise TypeError(f"Expected a colour.Color; got {type(new_color)!r}")
    self._data = bytes((int(c * 255) for c in new_color.rgb)) + b"\x00"

to_color()

Source code in pyflp/_event.py
352
353
354
def to_color(self) -> colour.Color:
    r, g, b = (c / 255 for c in self.data[:3])
    return colour.Color(rgb=(r, g, b))

_TextEvent

Bases: _VariableSizedEvent

Represents a variable sized event used for storing strings.

Source code in pyflp/_event.py
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
class _TextEvent(_VariableSizedEvent):
    """Represents a variable sized event used for storing strings."""

    @staticmethod
    def as_ascii(buf: bytes) -> str:
        return buf.decode("ascii", errors="ignore").strip("\0")

    @staticmethod
    def as_uf16(buf: bytes) -> str:
        return buf.decode("utf-16", errors="ignore").strip("\0")

    def dump(self, new_data: str) -> None:
        """Dumps a string to the event data. non UTF-16 data for UTF-16 type
        projects and non ASCII data for older projects will be removed before
        dumping.

        Args:
            new_data (str): The string to be dumped to event data;

        Raises:
            TypeError: When `new_data` isn't an `str` object.
        """

        text = new_data
        if not isinstance(text, str):
            raise TypeError(f"Expected an str object; got {type(text)!r}")
        # Version event (199) is always ASCII
        if self._uses_unicode and self.id_ != 199:
            self._data = text.encode("utf-16-le") + b"\0\0"
        else:
            self._data = text.encode("ascii") + b"\0"

    def to_str(self) -> str:
        if self._uses_unicode and self.id_ != 199:
            return self.as_uf16(self.data)
        return self.as_ascii(self.data)

    def __repr__(self) -> str:
        return f'<{super().__repr__().strip("<>")!r}, s="{self.to_str()!r}">'

    def __init__(
        self,
        index: int,
        id: EventIDType,
        data: bytes,
        uses_unicode: bool = True,
    ):
        """
        Args:
            id (EventID): An event ID from
                **192** to **207** or in `DATA_TEXT_EVENTS`.
            data (bytes): A `bytes` object.

        Raises:
            ValueError: When `id` is not in range of 192-207 or in `DATA_TEXT_EVENTS`.
        """

        if id not in range(TEXT, DATA) and id not in DATA_TEXT_EVENTS:
            raise ValueError(f"Unexpected ID: {id!r}")
        if not isinstance(data, bytes):
            raise TypeError(f"Expected a bytes object; got {type(data)!r}")
        super().__init__(index, id, data)
        self._uses_unicode = uses_unicode

__init__(index, id, data, uses_unicode=True)

Parameters:

Name Type Description Default
id EventID

An event ID from 192 to 207 or in DATA_TEXT_EVENTS.

required
data bytes

A bytes object.

required

Raises:

Type Description
ValueError

When id is not in range of 192-207 or in DATA_TEXT_EVENTS.

Source code in pyflp/_event.py
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
def __init__(
    self,
    index: int,
    id: EventIDType,
    data: bytes,
    uses_unicode: bool = True,
):
    """
    Args:
        id (EventID): An event ID from
            **192** to **207** or in `DATA_TEXT_EVENTS`.
        data (bytes): A `bytes` object.

    Raises:
        ValueError: When `id` is not in range of 192-207 or in `DATA_TEXT_EVENTS`.
    """

    if id not in range(TEXT, DATA) and id not in DATA_TEXT_EVENTS:
        raise ValueError(f"Unexpected ID: {id!r}")
    if not isinstance(data, bytes):
        raise TypeError(f"Expected a bytes object; got {type(data)!r}")
    super().__init__(index, id, data)
    self._uses_unicode = uses_unicode

__repr__()

Source code in pyflp/_event.py
394
395
def __repr__(self) -> str:
    return f'<{super().__repr__().strip("<>")!r}, s="{self.to_str()!r}">'

as_ascii(buf) staticmethod

Source code in pyflp/_event.py
360
361
362
@staticmethod
def as_ascii(buf: bytes) -> str:
    return buf.decode("ascii", errors="ignore").strip("\0")

as_uf16(buf) staticmethod

Source code in pyflp/_event.py
364
365
366
@staticmethod
def as_uf16(buf: bytes) -> str:
    return buf.decode("utf-16", errors="ignore").strip("\0")

dump(new_data)

Dumps a string to the event data. non UTF-16 data for UTF-16 type projects and non ASCII data for older projects will be removed before dumping.

Parameters:

Name Type Description Default
new_data str

The string to be dumped to event data;

required

Raises:

Type Description
TypeError

When new_data isn't an str object.

Source code in pyflp/_event.py
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
def dump(self, new_data: str) -> None:
    """Dumps a string to the event data. non UTF-16 data for UTF-16 type
    projects and non ASCII data for older projects will be removed before
    dumping.

    Args:
        new_data (str): The string to be dumped to event data;

    Raises:
        TypeError: When `new_data` isn't an `str` object.
    """

    text = new_data
    if not isinstance(text, str):
        raise TypeError(f"Expected an str object; got {type(text)!r}")
    # Version event (199) is always ASCII
    if self._uses_unicode and self.id_ != 199:
        self._data = text.encode("utf-16-le") + b"\0\0"
    else:
        self._data = text.encode("ascii") + b"\0"

to_str()

Source code in pyflp/_event.py
389
390
391
392
def to_str(self) -> str:
    if self._uses_unicode and self.id_ != 199:
        return self.as_uf16(self.data)
    return self.as_ascii(self.data)

_DataEvent

Bases: _VariableSizedEvent

Represents a variable sized event used for storing a blob of data, consists of a collection of POD types like int, bool, float, sometimes ASCII strings. Its size is determined by the event and also FL version sometimes. The task of parsing is completely handled by one of the FLObject subclasses, hence no to_* conversion method is provided.

Source code in pyflp/_event.py
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
class _DataEvent(_VariableSizedEvent):
    """Represents a variable sized event used for storing a blob of data, consists
    of a collection of POD types like int, bool, float, sometimes ASCII strings.
    Its size is determined by the event and also FL version sometimes.
    The task of parsing is completely handled by one of the FLObject subclasses,
    hence no `to_*` conversion method is provided."""

    CHUNK_SIZE = None
    """Parsing is not done if size of `data` argument is not equal to this."""

    def dump(self, new_bytes: bytes):
        """Dumps a blob of bytes to event data as is; no conversions of any-type.
        This method is used instead of directly dumping to event data for type-safety.

        Raises:
            TypeError: When `new_bytes` isn't a `bytes` object."""

        # * Changing the length of a data event is rarely needed. Maybe only for
        # * event-in-event type of events (e.g. InsertParamsEvent, Playlist events)
        # ? Maybe make a VariableDataEvent subclass for these events?
        # * This way event data size restrictions can be enforced below.

        if not isinstance(new_bytes, bytes):
            raise TypeError(
                f"Expected a bytes object; got a {type(new_bytes)!r} object"
            )
        self._data = new_bytes

    def __init__(self, index: int, id: EventIDType, data: bytes):
        """
        Args:
            id (EventID): An event ID in from **208** to **255**.
            data (bytes): A `bytes` object.

        Raises:
            ValueError: When the event ID is not in the range of 208 (`DATA`) to 255.
        """
        if id < DATA:
            raise ValueError(f"Expected an event ID from 209 to 255; got {id!r}")
        if not isinstance(data, bytes):
            raise TypeError(f"Expected a bytes object; got {type(data)!r}")
        super().__init__(index, id, data)
        if self.CHUNK_SIZE is not None:  # pragma: no cover
            if len(data) != self.CHUNK_SIZE:
                return

CHUNK_SIZE = None class-attribute

Parsing is not done if size of data argument is not equal to this.

__init__(index, id, data)

Parameters:

Name Type Description Default
id EventID

An event ID in from 208 to 255.

required
data bytes

A bytes object.

required

Raises:

Type Description
ValueError

When the event ID is not in the range of 208 (DATA) to 255.

Source code in pyflp/_event.py
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
def __init__(self, index: int, id: EventIDType, data: bytes):
    """
    Args:
        id (EventID): An event ID in from **208** to **255**.
        data (bytes): A `bytes` object.

    Raises:
        ValueError: When the event ID is not in the range of 208 (`DATA`) to 255.
    """
    if id < DATA:
        raise ValueError(f"Expected an event ID from 209 to 255; got {id!r}")
    if not isinstance(data, bytes):
        raise TypeError(f"Expected a bytes object; got {type(data)!r}")
    super().__init__(index, id, data)
    if self.CHUNK_SIZE is not None:  # pragma: no cover
        if len(data) != self.CHUNK_SIZE:
            return

dump(new_bytes)

Dumps a blob of bytes to event data as is; no conversions of any-type. This method is used instead of directly dumping to event data for type-safety.

Raises:

Type Description
TypeError

When new_bytes isn't a bytes object.

Source code in pyflp/_event.py
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
def dump(self, new_bytes: bytes):
    """Dumps a blob of bytes to event data as is; no conversions of any-type.
    This method is used instead of directly dumping to event data for type-safety.

    Raises:
        TypeError: When `new_bytes` isn't a `bytes` object."""

    # * Changing the length of a data event is rarely needed. Maybe only for
    # * event-in-event type of events (e.g. InsertParamsEvent, Playlist events)
    # ? Maybe make a VariableDataEvent subclass for these events?
    # * This way event data size restrictions can be enforced below.

    if not isinstance(new_bytes, bytes):
        raise TypeError(
            f"Expected a bytes object; got a {type(new_bytes)!r} object"
        )
    self._data = new_bytes