Skip to content

Add OneShot sequence subclass to make it easy to run a sequence once #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions adafruit_led_animation/animation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,16 @@ def animate(self):
for anim in self._peers:
anim.draw()
anim.after_draw()
anim.draw_count += 1

for anim in self._peers:
anim.show()

# Note that the main animation cycle_complete flag is used, not the peer flag.
for anim in self._peers:
if self.cycle_complete:
anim.on_cycle_complete()
if anim.cycle_complete:
anim.cycle_complete = False
anim.on_cycle_complete()

self._next_update = now + self._speed_ns
return True
Expand Down
6 changes: 4 additions & 2 deletions adafruit_led_animation/animation/comet.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,14 @@ def draw(self):
if self.bounce:
self.reverse = not self.reverse
self._direction = -self._direction
if self.reverse == self._initial_reverse:
else:
self.reset()
if self.reverse == self._initial_reverse and self.draw_count > 0:
self.cycle_complete = True

def reset(self):
"""
Resets to the first color.
Resets to the first state.
"""
self.reverse = self._initial_reverse
if self.reverse:
Expand Down
2 changes: 1 addition & 1 deletion adafruit_led_animation/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def pulse_generator(period: float, animation_object, white=False, dotstar_pwm=Fa
last_update = now
pos = cycle_position = (cycle_position + time_since_last_draw) % period
if pos < last_pos:
animation_object.on_cycle_complete()
animation_object.cycle_complete = True
last_pos = pos
if pos > half_period:
pos = period - pos
Expand Down
53 changes: 49 additions & 4 deletions adafruit_led_animation/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ def on_cycle_complete(self):
callback(self)

def _sequence_complete(self, animation): # pylint: disable=unused-argument
self.on_cycle_complete()
if self.advance_on_cycle_complete:
self._advance()

Expand Down Expand Up @@ -194,10 +193,10 @@ def next(self):
"""
Jump to the next animation.
"""
current = self._current
if current > self._current:
current = self._current + 1
if current >= len(self._members):
self.on_cycle_complete()
self.activate((self._current + 1) % len(self._members))
self.activate(current % len(self._members))

def random(self):
"""
Expand Down Expand Up @@ -275,3 +274,49 @@ def show(self):
Draws the current animation group members.
"""
self.current_animation.show()


class AnimateOnce(AnimationSequence):
"""
Wrapper around AnimationSequence that returns False to animate() until a sequence has completed.
Takes the same arguments as AnimationSequence, but overrides advance_on_cycle_complete=True
and advance_interval=0

Example:

This example animates a comet in one direction then pulses red momentarily

.. code-block:: python

import board
import neopixel
from adafruit_led_animation.animation.comet import Comet
from adafruit_led_animation.animation.pulse import Pulse
from adafruit_led_animation.color import BLUE, RED
from adafruit_led_animation.sequence import AnimateOnce

strip_pixels = neopixel.NeoPixel(board.A1, 30, brightness=0.5, auto_write=False)

comet = Comet(strip_pixels, 0.01, color=BLUE, bounce=False)
pulse = Pulse(strip_pixels, 0.01, color=RED, period=2)

animations = AnimateOnce(comet, pulse)

while animations.animate():
pass

"""

def __init__(self, *members, **kwargs):
kwargs["advance_on_cycle_complete"] = True
kwargs["advance_interval"] = 0
super().__init__(*members, **kwargs)
self._running = True

def on_cycle_complete(self):
super().on_cycle_complete()
self._running = False

def animate(self):
super().animate()
return self._running