Skip to content

Commit 76a3e43

Browse files
committed
a bunch of protocol changes to allow a second stage of drawing, and to move the cycle done callback out to animate()
1 parent 52b3d60 commit 76a3e43

File tree

13 files changed

+66
-43
lines changed

13 files changed

+66
-43
lines changed

adafruit_led_animation/animation/__init__.py

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,13 @@ class Animation:
5454
"""
5555
Base class for animations.
5656
"""
57-
cycle_complete_supported = False
57+
on_cycle_complete_supported = False
5858

5959
# pylint: disable=too-many-arguments
6060
def __init__(self, pixel_object, speed, color, peers=None, paused=False, name=None):
6161
self.pixel_object = pixel_object
6262
self.pixel_object.auto_write = False
63-
self.peers = peers if peers else []
64-
"""A sequence of animations to trigger .draw() on when this animation draws."""
63+
self._peers = [self] + peers if peers is not None else [self]
6564
self._speed_ns = 0
6665
self._color = None
6766
self._paused = paused
@@ -71,6 +70,7 @@ def __init__(self, pixel_object, speed, color, peers=None, paused=False, name=No
7170
self.speed = speed # sets _speed_ns
7271
self.color = color # Triggers _recompute_color
7372
self.name = name
73+
self.cycle_complete = False
7474
self.notify_cycles = 1
7575
"""Number of cycles to trigger additional cycle_done notifications after"""
7676
self.draw_count = 0
@@ -95,30 +95,59 @@ def animate(self):
9595
if now < self._next_update:
9696
return False
9797

98-
self.draw()
99-
self.draw_count += 1
100-
10198
# Draw related animations together
102-
if self.peers:
103-
for peer in self.peers:
104-
peer.draw()
99+
for anim in self._peers:
100+
anim.draw()
101+
anim.after_draw()
102+
103+
for anim in self._peers:
104+
anim.show()
105+
106+
# Note that the main animation cycle_complete flag is used, not the peer flag.
107+
for anim in self._peers:
108+
if self.cycle_complete:
109+
anim.on_cycle_complete()
110+
anim.cycle_complete = False
105111

106112
self._next_update = now + self._speed_ns
107113
return True
108114

109115
def draw(self):
110116
"""
111117
Animation subclasses must implement draw() to render the animation sequence.
112-
Draw must call show().
118+
Animations should not call show(), as animate() will do so, after after_draw().
119+
Animations should set .cycle_done = True when an animation cycle is completed.
113120
"""
114121
raise NotImplementedError()
115122

123+
def after_draw(self):
124+
"""
125+
Animation subclasses may implement after_draw() to do operations after the main draw()
126+
is called.
127+
"""
128+
116129
def show(self):
117130
"""
118131
Displays the updated pixels. Called during animates with changes.
119132
"""
120133
self.pixel_object.show()
121134

135+
@property
136+
def peers(self):
137+
"""
138+
Get the animation's peers. Peers are drawn, then shown together.
139+
"""
140+
return self._peers[1:]
141+
142+
@peers.setter
143+
def peers(self, peer_list):
144+
"""
145+
Set the animation's peers.
146+
:param list peer_list: List of peer animations.
147+
"""
148+
if peer_list is not None:
149+
self._peers = [self] + peer_list
150+
122151
def freeze(self):
123152
"""
124153
Stops the animation until resumed.
@@ -173,7 +202,7 @@ def _recompute_color(self, color):
173202
Override as needed.
174203
"""
175204

176-
def cycle_complete(self):
205+
def on_cycle_complete(self):
177206
"""
178207
Called by some animations when they complete an animation cycle.
179208
Animations that support cycle complete notifications will have X property set to False.

adafruit_led_animation/animation/chase.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def _resetter():
8383

8484
super().__init__(pixel_object, speed, color, name=name)
8585

86-
cycle_complete_supported = True
86+
on_cycle_complete_supported = True
8787

8888
@property
8989
def reverse(self):
@@ -115,10 +115,9 @@ def bar_colors():
115115

116116
colorgen = bar_colors()
117117
self.pixel_object[:] = [next(colorgen) for _ in self.pixel_object]
118-
self.show()
119118

120119
if self.draw_count % len(self.pixel_object) == 0:
121-
self.cycle_complete()
120+
self.cycle_complete = True
122121
self._offset = (self._offset + self._direction) % self._repeat_width
123122

124123
def bar_color(self, n, pixel_no=0): # pylint: disable=unused-argument

adafruit_led_animation/animation/colorcycle.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,10 @@ def __init__(self, pixel_object, speed, colors=RAINBOW, name=None):
6464
self._generator = self._color_generator()
6565
next(self._generator)
6666

67-
cycle_complete_supported = True
67+
on_cycle_complete_supported = True
6868

6969
def draw(self):
7070
self.pixel_object.fill(self.color)
71-
self.show()
7271
next(self._generator)
7372

7473
def _color_generator(self):
@@ -78,7 +77,7 @@ def _color_generator(self):
7877
yield
7978
index = (index + 1) % len(self.colors)
8079
if index == 0:
81-
self.cycle_complete()
80+
self.cycle_complete = True
8281

8382
def reset(self):
8483
"""

adafruit_led_animation/animation/comet.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def __init__(
8989
self._generator = self._comet_generator()
9090
super().__init__(pixel_object, speed, color, name=name)
9191

92-
cycle_complete_supported = True
92+
on_cycle_complete_supported = True
9393

9494
def _recompute_color(self, color):
9595
pass
@@ -130,13 +130,12 @@ def _comet_generator(self):
130130
]
131131
else:
132132
self.pixel_object[start : start + end] = colors[0:end]
133-
self.show()
134133
yield
135134
cycle_passes += 1
136135
if self.bounce:
137136
self.reverse = not self.reverse
138137
if not self.bounce or cycle_passes == 2:
139-
self.cycle_complete()
138+
self.cycle_complete = True
140139
cycle_passes = 0
141140

142141
def draw(self):

adafruit_led_animation/animation/pulse.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,11 @@ def __init__(self, pixel_object, speed, color, period=5, name=None):
6464
self._generator = None
6565
self.reset()
6666

67-
cycle_complete_supported = True
67+
on_cycle_complete_supported = True
6868

6969
def draw(self):
7070
color = next(self._generator)
7171
self.fill(color)
72-
self.show()
7372

7473
def reset(self):
7574
"""

adafruit_led_animation/animation/rainbow.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def generate_rainbow(self):
8585
self.colors.append(colorwheel(int(i)))
8686
i += self._step
8787

88-
cycle_complete_supported = True
88+
on_cycle_complete_supported = True
8989

9090
def _color_wheel_generator(self):
9191
period = int(self._period * NANOS_PER_SECOND)
@@ -113,9 +113,8 @@ def _color_wheel_generator(self):
113113
colorwheel((i + wheel_index) % 255) for i in range(num_pixels)
114114
]
115115
self._wheel_index = wheel_index
116-
self.show()
117116
if cycle_completed:
118-
self.cycle_complete()
117+
self.cycle_complete = True
119118
yield
120119

121120
def _draw_precomputed(self, num_pixels, wheel_index):

adafruit_led_animation/animation/rainbowchase.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,6 @@ def __init__(
8080
def bar_color(self, n, pixel_no=0):
8181
return self._colors[self._color_idx - n]
8282

83-
def cycle_complete(self):
83+
def on_cycle_complete(self):
8484
self._color_idx = (self._color_idx + self._direction) % len(self._colors)
85-
super().cycle_complete()
85+
super().on_cycle_complete()

adafruit_led_animation/animation/rainbowsparkle.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ def generate_rainbow(self):
106106
int(self._background_brightness * color[2]),
107107
)
108108

109-
def show(self):
109+
def after_draw(self):
110+
self.show()
110111
pixels = [
111112
random.randint(0, len(self.pixel_object) - 1)
112113
for n in range(self._num_sparkles)
@@ -115,4 +116,3 @@ def show(self):
115116
self.pixel_object[pixel] = self._bright_colors[
116117
(self._wheel_index + pixel) % len(self._bright_colors)
117118
]
118-
super().show()

adafruit_led_animation/animation/sparkle.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,3 @@ def draw(self):
9191
for pixel in pixels:
9292
self.pixel_object[pixel] = self._half_color
9393
self.pixel_object[pixel + 1] = self._dim_color
94-
self.show()

adafruit_led_animation/animation/sparklepulse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def __init__(
7474
self._half_period = period / 2
7575
self._position_factor = 1 / self._half_period
7676
self._bpp = len(pixel_object[0])
77-
if isinstance(pixel_object[-1], float):
77+
if self._bpp == 4 and isinstance(pixel_object[0][3], float):
7878
self._bpp = 3
7979
self._last_update = monotonic_ns()
8080
self._cycle_position = 0

adafruit_led_animation/group.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,15 @@ def __init__(self, *members, sync=False, name=None):
7979

8080
# Catch cycle_complete on the last animation.
8181
self._members[-1].add_cycle_complete_receiver(self._group_done)
82-
self.cycle_complete_supported = self._members[-1].cycle_complete_supported
82+
self.on_cycle_complete_supported = self._members[-1].on_cycle_complete_supported
8383

8484
def __str__(self):
8585
return "<AnimationGroup %s: %s>" % (self.__class__.__name__, self.name)
8686

8787
def _group_done(self, animation): # pylint: disable=unused-argument
88-
self.cycle_complete()
88+
self.on_cycle_complete()
8989

90-
def cycle_complete(self):
90+
def on_cycle_complete(self):
9191
"""
9292
Called by some animations when they complete an animation cycle.
9393
Animations that support cycle complete notifications will have X property set to False.

adafruit_led_animation/helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ def pulse_generator(period: float, animation_object, white=False):
381381
last_update = now
382382
pos = cycle_position = (cycle_position + time_since_last_draw) % period
383383
if pos < last_pos:
384-
animation_object.cycle_complete()
384+
animation_object.on_cycle_complete()
385385
last_pos = pos
386386
if pos > half_period:
387387
pos = period - pos

adafruit_led_animation/sequence.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ class AnimationSequence:
6565
Defaults to ``False``.
6666
:param bool random_order: Activate the animations in a random order. Defaults to ``False``.
6767
:param bool auto_reset: Automatically call reset() on animations when changing animations.
68-
:param bool advance_on_cycle_complete: Automatically advance when `cycle_complete` is triggered
69-
on member animations. All Animations must support
70-
cycle_complete to use this.
68+
:param bool advance_on_cycle_complete: Automatically advance when `on_cycle_complete` is
69+
triggered on member animations. All Animations must
70+
support on_cycle_complete to use this.
7171
7272
.. code-block:: python
7373
@@ -126,14 +126,14 @@ def __init__(
126126
self._color = None
127127
for member in self._members:
128128
member.add_cycle_complete_receiver(self._sequence_complete)
129-
self.cycle_complete_supported = self._members[-1].cycle_complete_supported
129+
self.on_cycle_complete_supported = self._members[-1].on_cycle_complete_supported
130130

131-
cycle_complete_supported = True
131+
on_cycle_complete_supported = True
132132

133133
def __str__(self):
134134
return "<%s: %s>" % (self.__class__.__name__, self.name)
135135

136-
def cycle_complete(self):
136+
def on_cycle_complete(self):
137137
"""
138138
Called by some animations when they complete an animation cycle.
139139
Animations that support cycle complete notifications will have X property set to False.
@@ -145,7 +145,7 @@ def cycle_complete(self):
145145
callback(self)
146146

147147
def _sequence_complete(self, animation): # pylint: disable=unused-argument
148-
self.cycle_complete()
148+
self.on_cycle_complete()
149149
if self.advance_on_cycle_complete:
150150
self._advance()
151151

@@ -194,7 +194,7 @@ def next(self):
194194
"""
195195
current = self._current
196196
if current > self._current:
197-
self.cycle_complete()
197+
self.on_cycle_complete()
198198
self.activate((self._current + 1) % len(self._members))
199199

200200
def random(self):

0 commit comments

Comments
 (0)