From 9dd6bf8d067a3c847b61d71daf9397afe977779f Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Mon, 1 Jun 2020 14:39:05 -0400 Subject: [PATCH 1/3] Add OneShot sequence subclass to make it easy to run a sequence one time. Also fixes some bugs in the animation sequence completion tracking. --- adafruit_led_animation/animation/__init__.py | 5 +- adafruit_led_animation/animation/comet.py | 6 ++- adafruit_led_animation/helper.py | 2 +- adafruit_led_animation/sequence.py | 53 ++++++++++++++++++-- 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/adafruit_led_animation/animation/__init__.py b/adafruit_led_animation/animation/__init__.py index 6327ead..c863f82 100644 --- a/adafruit_led_animation/animation/__init__.py +++ b/adafruit_led_animation/animation/__init__.py @@ -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 diff --git a/adafruit_led_animation/animation/comet.py b/adafruit_led_animation/animation/comet.py index 372ff87..bbe54e7 100644 --- a/adafruit_led_animation/animation/comet.py +++ b/adafruit_led_animation/animation/comet.py @@ -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: diff --git a/adafruit_led_animation/helper.py b/adafruit_led_animation/helper.py index 255a2d0..eddb522 100644 --- a/adafruit_led_animation/helper.py +++ b/adafruit_led_animation/helper.py @@ -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 diff --git a/adafruit_led_animation/sequence.py b/adafruit_led_animation/sequence.py index 3532cde..9930fce 100644 --- a/adafruit_led_animation/sequence.py +++ b/adafruit_led_animation/sequence.py @@ -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() @@ -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): """ @@ -275,3 +274,49 @@ def show(self): Draws the current animation group members. """ self.current_animation.show() + + +class OneShot(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 OneShot + + 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 = OneShot(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 From 7628f3399e2680e5674e21490f5b996a7dff84d0 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Mon, 8 Jun 2020 19:55:46 -0400 Subject: [PATCH 2/3] Rename to AnimateOnce --- adafruit_led_animation/sequence.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adafruit_led_animation/sequence.py b/adafruit_led_animation/sequence.py index 9930fce..2526cf7 100644 --- a/adafruit_led_animation/sequence.py +++ b/adafruit_led_animation/sequence.py @@ -276,7 +276,7 @@ def show(self): self.current_animation.show() -class OneShot(AnimationSequence): +class AnimateOnce(AnimationSequence): """ Wrapper around AnimationSequence that returns False to animate() until a sequence has completed. Takes the same arguments as AnimationSequence, but overrides @@ -293,14 +293,14 @@ class OneShot(AnimationSequence): 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 OneShot + 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 = OneShot(comet, pulse) + animations = AnimateOnce(comet, pulse) while animations.animate(): pass From 307665abcbb8e80bae977e003b702379cb243ee8 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Mon, 8 Jun 2020 20:40:35 -0400 Subject: [PATCH 3/3] convince github actions to rebuild --- adafruit_led_animation/sequence.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/adafruit_led_animation/sequence.py b/adafruit_led_animation/sequence.py index 2526cf7..ce9005c 100644 --- a/adafruit_led_animation/sequence.py +++ b/adafruit_led_animation/sequence.py @@ -279,8 +279,8 @@ def show(self): 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 + Takes the same arguments as AnimationSequence, but overrides advance_on_cycle_complete=True + and advance_interval=0 Example: