flickerstrip-py/flickerstrip_py/core/pattern_builder.py

67 lines
1.8 KiB
Python

from typing import Tuple
from flickerstrip_py.models.pattern import Pattern, PatternData
RGBColor = Tuple[int, int, int]
class PatternBuilder:
def __init__(self, name: str, fps=1, pixels_per_frame=1):
self.data: list[RGBColor] = []
self.name = name
self.fps = fps
self.fps: int = fps
self.frame_count: int = 1
self.pixels_per_frame: int = pixels_per_frame
def set_pixel(self, f: int, i: int, color: RGBColor):
offset = f * self.pixels_per_frame + i
self.data[offset] = color
def append_pixel(self, color: RGBColor):
self.data.append(color)
def get_frame(self, f: int) -> list[RGBColor]:
start = f * self.pixels_per_frame
end = start + self.pixels_per_frame
return self.data[start:end]
def next_frame(self):
if not self.is_valid():
raise Exception("Not enough pixels for next frame")
self.frame_count += 1
def is_valid(self):
if self.frame_count == 0:
return False
if len(self.data) != self.frame_count * self.pixels_per_frame:
return False
return True
def to_pattern_data(self) -> PatternData:
data = bytes(y for x in self.data for y in x)
return PatternData(data=data)
def to_pattern(self) -> Pattern:
return Pattern(
id=0,
flags=0,
name=self.name,
fps=self.fps,
frames=self.frame_count,
pixels=self.pixels_per_frame,
)
@classmethod
def from_data(cls, meta: Pattern, data: PatternData):
builder = PatternBuilder(meta.name, meta.fps, meta.pixels)
builder.data = [
tuple(data.data[x : x + 3]) for x in range(0, len(data.data), 3)
]
builder.frame_count = meta.frames
return builder