Berry animation rename internal classes (#24301)

This commit is contained in:
s-hadinger 2026-01-03 22:05:14 +01:00 committed by GitHub
parent 6a33f8565d
commit 950eccbd33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
65 changed files with 877 additions and 913 deletions

View File

@ -16,7 +16,7 @@ class cylon_animation : animation.engine_proxy
"period": {"type": "time"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class shutter_bidir_animation : animation.engine_proxy
"period": {"type": "time"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class shutter_central_animation : animation.engine_proxy
"period": {"type": "time"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class shutter_lr_animation : animation.engine_proxy
"period": {}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class cylon_effect_animation : animation.engine_proxy
"back_color": {"type": "color"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class rainbow_pulse_animation : animation.engine_proxy
"back_color": {"type": "color"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class shutter_bidir_animation : animation.engine_proxy
"period": {"type": "time"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class shutter_central_animation : animation.engine_proxy
"period": {"type": "time"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -15,7 +15,7 @@ class shutter_central_animation : animation.engine_proxy
"period": {"type": "time"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class pulse_effect_animation : animation.engine_proxy
"brightness": {"type": "percentage"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -16,7 +16,7 @@ class pulse_effect_animation : animation.engine_proxy
"brightness": {"type": "percentage"}
})
# Template setup method - overrides EngineProxy placeholder
# Template setup method - overrides engine_proxy placeholder
def setup_template()
var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')

View File

@ -1,6 +1,6 @@
# Berry Animation Framework - Class Hierarchy and Parameters Reference
This document provides a comprehensive reference for all classes in the Berry Animation Framework that extend `ParameterizedObject`, including their parameters and factory functions.
This document provides a comprehensive reference for all classes in the Berry Animation Framework that extend `parameterized_object`, including their parameters and factory functions.
## Table of Contents
@ -14,9 +14,9 @@ This document provides a comprehensive reference for all classes in the Berry An
## Class Hierarchy
```
ParameterizedObject (base class with parameter management and playable interface)
parameterized_object (base class with parameter management and playable interface)
├── Animation (unified base class for all visual elements)
│ ├── EngineProxy (combines rendering and orchestration)
│ ├── engine_proxy (combines rendering and orchestration)
│ │ └── (user-defined template animations)
│ ├── SolidAnimation (solid color fill)
│ ├── BeaconAnimation (pulse at specific position)
@ -32,15 +32,15 @@ ParameterizedObject (base class with parameter management and playable interface
│ ├── twinkle (twinkling stars effect)
│ ├── WaveAnimation (wave motion effects)
│ └── RichPaletteAnimation (smooth palette transitions)
├── SequenceManager (orchestrates animation sequences)
└── ValueProvider (dynamic value generation)
├── StaticValueProvider (wraps static values)
├── sequence_manager (orchestrates animation sequences)
└── value_provider (dynamic value generation)
├── static_value (wraps static values)
├── strip_length (provides LED strip length)
├── IterationNumberProvider (provides sequence iteration number)
├── OscillatorValueProvider (oscillating values with waveforms)
├── iteration_number (provides sequence iteration number)
├── oscillator_value (oscillating values with waveforms)
├── closure_value (computed values, internal use only)
└── color_provider (dynamic color generation)
├── StaticColorProvider (solid color)
├── static_color (solid color)
├── ColorCycleColorProvider (cycles through palette)
├── rich_palette_color (smooth palette transitions)
└── breathe_color (breathing color effect)
@ -48,7 +48,7 @@ ParameterizedObject (base class with parameter management and playable interface
## Base Classes
### ParameterizedObject
### parameterized_object
Base class for all parameterized objects in the framework. Provides parameter management with validation, storage, and retrieval, as well as the playable interface for lifecycle management (start/stop/update).
@ -71,7 +71,7 @@ This unified base class enables:
### Animation
Unified base class for all visual elements. Inherits from `ParameterizedObject`.
Unified base class for all visual elements. Inherits from `parameterized_object`.
| Parameter | Type | Default | Constraints | Description |
|-----------|------|---------|-------------|-------------|
@ -80,7 +80,7 @@ Unified base class for all visual elements. Inherits from `ParameterizedObject`.
| `priority` | int | 10 | 0-255 | Rendering priority (higher = on top) |
| `duration` | int | 0 | min: 0 | Animation duration in ms (0 = infinite) |
| `loop` | bool | false | - | Whether to loop when duration is reached |
| `opacity` | any | 255 | - | Animation opacity (number, FrameBuffer, or Animation) |
| `opacity` | any | 255 | - | Animation opacity (number, frame_buffer, or Animation) |
| `color` | int | 0xFFFFFFFF | - | Base color in ARGB format |
**Special Behavior**: Setting `is_running = true/false` starts/stops the animation.
@ -89,7 +89,7 @@ Unified base class for all visual elements. Inherits from `ParameterizedObject`.
**Factory**: `animation.animation(engine)`
### EngineProxy
### engine_proxy
A specialized animation class that combines rendering and orchestration capabilities. Extends `Animation` and can contain child animations and sequences. Inherits from `Animation`.
@ -119,7 +119,7 @@ A specialized animation class that combines rendering and orchestration capabili
### Template Animations
Template animations are user-defined classes that extend `EngineProxy`, created using the DSL's `template animation` syntax. They provide reusable, parameterized animation patterns.
Template animations are user-defined classes that extend `engine_proxy`, created using the DSL's `template animation` syntax. They provide reusable, parameterized animation patterns.
**DSL Definition**:
```berry
@ -157,7 +157,7 @@ Template animation parameters support all standard constraints:
- `nillable` - Whether parameter can be nil (true/false)
**Implicit Parameters**:
Template animations automatically inherit parameters from the `EngineProxy` class hierarchy without explicit declaration:
Template animations automatically inherit parameters from the `engine_proxy` class hierarchy without explicit declaration:
- `id` (string, default: "animation") - Animation name
- `priority` (int, default: 10) - Rendering priority
- `duration` (int, default: 0) - Animation duration in milliseconds
@ -203,9 +203,9 @@ run my_shutter
Value providers generate dynamic values over time for use as animation parameters.
### ValueProvider
### value_provider
Base interface for all value providers. Inherits from `ParameterizedObject`.
Base interface for all value providers. Inherits from `parameterized_object`.
| Parameter | Type | Default | Constraints | Description |
|-----------|------|---------|-------------|-------------|
@ -217,9 +217,9 @@ Base interface for all value providers. Inherits from `ParameterizedObject`.
**Factory**: N/A (base interface)
### StaticValueProvider
### static_value
Wraps static values to provide ValueProvider interface. Inherits from `ValueProvider`.
Wraps static values to provide value_provider interface. Inherits from `value_provider`.
| Parameter | Type | Default | Constraints | Description |
|-----------|------|---------|-------------|-------------|
@ -229,7 +229,7 @@ Wraps static values to provide ValueProvider interface. Inherits from `ValueProv
### strip_length
Provides access to the LED strip length as a dynamic value. Inherits from `ValueProvider`.
Provides access to the LED strip length as a dynamic value. Inherits from `value_provider`.
| Parameter | Type | Default | Constraints | Description |
|-----------|------|---------|-------------|-------------|
@ -239,9 +239,9 @@ Provides access to the LED strip length as a dynamic value. Inherits from `Value
**Factory**: `animation.strip_length(engine)`
### OscillatorValueProvider
### oscillator_value
Generates oscillating values using various waveforms. Inherits from `ValueProvider`.
Generates oscillating values using various waveforms. Inherits from `value_provider`.
| Parameter | Type | Default | Constraints | Description |
|-----------|------|---------|-------------|-------------|
@ -338,11 +338,11 @@ animation pulse = pulsating_animation(
## Color Providers
Color providers generate dynamic colors over time, extending ValueProvider for color-specific functionality.
Color providers generate dynamic colors over time, extending value_provider for color-specific functionality.
### color_provider
Base interface for all color providers. Inherits from `ValueProvider`.
Base interface for all color providers. Inherits from `value_provider`.
| Parameter | Type | Default | Constraints | Description |
|-----------|------|---------|-------------|-------------|
@ -353,7 +353,7 @@ Base interface for all color providers. Inherits from `ValueProvider`.
**Factory**: N/A (base interface)
### StaticColorProvider
### static_color
Returns a single, static color. Inherits from `color_provider`.
@ -468,7 +468,7 @@ Creates breathing/pulsing color effects by modulating the brightness of a base c
| `duration` | int | 3000 | min: 1 | Time for one complete breathing cycle in ms |
| `curve_factor` | int | 2 | 1-5 | Breathing curve shape (1=cosine wave, 2-5=curved breathing with pauses) |
| *(inherits brightness from color_provider)* | | | | Overall brightness scaling applied after breathing effect |
| *(inherits all OscillatorValueProvider parameters)* | | | | |
| *(inherits all oscillator_value parameters)* | | | | |
**Curve Factor Effects:**
- `1`: Pure cosine wave (smooth pulsing)

View File

@ -49,7 +49,7 @@ class MyAnimation : animation.animation
return false
end
# Use virtual parameter access - automatically resolves ValueProviders
# Use virtual parameter access - automatically resolves value_providers
var param1 = self.my_param1
var param2 = self.my_param2
@ -79,7 +79,7 @@ The `PARAMS` static variable defines all parameters specific to your animation c
- **Parameter validation** with min/max constraints and type checking
- **Default value handling** for initialization
- **Virtual parameter access** through getmember/setmember
- **Automatic ValueProvider resolution**
- **Automatic value_provider resolution**
#### Parameter Definition Format
@ -152,13 +152,13 @@ end
## Value Provider Integration
### Automatic ValueProvider Resolution
### Automatic value_provider Resolution
The virtual parameter system automatically resolves ValueProviders when you access parameters:
The virtual parameter system automatically resolves value_providers when you access parameters:
```berry
def render(frame, time_ms, strip_length)
# Virtual parameter access automatically resolves ValueProviders
# Virtual parameter access automatically resolves value_providers
var color = self.color # Returns current color value, not the provider
var position = self.pos # Returns current position value
var size = self.size # Returns current size value
@ -177,7 +177,7 @@ end
### Setting Dynamic Parameters
Users can set both static values and ValueProviders using the same syntax:
Users can set both static values and value_providers using the same syntax:
```berry
# Create animation
@ -370,13 +370,13 @@ var success = anim.set_param("size", -1) # Returns false, no exception
### Accessing Raw Parameters
```berry
# Get current parameter value (resolved if ValueProvider)
# Get current parameter value (resolved if value_provider)
var current_color = anim.color
# Get raw parameter (returns ValueProvider if set)
# Get raw parameter (returns value_provider if set)
var raw_color = anim.get_param("color")
# Check if parameter is a ValueProvider
# Check if parameter is a value_provider
if animation.is_value_provider(raw_color)
print("Color is dynamic")
else
@ -486,7 +486,7 @@ class BeaconAnimation : animation.animation
end
var pixel_size = strip_length
# Use virtual parameter access - automatically resolves ValueProviders
# Use virtual parameter access - automatically resolves value_providers
var back_color = self.back_color
var pos = self.pos
var slew_size = self.slew_size

View File

@ -1156,7 +1156,7 @@ my_fade.opacity = 200 # Set the implicit opacity parameter
- Implicit parameters can be overridden by explicit declarations if needed
- They follow the same constraint rules as explicit parameters
- They are accessed as `self.<param>` within the template body
- All implicit parameters come from the `Animation` and `ParameterizedObject` base classes
- All implicit parameters come from the `Animation` and `parameterized_object` base classes
**Key Features:**
- Generates reusable animation classes extending `engine_proxy`

View File

@ -162,7 +162,7 @@ _add_inherited_params_to_template(template_params_map)
└── Fallback to static list if instance creation fails
```
**Inherited Parameters (from Animation and ParameterizedObject):**
**Inherited Parameters (from Animation and parameterized_object):**
- `id` (string, default: "animation")
- `priority` (int, default: 10)
- `duration` (int, default: 0)

View File

@ -45,12 +45,12 @@ class BeaconAnimation : animation.animation
# Render the beacon to the provided frame buffer
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels
# @return bool - True if frame was modified, false otherwise
def render(frame, time_ms, strip_length)
# Use virtual parameter access - automatically resolves ValueProviders
# Use virtual parameter access - automatically resolves value_providers
var back_color = self.back_color
var pos = self.pos
var slew_size = self.slew_size

View File

@ -101,7 +101,7 @@ class CometAnimation : animation.animation
# Render the comet to the provided frame buffer
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels
# @return bool - True if frame was modified, false otherwise
@ -109,7 +109,7 @@ class CometAnimation : animation.animation
# Get the integer position of the head (convert from 1/256th pixels to pixels)
var head_pixel = self.head_position / 256
# Get current parameter values using virtual member access (resolves ValueProviders automatically)
# Get current parameter values using virtual member access (resolves value_providers automatically)
var current_color = self.color
var tail_length = self.tail_length
var direction = self.direction

View File

@ -36,12 +36,12 @@ class CrenelPositionAnimation : animation.animation
# Render the crenel pattern to the provided frame buffer
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels
# @return bool - True if frame was modified, false otherwise
def render(frame, time_ms, strip_length)
# Access parameters via virtual members (automatically resolves ValueProviders)
# Access parameters via virtual members (automatically resolves value_providers)
var back_color = self.back_color
var pos = self.pos
var pulse_size = self.pulse_size

View File

@ -219,7 +219,7 @@ class FireAnimation : animation.animation
# Render the fire to the provided frame buffer
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels
# @return bool - True if frame was modified, false otherwise

View File

@ -127,7 +127,7 @@ class PaletteGradientAnimation : animation.animation
# Render the pattern to the provided frame buffer
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels
# @return bool - True if frame was modified, false otherwise

View File

@ -162,7 +162,7 @@ class twinkle : animation.animation
# Create new star at full brightness with random intensity alpha
var star_alpha = min_brightness + self._random_range(max_brightness - min_brightness + 1)
# Get base color (automatically resolves ValueProviders)
# Get base color (automatically resolves value_providers)
var base_color = color
# Extract RGB components (ignore original alpha)
@ -180,7 +180,7 @@ class twinkle : animation.animation
# Render the twinkle to the provided frame buffer
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels
# @return bool - True if frame was modified, false otherwise

View File

@ -63,9 +63,9 @@ class BounceAnimation : animation.animation
end
end
# Override start method for timing control and ValueProvider propagation
# Override start method for timing control and value_provider propagation
def start(time_ms)
# Call parent start first (handles ValueProvider propagation)
# Call parent start first (handles value_provider propagation)
super(self).start(time_ms)
# Reset physics state for fresh start/restart

View File

@ -60,7 +60,7 @@ class JitterAnimation : animation.animation
# Override start method for lifecycle control
def start(time_ms)
# Call parent start first (handles ValueProvider propagation)
# Call parent start first (handles value_provider propagation)
super(self).start(time_ms)
# Reset jitter timing

View File

@ -52,7 +52,7 @@ class ScaleAnimation : animation.animation
# Start/restart the animation
def start(time_ms)
# Call parent start first (handles ValueProvider propagation)
# Call parent start first (handles value_provider propagation)
super(self).start(time_ms)
# Reset scale phase for animated modes

View File

@ -80,7 +80,7 @@ class SparkleAnimation : animation.animation
# Override start method for timing control (acts as both start and restart)
def start(time_ms)
# Call parent start first (handles ValueProvider propagation)
# Call parent start first (handles value_provider propagation)
super(self).start(time_ms)
# Reset random seed for consistent restarts
@ -171,7 +171,7 @@ class SparkleAnimation : animation.animation
# Get base color using virtual parameter access
var base_color = 0xFFFFFFFF
# Access color parameter (automatically resolves ValueProviders)
# Access color parameter (automatically resolves value_providers)
var color_param = self.color
if animation.is_color_provider(color_param) && color_param.get_color_for_value != nil
base_color = color_param.get_color_for_value(brightness, 0)

View File

@ -7,7 +7,7 @@
# This is the unified base class for all visual elements in the framework.
# A Pattern is simply an Animation with infinite duration (duration = 0).
#
# Extends ParameterizedObject to provide parameter management and playable interface.
# Extends parameterized_object to provide parameter management and playable interface.
import "./core/param_encoder" as encode_constraints
@ -66,12 +66,12 @@ class Animation : animation.parameterized_object
# Render the animation to the provided frame buffer
# Default implementation renders a solid color (makes Animation equivalent to solid pattern)
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels
# @return bool - True if frame was modified, false otherwise
def render(frame, time_ms, strip_length)
# Access parameters via virtual members (auto-resolves ValueProviders)
# Access parameters via virtual members (auto-resolves value_providers)
var current_color = self.member("color")
# Fill the entire frame with the current color if not transparent
@ -84,7 +84,7 @@ class Animation : animation.parameterized_object
# Post-processing of rendering
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels
def post_render(frame, time_ms, strip_length)
@ -104,7 +104,7 @@ class Animation : animation.parameterized_object
# Apply opacity to frame buffer - handles numbers and animations
#
# @param frame: FrameBuffer - The frame buffer to apply opacity to
# @param frame: frame_buffer - The frame buffer to apply opacity to
# @param opacity: int|Animation - Opacity value or animation
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels

View File

@ -1,6 +1,6 @@
# Unified Animation Engine
#
# Uses composition pattern: contains a root EngineProxy that manages all children.
# Uses composition pattern: contains a root engine_proxy that manages all children.
# The engine provides infrastructure (strip output, fast_loop) while delegating
# child management and rendering to the root animation.
@ -11,7 +11,7 @@ class AnimationEngine
# Core properties
var strip # LED strip object
var strip_length # Strip length (cached for performance)
var root_animation # Root EngineProxy that holds all children
var root_animation # Root engine_proxy that holds all children
var frame_buffer # Main frame buffer
var temp_buffer # Temporary buffer for blending
@ -72,7 +72,7 @@ class AnimationEngine
self.frame_buffer = animation.frame_buffer(self.strip_length)
self.temp_buffer = animation.frame_buffer(self.strip_length)
# Create root EngineProxy to manage all children
# Create root engine_proxy to manage all children
self.root_animation = animation.engine_proxy(self)
# Initialize state
@ -155,7 +155,7 @@ class AnimationEngine
# Add an animation or sequence to the root animation
#
# @param obj: Animation|SequenceManager - The object to add
# @param obj: Animation|sequence_manager - The object to add
# @return bool - True if added, false if already exists
def add(obj)
var ret = self.root_animation.add(obj)
@ -167,7 +167,7 @@ class AnimationEngine
# Remove an animation or sequence from the root animation
#
# @param obj: Animation|SequenceManager - The object to remove
# @param obj: Animation|sequence_manager - The object to remove
# @return bool - True if removed, false if not found
def remove(obj)
var ret = self.root_animation.remove(obj)
@ -549,7 +549,7 @@ class AnimationEngine
self.strip = nil
end
# Sequence iteration tracking methods, delegate to EngineProxy
# Sequence iteration tracking methods, delegate to engine_proxy
# Push a new iteration context onto the stack
# Called when a sequence starts repeating
@ -574,7 +574,7 @@ class AnimationEngine
end
# Get the current iteration number from the innermost sequence context
# Used by IterationNumberProvider to return the current iteration
# Used by iteration_number to return the current iteration
#
# @return int|nil - Current iteration number (0-based) or nil if not in sequence
def get_current_iteration_number()

View File

@ -1,6 +1,6 @@
# Engine Proxy - Combines rendering and orchestration
#
# An EngineProxy is a Playable that can both render visual content
# An engine_proxy is a Playable that can both render visual content
# AND orchestrate sub-animations and sequences. This enables complex
# composite effects that combine multiple animations with timing control.
#
@ -11,7 +11,7 @@
import "./core/param_encoder" as encode_constraints
class EngineProxy : animation.animation
class engine_proxy : animation.animation
# Non-parameter instance variables
var animations # List of child animations
var sequences # List of child sequence managers
@ -80,12 +80,12 @@ class EngineProxy : animation.animation
# Add a child animation, sequence, or value provider
#
# @param obj: Animation|SequenceManager|ValueProvider - The child to add
# @param obj: Animation|sequence_manager|value_provider - The child to add
# @return self for method chaining
def add(obj)
if isinstance(obj, animation.sequence_manager)
return self._add_sequence_manager(obj)
# Check if it's a ValueProvider (before Animation check, as some animations might also be providers)
# Check if it's a value_provider (before Animation check, as some animations might also be providers)
elif isinstance(obj, animation.value_provider)
return self._add_value_provider(obj)
# Check if it's an Animation (or subclass)
@ -93,7 +93,7 @@ class EngineProxy : animation.animation
return self._add_animation(obj)
else
# Unknown type - provide helpful error message
raise "type_error", "only Animation, SequenceManager, or ValueProvider"
raise "type_error", "only Animation, sequence_manager, or value_provider"
end
end
@ -109,7 +109,7 @@ class EngineProxy : animation.animation
# Add a value provider
#
# @param provider: ValueProvider - The value provider instance to add
# @param provider: value_provider - The value provider instance to add
# @return true if successful, false if already in list
def _add_value_provider(provider)
if (self.value_providers.find(provider) == nil)
@ -206,7 +206,7 @@ class EngineProxy : animation.animation
# Remove a value provider
#
# @param obj: ValueProvider instance
# @param obj: value_provider instance
# @return true if actually removed
def _remove_value_provider(obj)
var idx = self.value_providers.find(obj)
@ -219,13 +219,13 @@ class EngineProxy : animation.animation
end
# Generic remove method that delegates to specific remove methods
# @param obj: Animation, SequenceManager, or ValueProvider - The object to remove
# @param obj: Animation, sequence_manager, or value_provider - The object to remove
# @return self for method chaining
def remove(obj)
# Check if it's a SequenceManager
# Check if it's a sequence_manager
if isinstance(obj, animation.sequence_manager)
return self._remove_sequence_manager(obj)
# Check if it's a ValueProvider (before Animation check)
# Check if it's a value_provider (before Animation check)
elif isinstance(obj, animation.value_provider)
return self._remove_value_provider(obj)
# Check if it's an Animation (or subclass)
@ -373,7 +373,7 @@ class EngineProxy : animation.animation
# Render the hybrid animation
# Renders own content first, then all child animations
#
# @param frame: FrameBuffer - The frame buffer to render to
# @param frame: frame_buffer - The frame buffer to render to
# @param time_ms: int - Current time in milliseconds
# @param strip_length: int - Length of the LED strip in pixels (optional, defaults to self.strip_length)
# @return bool - True if frame was modified, false otherwise
@ -464,7 +464,7 @@ class EngineProxy : animation.animation
end
# Get the current iteration number from the innermost sequence context
# Used by IterationNumberProvider to return the current iteration
# Used by iteration_number to return the current iteration
#
# @return int|nil - Current iteration number (0-based) or nil if not in sequence
def get_current_iteration_number()
@ -476,4 +476,4 @@ class EngineProxy : animation.animation
end
return {'engine_proxy': EngineProxy}
return {'engine_proxy': engine_proxy}

View File

@ -1,4 +1,4 @@
# FrameBuffer class for Berry Animation Framework
# frame_buffer class for Berry Animation Framework
#
# This class provides a buffer for storing and manipulating pixel data
# for LED animations. It uses a bytes object for efficient storage and
@ -17,12 +17,12 @@
# so that it is not solidified
import "./core/frame_buffer_ntv" as FrameBufferNtv
class FrameBuffer : FrameBufferNtv
class frame_buffer : FrameBufferNtv
var pixels # Pixel data (bytes object)
var width # Number of pixels
# Initialize a new frame buffer with the specified width
# Takes either an int (width) or an instance of FrameBuffer (instance)
# Takes either an int (width) or an instance of frame_buffer (instance)
def init(width_or_buffer)
if type(width_or_buffer) == 'int'
var width = width_or_buffer
@ -135,11 +135,6 @@ class FrameBuffer : FrameBufferNtv
def copy()
return animation.frame_buffer(self) # return using the self copying constructor
end
# String representation of the frame buffer
def tostring()
return f"FrameBuffer(width={self.width}, pixels={self.pixels})"
end
end
return {'frame_buffer': FrameBuffer}
return {'frame_buffer': frame_buffer}

View File

@ -280,7 +280,7 @@ end
# Export only the encode function (decode not needed - use constraint_mask/constraint_find instead)
# Note: constraint_mask() and constraint_find() are static methods
# in ParameterizedObject class for accessing encoded constraints
# in parameterized_object class for accessing encoded constraints
return {
'enc_params': encode_constraints
}

View File

@ -1,8 +1,8 @@
# ParameterizedObject - Base class for parameter management and playable behavior
# parameterized_object - Base class for parameter management and playable behavior
#
# This class provides a common parameter management system that can be shared
# between Animation and ValueProvider classes. It handles parameter validation,
# storage, and retrieval with support for ValueProvider instances.
# between Animation and value_provider classes. It handles parameter validation,
# storage, and retrieval with support for value_provider instances.
#
# It also provides the common interface for playable objects (animations and sequences)
# that can be started, stopped, and updated over time. This enables:
@ -16,7 +16,7 @@
import "./core/param_encoder" as encode_constraints
class ParameterizedObject
class parameterized_object
var values # Map storing all parameter values
var engine # Reference to the animation engine
var start_time # Time when object started (ms) (int), value is set at first call to update() or render()
@ -101,7 +101,7 @@ class ParameterizedObject
# This is called when accessing a member that doesn't exist as a real instance variable
#
# @param name: string - Parameter name being accessed
# @return any - Resolved parameter value (ValueProvider resolved to actual value)
# @return any - Resolved parameter value (value_provider resolved to actual value)
def member(name)
# if global.debug_animation
# log(f">>> member {name=}", 3)
@ -137,7 +137,7 @@ class ParameterizedObject
# This is called when setting a member that doesn't exist as a real instance variable
#
# @param name: string - Parameter name being set
# @param value: any - Value to set (can be static value or ValueProvider)
# @param value: any - Value to set (can be static value or value_provider)
def setmember(name, value)
# Check if it's a parameter in the class hierarchy and set it with validation
if self.has_param(name)
@ -151,9 +151,9 @@ class ParameterizedObject
# Internal method to set a parameter value with validation
#
# @param name: string - Parameter name
# @param value: any - Value to set (can be static value or ValueProvider)
# @param value: any - Value to set (can be static value or value_provider)
def _set_parameter_value(name, value)
# Validate the value (skip validation for ValueProvider instances)
# Validate the value (skip validation for value_provider instances)
if !animation.is_value_provider(value)
value = self._validate_param(name, value) # Get potentially converted value
end
@ -165,11 +165,11 @@ class ParameterizedObject
self.on_param_changed(name, value)
end
# Internal method to resolve a parameter value (handles ValueProviders)
# Internal method to resolve a parameter value (handles value_providers)
#
# @param name: string - Parameter name
# @param time_ms: int - Current time in milliseconds for ValueProvider resolution
# @return any - Resolved value (static or from ValueProvider)
# @param time_ms: int - Current time in milliseconds for value_provider resolution
# @return any - Resolved value (static or from value_provider)
def _resolve_parameter_value(name, time_ms)
if !self.values.contains(name)
# Return default if available from class hierarchy
@ -182,7 +182,7 @@ class ParameterizedObject
var value = self.values[name]
# Apply produce_value() if it' a ValueProvider
# Apply produce_value() if it' a value_provider
return self.resolve_value(value, name, time_ms)
end
@ -198,7 +198,7 @@ class ParameterizedObject
raise "attribute_error", f"'{classname(self)}' object has no attribute '{name}'"
end
# Accept ValueProvider instances for all parameters
# Accept value_provider instances for all parameters
if animation.is_value_provider(value)
return value
end
@ -315,7 +315,7 @@ class ParameterizedObject
#
# @param name: string - Parameter name
# @param default_value: any - Default value if parameter not found
# @return any - Parameter value or default (may be ValueProvider)
# @return any - Parameter value or default (may be value_provider)
def get_param(name, default_value)
# Check stored values
if self.values.contains(name)
@ -546,13 +546,13 @@ class ParameterizedObject
# var encoded = param_encoder.animation.enc_params({"min": 0, "max": 255, "default": 128})
#
# Checking if constraint contains a field:
# if ParameterizedObject.constraint_mask(encoded, "min")
# if parameterized_object.constraint_mask(encoded, "min")
# print("Has min constraint")
# end
#
# Getting constraint field value:
# var min_val = ParameterizedObject.constraint_find(encoded, "min", 0)
# var max_val = ParameterizedObject.constraint_find(encoded, "max", 255)
# var min_val = parameterized_object.constraint_find(encoded, "min", 0)
# var max_val = parameterized_object.constraint_find(encoded, "max", 255)
# ============================================================================
# Check if an encoded constraint contains a specific field (monolithic, no sub-calls)
#
@ -566,8 +566,8 @@ class ParameterizedObject
#
# Example:
# var encoded = bytes("07 00 00 FF 80") # min=0, max=255, default=128
# ParameterizedObject.constraint_mask(encoded, "min") # => true
# ParameterizedObject.constraint_mask(encoded, "enum") # => false
# parameterized_object.constraint_mask(encoded, "min") # => true
# parameterized_object.constraint_mask(encoded, "enum") # => false
static var _MASK = [
"min", #- 0x01 HAS_MIN-#
"max", #- 0x02, HAS_MAX-#
@ -616,10 +616,10 @@ class ParameterizedObject
#
# Example:
# var encoded = bytes("07 00 00 FF 80") # min=0, max=255, default=128
# ParameterizedObject.constraint_find(encoded, "min", 0) # => 0
# ParameterizedObject.constraint_find(encoded, "max", 255) # => 255
# ParameterizedObject.constraint_find(encoded, "default", 100) # => 128
# ParameterizedObject.constraint_find(encoded, "enum", nil) # => nil (not present)
# parameterized_object.constraint_find(encoded, "min", 0) # => 0
# parameterized_object.constraint_find(encoded, "max", 255) # => 255
# parameterized_object.constraint_find(encoded, "default", 100) # => 128
# parameterized_object.constraint_find(encoded, "enum", nil) # => nil (not present)
static def constraint_find(encoded_bytes, name, default)
@ -728,4 +728,4 @@ class ParameterizedObject
end
end
return {'parameterized_object': ParameterizedObject}
return {'parameterized_object': parameterized_object}

View File

@ -2,7 +2,7 @@
# Handles async execution of animation sequences without blocking delays
# Supports sub-sequences and repeat logic through recursive composition
#
# Extends ParameterizedObject to provide parameter management and playable interface,
# Extends parameterized_object to provide parameter management and playable interface,
# allowing sequences to be treated uniformly with animations by the engine.
#
# Memory-optimized: Uses two parallel arrays instead of array of maps
@ -16,7 +16,7 @@
import "./core/param_encoder" as encode_constraints
class SequenceManager : animation.parameterized_object
class sequence_manager : animation.parameterized_object
# static var DURATION_CLOSURE = -2
# static var DURATION_SUBSEQUENCE = -3
@ -441,4 +441,4 @@ class SequenceManager : animation.parameterized_object
end
end
return {'sequence_manager': SequenceManager }
return {'sequence_manager': sequence_manager }

View File

@ -979,7 +979,7 @@ class SimpleDSLTranspiler
if is_repeat_syntax
# Second syntax: sequence name repeat N times { ... }
# Create a single SequenceManager with fluent interface
# Create a single sequence_manager with fluent interface
self.add(f"var {name}_ = animation.sequence_manager(engine, {repeat_count})")
# Process sequence body - add steps using fluent interface
@ -2810,7 +2810,7 @@ class SimpleDSLTranspiler
self.add("")
# Generate setup_template method (contains all template code)
self.add(" # Template setup method - overrides EngineProxy placeholder")
self.add(" # Template setup method - overrides engine_proxy placeholder")
self.add(" def setup_template()")
self.add(" var engine = self # using 'self' as a proxy to engine object (instead of 'self.engine')")
self.add("")
@ -3101,7 +3101,7 @@ class SimpleDSLTranspiler
return false
end
# For template animations, check if parameter masks an existing parameter from EngineProxy or Animation
# For template animations, check if parameter masks an existing parameter from engine_proxy or Animation
if is_template_animation
var base_class_params = [
"name", "is_running", "priority", "duration", "loop", "opacity", "color"
@ -3109,7 +3109,7 @@ class SimpleDSLTranspiler
for base_param : base_class_params
if param_name == base_param
self.warning(f"Template animation parameter '{param_name}' masks existing parameter from EngineProxy base class. This may cause unexpected behavior. Consider using a different name like 'custom_{param_name}' or '{param_name}_value'.")
self.warning(f"Template animation parameter '{param_name}' masks existing parameter from engine_proxy base class. This may cause unexpected behavior. Consider using a different name like 'custom_{param_name}' or '{param_name}_value'.")
break
end
end

View File

@ -1,7 +1,7 @@
# Breathe Color Provider for Berry Animation Framework
#
# This color provider creates breathing/pulsing color effects by modulating the brightness
# of a base color over time. It inherits from OscillatorValueProvider to leverage its
# of a base color over time. It inherits from oscillator_value to leverage its
# robust time management and waveform generation, then applies the oscillator value
# as brightness modulation to a base color.
#
@ -27,7 +27,7 @@ class breathe_color : animation.oscillator_value
#
# @param engine: AnimationEngine - The animation engine (required)
def init(engine)
# Call parent constructor (OscillatorValueProvider)
# Call parent constructor (oscillator_value)
super(self).init(engine)
# Configure the inherited oscillator for breathing behavior

View File

@ -1,4 +1,4 @@
# closure_value - ValueProvider that wraps a closure/function
# closure_value - value_provider that wraps a closure/function
#
# This provider allows using closures (functions) as value providers.
# The closure is called with (self, param_name, time_ms) parameters when

View File

@ -63,7 +63,7 @@ class ColorCycleColorProvider : animation.color_provider
# Virtual member access - implements the virtual "palette_size" attribute
#
# @param name: string - Parameter name being accessed
# @return any - Resolved parameter value (ValueProvider resolved to actual value)
# @return any - Resolved parameter value (value_provider resolved to actual value)
def member(name)
if name == "palette_size"
return self._get_palette_size()

View File

@ -4,8 +4,8 @@
# Color providers generate colors based on time or values, which can be used by
# renderers or other components that need color information.
#
# color_provider now inherits from ValueProvider, making it a specialized value provider
# for color values. This provides consistency with the ValueProvider system while
# color_provider now inherits from value_provider, making it a specialized value provider
# for color values. This provides consistency with the value_provider system while
# maintaining the specific color-related methods.
#
# Follows the parameterized class specification:
@ -92,8 +92,8 @@ class color_provider : animation.value_provider
end
# Add a method to check if an object is a color provider
# Note: Since color_provider now inherits from ValueProvider, all ColorProviders
# are also ValueProviders and will be detected by animation.is_value_provider()
# Note: Since color_provider now inherits from value_provider, all ColorProviders
# are also value_providers and will be detected by animation.is_value_provider()
def is_color_provider(obj)
return isinstance(obj, animation.color_provider)
end

View File

@ -1,4 +1,4 @@
# IterationNumberProvider - ValueProvider that returns current sequence iteration number
# iteration_number - value_provider that returns current sequence iteration number
#
# This provider returns the current iteration number (0-based) for the innermost
# sequence context, or nil if not called within a sequence.
@ -21,8 +21,8 @@
import "./core/param_encoder" as encode_constraints
#@ solidify:IterationNumberProvider,weak
class IterationNumberProvider : animation.value_provider
#@ solidify:iteration_number,weak
class iteration_number : animation.value_provider
# Produce the current iteration number from the animation engine
#
# @param name: string - Parameter name being requested (ignored)
@ -34,4 +34,4 @@ class IterationNumberProvider : animation.value_provider
end
end
return {'iteration_number': IterationNumberProvider}
return {'iteration_number': iteration_number}

View File

@ -1,7 +1,7 @@
# OscillatorValueProvider for Berry Animation Framework
# oscillator_value for Berry Animation Framework
#
# This value provider generates oscillating values based on time using various waveforms.
# It's based on the original Animate_oscillator class but adapted to work as a ValueProvider.
# It's based on the original Animate_oscillator class but adapted to work as a value_provider.
#
# Supported waveforms:
# - SAWTOOTH (1): Linear ramp from a to b
@ -23,8 +23,8 @@ var EASE_OUT = 7
var ELASTIC = 8
var BOUNCE = 9
#@ solidify:OscillatorValueProvider,weak
class OscillatorValueProvider : animation.value_provider
#@ solidify:oscillator_value,weak
class oscillator_value : animation.value_provider
# Non-parameter instance variables only
var value # current calculated value
@ -38,7 +38,7 @@ class OscillatorValueProvider : animation.value_provider
"duty_cycle": {"min": 0, "max": 255, "default": 127}
})
# Initialize a new OscillatorValueProvider
# Initialize a new oscillator_value
#
# @param engine: AnimationEngine - Reference to the animation engine (required)
def init(engine)
@ -171,7 +171,7 @@ end
# Create a ramp (same as oscillator, for semantic clarity)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New ramp instance
# @return oscillator_value - New ramp instance
def ramp(engine)
var osc = animation.oscillator_value(engine)
osc.form = 1 #-animation.SAWTOOTH-#
@ -181,7 +181,7 @@ end
# Create a linear oscillator (triangle wave)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New linear oscillator instance
# @return oscillator_value - New linear oscillator instance
def linear(engine)
var osc = animation.oscillator_value(engine)
osc.form = 2 #-animation.TRIANGLE-#
@ -191,7 +191,7 @@ end
# Create a smooth oscillator (cosine wave)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New smooth oscillator instance
# @return oscillator_value - New smooth oscillator instance
def smooth(engine)
var osc = animation.oscillator_value(engine)
osc.form = 4 #-animation.COSINE-#
@ -201,7 +201,7 @@ end
# Create a cosine oscillator (alias for smooth - cosine wave)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New cosine oscillator instance
# @return oscillator_value - New cosine oscillator instance
def cosine_osc(engine)
var osc = animation.oscillator_value(engine)
osc.form = 4 #-animation.COSINE-#
@ -211,7 +211,7 @@ end
# Create a sine wave oscillator
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New sine wave instance
# @return oscillator_value - New sine wave instance
def sine_osc(engine)
var osc = animation.oscillator_value(engine)
osc.form = 5 #-animation.SINE-#
@ -221,7 +221,7 @@ end
# Create a square wave oscillator
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New square wave instance
# @return oscillator_value - New square wave instance
def square(engine)
var osc = animation.oscillator_value(engine)
osc.form = 3 #-animation.SQUARE-#
@ -231,7 +231,7 @@ end
# Create an ease-in oscillator (quadratic acceleration)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New ease-in instance
# @return oscillator_value - New ease-in instance
def ease_in(engine)
var osc = animation.oscillator_value(engine)
osc.form = 6 #-animation.EASE_IN-#
@ -241,7 +241,7 @@ end
# Create an ease-out oscillator (quadratic deceleration)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New ease-out instance
# @return oscillator_value - New ease-out instance
def ease_out(engine)
var osc = animation.oscillator_value(engine)
osc.form = 7 #-animation.EASE_OUT-#
@ -251,7 +251,7 @@ end
# Create an elastic oscillator (spring-like overshoot and oscillation)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New elastic instance
# @return oscillator_value - New elastic instance
def elastic(engine)
var osc = animation.oscillator_value(engine)
osc.form = 8 #-animation.ELASTIC-#
@ -261,7 +261,7 @@ end
# Create a bounce oscillator (ball-like bouncing with decreasing amplitude)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New bounce instance
# @return oscillator_value - New bounce instance
def bounce(engine)
var osc = animation.oscillator_value(engine)
osc.form = 9 #-animation.BOUNCE-#
@ -271,7 +271,7 @@ end
# Create a sawtooth oscillator (alias for ramp - linear progression from min_value to max_value)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New sawtooth instance
# @return oscillator_value - New sawtooth instance
def sawtooth(engine)
var osc = animation.oscillator_value(engine)
osc.form = 1 #-animation.SAWTOOTH-#
@ -281,7 +281,7 @@ end
# Create a triangle oscillator (alias for linear - triangle wave from min_value to max_value and back)
#
# @param engine: AnimationEngine - Animation engine reference
# @return OscillatorValueProvider - New triangle instance
# @return oscillator_value - New triangle instance
def triangle(engine)
var osc = animation.oscillator_value(engine)
osc.form = 2 #-animation.TRIANGLE-#
@ -310,4 +310,4 @@ return {'ramp': ramp,
'EASE_OUT': EASE_OUT,
'ELASTIC': ELASTIC,
'BOUNCE': BOUNCE,
'oscillator_value': OscillatorValueProvider}
'oscillator_value': oscillator_value}

View File

@ -1,4 +1,4 @@
# StaticColorProvider for Berry Animation Framework
# static_color for Berry Animation Framework
#
# This color provider returns a single, static color.
# It's the simplest implementation of the color_provider interface.
@ -9,8 +9,8 @@
import "./core/param_encoder" as encode_constraints
#@ solidify:StaticColorProvider,weak
class StaticColorProvider : animation.color_provider
#@ solidify:static_color,weak
class static_color : animation.color_provider
# Parameter definitions
static var PARAMS = animation.enc_params({
"color": {"default": 0xFFFFFFFF} # Default to white
@ -45,4 +45,4 @@ class StaticColorProvider : animation.color_provider
end
end
return {'static_color': StaticColorProvider}
return {'static_color': static_color}

View File

@ -1,4 +1,4 @@
# StaticValueProvider for Berry Animation Framework
# static_value for Berry Animation Framework
#
# This value provider returns a single, static value for any parameter type.
# It's a dummy implementation that serves as a wrapper for static values,
@ -13,14 +13,14 @@
import "./core/param_encoder" as encode_constraints
#@ solidify:StaticValueProvider,weak
class StaticValueProvider : animation.value_provider
#@ solidify:static_value,weak
class static_value : animation.value_provider
# Parameter definitions
static var PARAMS = animation.enc_params({
"value": {"default": nil, "type": "any"}
})
# # Comparison operators to make StaticValueProvider work with validation code
# # Comparison operators to make static_value work with validation code
# def <(other)
# return self.value < int(other)
# end
@ -66,8 +66,8 @@ class StaticValueProvider : animation.value_provider
# String representation of the provider
# def tostring()
# return f"StaticValueProvider(value={self.value})"
# return f"static_value(value={self.value})"
# end
end
return {'static_value': StaticValueProvider}
return {'static_value': static_value}

View File

@ -1,4 +1,4 @@
# ValueProvider interface for Berry Animation Framework
# value_provider interface for Berry Animation Framework
#
# This defines the core interface for value providers in the animation framework.
# Value providers generate values based on time, which can be used by animations
@ -7,15 +7,15 @@
# This is the super-class for all value provider variants and provides the interface
# that animations can use to get dynamic values for their parameters.
#
# ValueProviders follow the parameterized class specification:
# value_providers follow the parameterized class specification:
# - Constructor takes only 'engine' parameter
# - All other parameters set via virtual member assignment
# - No setter/getter methods for parameters
import "./core/param_encoder" as encode_constraints
#@ solidify:ValueProvider,weak
class ValueProvider : animation.parameterized_object
#@ solidify:value_provider,weak
class value_provider : animation.parameterized_object
# Produce a value for a specific parameter name and time
# This is the main method that subclasses should override
@ -42,5 +42,5 @@ def is_value_provider(obj)
return isinstance(obj, animation.value_provider)
end
return {'value_provider': ValueProvider,
return {'value_provider': value_provider,
'is_value_provider': is_value_provider}

View File

@ -9161,7 +9161,7 @@ be_local_closure(class_SimpleDSLTranspiler__validate_template_parameter_name,
/* K34 */ be_nested_str_weak(loop),
/* K35 */ be_nested_str_weak(opacity),
/* K36 */ be_nested_str_weak(warning),
/* K37 */ be_nested_str_weak(Template_X20animation_X20parameter_X20_X27_X25s_X27_X20masks_X20existing_X20parameter_X20from_X20EngineProxy_X20base_X20class_X2E_X20This_X20may_X20cause_X20unexpected_X20behavior_X2E_X20Consider_X20using_X20a_X20different_X20name_X20like_X20_X27custom__X25s_X27_X20or_X20_X27_X25s_value_X27_X2E),
/* K37 */ be_nested_str_weak(Template_X20animation_X20parameter_X20_X27_X25s_X27_X20masks_X20existing_X20parameter_X20from_X20engine_proxy_X20base_X20class_X2E_X20This_X20may_X20cause_X20unexpected_X20behavior_X2E_X20Consider_X20using_X20a_X20different_X20name_X20like_X20_X27custom__X25s_X27_X20or_X20_X27_X25s_value_X27_X2E),
}),
be_str_weak(_validate_template_parameter_name),
&be_const_str_solidified,
@ -14936,7 +14936,7 @@ be_local_closure(class_SimpleDSLTranspiler_generate_template_animation_class,
/* K28 */ be_nested_str_weak(_X20_X20_X20_X20_X22_X25s_X22_X3A_X20_X7B_X22type_X22_X3A_X20_X22_X25s_X22_X7D_X25s),
/* K29 */ be_nested_str_weak(_X20_X20_X20_X20_X22_X25s_X22_X3A_X20_X7B_X7D_X25s),
/* K30 */ be_nested_str_weak(_X20_X20_X7D_X29),
/* K31 */ be_nested_str_weak(_X20_X20_X23_X20Template_X20setup_X20method_X20_X2D_X20overrides_X20EngineProxy_X20placeholder),
/* K31 */ be_nested_str_weak(_X20_X20_X23_X20Template_X20setup_X20method_X20_X2D_X20overrides_X20engine_proxy_X20placeholder),
/* K32 */ be_nested_str_weak(_X20_X20def_X20setup_template_X28_X29),
/* K33 */ be_nested_str_weak(_X20_X20_X20_X20var_X20engine_X20_X3D_X20self_X20_X20_X20_X23_X20using_X20_X27self_X27_X20as_X20a_X20proxy_X20to_X20engine_X20object_X20_X28instead_X20of_X20_X27self_X2Eengine_X27_X29),
/* K34 */ be_nested_str_weak(SimpleDSLTranspiler),

View File

@ -1,4 +1,4 @@
# Black Frame Fix Test for SequenceManager
# Black Frame Fix Test for sequence_manager
# Tests the atomic transition functionality that eliminates black frames
# between animation transitions with closure steps
#

View File

@ -1,6 +1,6 @@
# Constraint Encoding Test Suite
#
# Comprehensive tests for animation.enc_params() and ParameterizedObject static methods:
# Comprehensive tests for animation.enc_params() and parameterized_object static methods:
# - constraint_mask()
# - constraint_find()
#
@ -260,7 +260,7 @@ var gradient_encoded = animation.enc_params(gradient_params)
assert_equal(animation.parameterized_object.constraint_mask(gradient_encoded["color"], "nillable"), 0x20, "5.4a: color nillable")
assert_equal(animation.parameterized_object.constraint_find(gradient_encoded["color"], "default", 999), nil, "5.4b: color default nil")
# Test 5.5: OscillatorValueProvider PARAMS (large enum)
# Test 5.5: oscillator_value PARAMS (large enum)
var oscillator_params = {
"min_value": {"default": 0},
"max_value": {"default": 100},

View File

@ -1,12 +1,12 @@
#!/usr/bin/env berry
# Core ValueProvider system test - focuses only on the essential functionality
# Core value_provider system test - focuses only on the essential functionality
# Mock the animation module for testing
var animation = {}
# Define the ValueProvider base class
class ValueProvider
# Define the value_provider base class
class value_provider
def get_value(time_ms)
return nil
end
@ -16,8 +16,8 @@ class ValueProvider
end
end
# Define the StaticValueProvider
class StaticValueProvider : ValueProvider
# Define the static_value
class static_value : value_provider
var value
def init(value)
@ -41,29 +41,29 @@ class StaticValueProvider : ValueProvider
end
def tostring()
return f"StaticValueProvider(value={self.value})"
return f"static_value(value={self.value})"
end
end
# Helper function to check if object is a value provider
def is_value_provider(obj)
return obj != nil && type(obj) == "instance" && isinstance(obj, ValueProvider)
return obj != nil && type(obj) == "instance" && isinstance(obj, value_provider)
end
# Test the core functionality
def test_core_functionality()
print("=== Core ValueProvider System Test ===")
print("=== Core value_provider System Test ===")
# Test 1: Basic ValueProvider interface
print("1. Testing ValueProvider interface...")
var base_provider = ValueProvider()
# Test 1: Basic value_provider interface
print("1. Testing value_provider interface...")
var base_provider = value_provider()
assert(base_provider.get_value(1000) == nil, "Base provider should return nil")
assert(base_provider.update(1000) == false, "Base provider update should return false")
print(" ✓ Base interface works")
# Test 2: StaticValueProvider basic functionality
print("2. Testing StaticValueProvider...")
var static_provider = StaticValueProvider(42)
# Test 2: static_value basic functionality
print("2. Testing static_value...")
var static_provider = static_value(42)
assert(static_provider.get_value(1000) == 42, "Should return static value")
assert(static_provider.update(1000) == false, "Update should return false")
print(" ✓ Static provider basic functionality works")
@ -85,8 +85,8 @@ def test_core_functionality()
# Test 4: Provider detection
print("4. Testing provider detection...")
assert(is_value_provider(static_provider) == true, "Should detect StaticValueProvider")
assert(is_value_provider(base_provider) == true, "Should detect ValueProvider")
assert(is_value_provider(static_provider) == true, "Should detect static_value")
assert(is_value_provider(base_provider) == true, "Should detect value_provider")
assert(is_value_provider(42) == false, "Should not detect integer")
assert(is_value_provider("hello") == false, "Should not detect string")
assert(is_value_provider(nil) == false, "Should not detect nil")
@ -124,9 +124,9 @@ def test_core_functionality()
print("=== All core tests passed! ===")
print()
print("Core ValueProvider system is working correctly:")
print("- ValueProvider base interface")
print("- StaticValueProvider with universal method support")
print("Core value_provider system is working correctly:")
print("- value_provider base interface")
print("- static_value with universal method support")
print("- Provider detection")
print("- Parameter resolution with method-specific fallback")

View File

@ -135,9 +135,9 @@ def test_crenel_with_dynamic_color_provider()
print("✓ CrenelPositionAnimation with dynamic color_provider test passed")
end
# Test CrenelPositionAnimation with generic ValueProvider
# Test CrenelPositionAnimation with generic value_provider
def test_crenel_with_generic_value_provider()
print("Testing CrenelPositionAnimation with generic ValueProvider...")
print("Testing CrenelPositionAnimation with generic value_provider...")
# Create engine and strip for testing
var strip = global.Leds(10)
@ -153,7 +153,7 @@ def test_crenel_with_generic_value_provider()
var crenel = animation.crenel_animation(engine)
# Set parameters via virtual member assignment
crenel.color = static_provider # generic ValueProvider
crenel.color = static_provider # generic value_provider
crenel.back_color = 0x00000000 # transparent (default)
crenel.pos = 2
crenel.pulse_size = 3
@ -170,10 +170,10 @@ def test_crenel_with_generic_value_provider()
frame.clear()
var result = crenel.render(frame, engine.time_ms, engine.strip_length)
assert(result == true, "Render should succeed with generic ValueProvider")
assert(result == true, "Render should succeed with generic value_provider")
assert(crenel.is_running == true, "Animation should be running")
print("✓ CrenelPositionAnimation with generic ValueProvider test passed")
print("✓ CrenelPositionAnimation with generic value_provider test passed")
end
# Test direct color assignment with both types

View File

@ -17,7 +17,7 @@ import animation_dsl
import string
# Test class to verify value provider parameter validation and arithmetic expression fixes
class DSLValueProviderValidationTest
class DSLvalue_providerValidationTest
var test_results
def init()
@ -457,10 +457,10 @@ class DSLValueProviderValidationTest
end
# Run tests
var test_runner = DSLValueProviderValidationTest()
var test_runner = DSLvalue_providerValidationTest()
test_runner.run_all_tests()
# Export for use in other test files
return {
"DSLValueProviderValidationTest": DSLValueProviderValidationTest
"DSLvalue_providerValidationTest": DSLvalue_providerValidationTest
}

View File

@ -1,11 +1,11 @@
# Unit tests for EngineProxy class
# Unit tests for engine_proxy class
#
# Tests the ability to create animations that combine both rendering
# and orchestration of sub-animations and sequences.
import animation
print("Starting EngineProxy Tests...")
print("Starting engine_proxy Tests...")
# Create test engine
var strip = global.Leds(30)
@ -15,7 +15,7 @@ var engine = animation.create_engine(strip)
print("\n=== Test 1: Basic Creation ===")
var proxy = animation.engine_proxy(engine)
assert(proxy != nil, "Engine proxy should be created")
assert(isinstance(proxy, animation.parameterized_object), "Engine proxy should be a ParameterizedObject")
assert(isinstance(proxy, animation.parameterized_object), "Engine proxy should be a parameterized_object")
assert(isinstance(proxy, animation.animation), "Engine proxy should be an Animation")
assert(proxy.is_running == false, "Engine proxy should not be running initially")
print("✓ Basic creation test passed")
@ -112,16 +112,16 @@ var proxy3 = animation.engine_proxy(engine)
proxy3.color = 0xFFFF00FF # Magenta
proxy3.priority = 15
# Add to engine (should work since EngineProxy is a Playable)
# Add to engine (should work since engine_proxy is a Playable)
engine.add(proxy3)
assert(size(engine.get_animations()) == 1, "Engine should have 1 animation")
print("✓ Engine integration test passed")
# Test 11: Type checking
print("\n=== Test 11: Type Checking ===")
assert(isinstance(proxy, animation.parameterized_object), "Engine proxy is a ParameterizedObject")
assert(isinstance(proxy, animation.parameterized_object), "Engine proxy is a parameterized_object")
assert(isinstance(proxy, animation.animation), "Engine proxy is an Animation")
assert(!isinstance(proxy, animation.sequence_manager), "Engine proxy is not a SequenceManager")
assert(!isinstance(proxy, animation.sequence_manager), "Engine proxy is not a sequence_manager")
print("✓ Type checking test passed")
# Test 12: String representation
@ -132,5 +132,5 @@ print(f"Engine proxy string: {str_repr}")
print("✓ String representation test passed")
print("\n" + "="*50)
print("🎉 All EngineProxy tests passed!")
print("🎉 All engine_proxy tests passed!")
print("="*50)

View File

@ -1,13 +1,13 @@
# Test file for FrameBuffer class
# Test file for frame_buffer class
#
# This file contains tests for the FrameBuffer class
# This file contains tests for the frame_buffer class
#
# Command to run test is:
# ./berry -s -g -m lib/libesp32/berry_animation -e "import tasmota" lib/libesp32/berry_animation/tests/frame_buffer_test.be
import animation
print("Testing FrameBuffer...")
print("Testing frame_buffer...")
# Create a frame buffer with 10 pixels
var fb = animation.frame_buffer(10)
@ -248,5 +248,5 @@ var max_pixel = max_test.get_pixel_color(0)
var max_alpha = (max_pixel >> 24) & 0xFF
assert(max_alpha == 255, f"Alpha should be capped at 255, got {max_alpha}")
print("All FrameBuffer tests passed!")
print("All frame_buffer tests passed!")
return true

View File

@ -67,9 +67,9 @@ def test_get_param_value_with_color_provider()
print("✓ get_param_value() with color_provider test passed")
end
# Test that get_param_value() calls produce_value() for generic ValueProviders
# Test that get_param_value() calls produce_value() for generic value_providers
def test_get_param_value_with_generic_provider()
print("Testing get_param_value() with generic ValueProvider...")
print("Testing get_param_value() with generic value_provider...")
# Create a test animation using new constructor pattern
var test_anim = animation.animation(mock_engine)
@ -78,8 +78,8 @@ def test_get_param_value_with_generic_provider()
test_anim.loop = false
test_anim.opacity = 255
# Create a generic ValueProvider that we can track calls on
class TrackingValueProvider : animation.value_provider
# Create a generic value_provider that we can track calls on
class Trackingvalue_provider : animation.value_provider
var value
var produce_value_called
@ -99,9 +99,9 @@ def test_get_param_value_with_generic_provider()
end
end
var tracking_provider = TrackingValueProvider(mock_engine, 42)
var tracking_provider = Trackingvalue_provider(mock_engine, 42)
# Set the ValueProvider (using the 'priority' parameter that exists in base Animation)
# Set the value_provider (using the 'priority' parameter that exists in base Animation)
test_anim.priority = tracking_provider
# Call get_param_value() - should call produce_value()
@ -110,12 +110,12 @@ def test_get_param_value_with_generic_provider()
assert(result == 42, "Should return the value")
assert(tracking_provider.produce_value_called == 1, "Should call produce_value() once")
print("✓ get_param_value() with generic ValueProvider test passed")
print("✓ get_param_value() with generic value_provider test passed")
end
# Test that get_param_value() calls produce_value() method consistently
def test_get_param_value_with_context_aware_provider()
print("Testing get_param_value() with context-aware ValueProvider...")
print("Testing get_param_value() with context-aware value_provider...")
# Create a test animation using new constructor pattern
var test_anim = animation.animation(mock_engine)
@ -124,7 +124,7 @@ def test_get_param_value_with_context_aware_provider()
test_anim.loop = false
test_anim.opacity = 255
# Create a ValueProvider that returns different values based on parameter name
# Create a value_provider that returns different values based on parameter name
class ContextAwareProvider : animation.value_provider
var base_value
var produce_value_called
@ -154,7 +154,7 @@ def test_get_param_value_with_context_aware_provider()
var context_provider = ContextAwareProvider(mock_engine, 5)
# Set the ValueProvider (using the 'duration' parameter that exists in base Animation)
# Set the value_provider (using the 'duration' parameter that exists in base Animation)
test_anim.duration = context_provider
# Call get_param_value() - should call produce_value() with parameter name

View File

@ -1,4 +1,4 @@
# Test suite for OscillatorValueProvider ease_in and ease_out functionality
# Test suite for oscillator_value ease_in and ease_out functionality
#
# This test verifies that the new EASE_IN and EASE_OUT waveforms work correctly
# and produce the expected easing curves.
@ -214,7 +214,7 @@ end
# Run all tests
def run_oscillator_ease_tests()
print("=== OscillatorValueProvider Ease Tests ===")
print("=== oscillator_value Ease Tests ===")
try
test_ease_in_waveform()
@ -225,7 +225,7 @@ def run_oscillator_ease_tests()
test_ease_tostring()
test_ease_constants()
print("=== All OscillatorValueProvider ease tests passed! ===")
print("=== All oscillator_value ease tests passed! ===")
return true
except .. as e, msg
print(f"Test failed: {e} - {msg}")

View File

@ -1,4 +1,4 @@
# Test suite for OscillatorValueProvider ELASTIC and BOUNCE functionality
# Test suite for oscillator_value ELASTIC and BOUNCE functionality
#
# This test verifies that the new ELASTIC and BOUNCE waveforms work correctly
# and produce the expected spring-like and bouncing curves.
@ -246,7 +246,7 @@ end
# Run all tests
def run_oscillator_elastic_bounce_tests()
print("=== OscillatorValueProvider Elastic & Bounce Tests ===")
print("=== oscillator_value Elastic & Bounce Tests ===")
try
test_elastic_waveform()
@ -257,7 +257,7 @@ def run_oscillator_elastic_bounce_tests()
test_elastic_bounce_constants()
test_elastic_bounce_characteristics()
print("=== All OscillatorValueProvider elastic & bounce tests passed! ===")
print("=== All oscillator_value elastic & bounce tests passed! ===")
return true
except .. as e, msg
print(f"Test failed: {e} - {msg}")

View File

@ -1,6 +1,6 @@
# Test suite for OscillatorValueProvider
# Test suite for oscillator_value
#
# This test verifies that the OscillatorValueProvider works correctly
# This test verifies that the oscillator_value works correctly
# with all waveform types and parameter configurations using the new parameterized API.
import animation
@ -23,7 +23,7 @@ var mock_engine = MockEngine()
# Test basic oscillator functionality
def test_oscillator_basic()
print("Testing OscillatorValueProvider basic functionality...")
print("Testing oscillator_value basic functionality...")
# Create oscillator using new parameterized API
var osc = animation.oscillator_value(mock_engine)
@ -53,7 +53,7 @@ def test_oscillator_basic()
assert(osc.min_value == 10, "Starting value should be set to 10")
assert(osc.max_value == 90, "End value should be set to 90")
print("✓ OscillatorValueProvider basic functionality test passed")
print("✓ oscillator_value basic functionality test passed")
end
# Test sawtooth waveform
@ -373,14 +373,14 @@ def test_produce_value_method()
print("✓ produce_value method test passed")
end
# Test ValueProvider interface compliance
# Test value_provider interface compliance
def test_value_provider_interface()
print("Testing ValueProvider interface compliance...")
print("Testing value_provider interface compliance...")
var osc = animation.oscillator_value(mock_engine)
# Test that it's recognized as a value provider
assert(animation.is_value_provider(osc) == true, "OscillatorValueProvider should be recognized as ValueProvider")
assert(animation.is_value_provider(osc) == true, "oscillator_value should be recognized as value_provider")
# Test that produce_value() works with time parameter
var value = osc.produce_value("test", mock_engine.time_ms)
@ -390,7 +390,7 @@ def test_value_provider_interface()
var result = osc.start(mock_engine.time_ms)
assert(result == osc, "start() should return self for method chaining")
print("✓ ValueProvider interface compliance test passed")
print("✓ value_provider interface compliance test passed")
end
# Test edge cases and error handling
@ -526,7 +526,7 @@ end
# Run all tests
def run_oscillator_value_provider_tests()
print("=== OscillatorValueProvider Tests ===")
print("=== oscillator_value Tests ===")
try
test_oscillator_basic()
@ -543,7 +543,7 @@ def run_oscillator_value_provider_tests()
test_edge_cases()
test_tostring()
print("=== All OscillatorValueProvider tests passed! ===")
print("=== All oscillator_value tests passed! ===")
return true
except .. as e, msg
print(f"Test failed: {e} - {msg}")

View File

@ -1,16 +1,16 @@
# Test suite for parameter validation system
#
# This test verifies that the parameter validation system correctly accepts
# ValueProvider instances for integer and real parameters.
# value_provider instances for integer and real parameters.
import animation
import global
import "./core/param_encoder" as encode_constraints
# Test that parameters accept ValueProviders and integers only
# Test that parameters accept value_providers and integers only
def test_parameter_accepts_value_providers()
print("Testing parameter validation with ValueProviders...")
print("Testing parameter validation with value_providers...")
# Create engine for testing
var strip = global.Leds()
@ -27,20 +27,20 @@ def test_parameter_accepts_value_providers()
assert(test_anim.set_param("opacity", 42) == true, "Should accept static integer")
assert(test_anim.get_param("opacity", 0) == 42, "Should return static integer")
# Test with StaticValueProvider
# Test with static_value
var static_provider = animation.static_value(engine)
static_provider.value = 123
assert(test_anim.set_param("opacity", static_provider) == true, "Should accept StaticValueProvider")
assert(test_anim.set_param("opacity", static_provider) == true, "Should accept static_value")
# Test with OscillatorValueProvider
# Test with oscillator_value
var oscillator = animation.oscillator_value(engine)
oscillator.min_value = 0
oscillator.max_value = 255
oscillator.duration = 1000
oscillator.form = animation.SAWTOOTH
assert(test_anim.set_param("opacity", oscillator) == true, "Should accept OscillatorValueProvider")
assert(test_anim.set_param("opacity", oscillator) == true, "Should accept oscillator_value")
print("✓ Parameter validation with ValueProviders test passed")
print("✓ Parameter validation with value_providers test passed")
end
# Test that loop parameter handles boolean values correctly
@ -91,9 +91,9 @@ def test_range_validation()
print("✓ Range validation test passed")
end
# Test range validation is skipped for ValueProviders
# Test range validation is skipped for value_providers
def test_range_validation_with_providers()
print("Testing range validation with ValueProviders...")
print("Testing range validation with value_providers...")
# Create engine for testing
var strip = global.Leds()
@ -107,15 +107,15 @@ def test_range_validation_with_providers()
assert(test_anim.set_param("opacity", 0) == true, "Should accept minimum value")
assert(test_anim.set_param("opacity", 255) == true, "Should accept maximum value")
# Test that ValueProviders bypass range validation
# Test that value_providers bypass range validation
# (since they provide dynamic values that can't be validated at set time)
var oscillator = animation.oscillator_value(engine)
oscillator.min_value = -50 # Outside range
oscillator.max_value = 300 # Outside range
oscillator.duration = 1000
assert(test_anim.set_param("opacity", oscillator) == true, "Should accept ValueProvider even if it might produce out-of-range values")
assert(test_anim.set_param("opacity", oscillator) == true, "Should accept value_provider even if it might produce out-of-range values")
print("✓ Range validation with ValueProviders test passed")
print("✓ Range validation with value_providers test passed")
end
# Test type validation
@ -181,12 +181,12 @@ def test_type_validation()
assert(test_obj.set_param("any_param", test_instance) == true, "Should accept instance for any_param")
assert(test_obj.set_param("any_param", 3.14) == true, "Should accept real for any_param")
# Test that ValueProviders bypass type validation
# Test that value_providers bypass type validation
var static_provider = animation.static_value(engine)
static_provider.value = 42 # Use a valid value for the provider itself
assert(test_obj.set_param("int_param", static_provider) == true, "Should accept ValueProvider for any type")
assert(test_obj.set_param("string_param", static_provider) == true, "Should accept ValueProvider for any type")
assert(test_obj.set_param("bool_param", static_provider) == true, "Should accept ValueProvider for any type")
assert(test_obj.set_param("int_param", static_provider) == true, "Should accept value_provider for any type")
assert(test_obj.set_param("string_param", static_provider) == true, "Should accept value_provider for any type")
assert(test_obj.set_param("bool_param", static_provider) == true, "Should accept value_provider for any type")
print("✓ Type validation test passed")
end

View File

@ -1,6 +1,6 @@
# Test suite for ParameterizedObject
# Test suite for parameterized_object
#
# This test verifies that the ParameterizedObject base class works correctly
# This test verifies that the parameterized_object base class works correctly
# and provides proper virtual parameter management.
import animation
@ -24,11 +24,11 @@ end
var mock_engine = MockEngine()
# Test basic ParameterizedObject functionality
# Test basic parameterized_object functionality
def test_parameterized_object_basic()
print("Testing basic ParameterizedObject functionality...")
print("Testing basic parameterized_object functionality...")
# Create a simple test class that extends ParameterizedObject
# Create a simple test class that extends parameterized_object
class TestObject : animation.parameterized_object
# No instance variables for parameters - they're handled by the virtual system
@ -92,7 +92,7 @@ def test_parameterized_object_basic()
# Test non-existent parameter
assert(obj.set_param("invalid_param", 42) == false, "Should reject unknown parameter")
print("✓ Basic ParameterizedObject test passed")
print("✓ Basic parameterized_object test passed")
end
# Test class hierarchy parameter inheritance
@ -144,9 +144,9 @@ def test_parameter_hierarchy()
print("✓ Parameter hierarchy test passed")
end
# Test ValueProvider as parameter
# Test value_provider as parameter
def test_value_provider_as_parameter()
print("Testing ValueProvider as parameter...")
print("Testing value_provider as parameter...")
# Create a simple test class
class TestClass : animation.parameterized_object
@ -161,8 +161,8 @@ def test_value_provider_as_parameter()
var obj = TestClass(mock_engine)
# Create a mock ValueProvider
class MockValueProvider : animation.value_provider
# Create a mock value_provider
class Mockvalue_provider : animation.value_provider
var test_value
def init(engine, value)
super(self).init(engine)
@ -176,10 +176,10 @@ def test_value_provider_as_parameter()
end
end
var provider = MockValueProvider(mock_engine, 75)
var provider = Mockvalue_provider(mock_engine, 75)
# Set ValueProvider as parameter (should bypass validation)
assert(obj.set_param("dynamic_value", provider) == true, "Should accept ValueProvider as parameter")
# Set value_provider as parameter (should bypass validation)
assert(obj.set_param("dynamic_value", provider) == true, "Should accept value_provider as parameter")
# Test that get_param returns the provider itself
var returned_provider = obj.get_param("dynamic_value")
@ -189,12 +189,12 @@ def test_value_provider_as_parameter()
assert(returned_provider.produce_value("test", 1000) == 75, "Returned provider should produce expected value")
# Test that virtual member access resolves the provider
assert(obj.dynamic_value == 75, "Virtual member should resolve ValueProvider")
assert(obj.dynamic_value == 75, "Virtual member should resolve value_provider")
# Test get_param_value explicitly
assert(obj.get_param_value("dynamic_value", 1000) == 75, "Should resolve ValueProvider value")
assert(obj.get_param_value("dynamic_value", 1000) == 75, "Should resolve value_provider value")
print("✓ ValueProvider as parameter test passed")
print("✓ value_provider as parameter test passed")
end
# Test parameter metadata
@ -460,7 +460,7 @@ end
# Run all tests
def run_parameterized_object_tests()
print("=== ParameterizedObject Tests ===")
print("=== parameterized_object Tests ===")
try
test_parameterized_object_basic()
@ -472,7 +472,7 @@ def run_parameterized_object_tests()
test_engine_requirement()
test_equality_operator()
print("=== All ParameterizedObject tests passed! ===")
print("=== All parameterized_object tests passed! ===")
return true
except .. as e, msg
print(f"Test failed: {e} - {msg}")

View File

@ -138,7 +138,7 @@ assert(anim.opacity == 255, "Opacity should be set correctly")
# Test color provider integration
assert(anim.color_provider != nil, "Internal color provider should exist")
assert(animation.is_value_provider(anim.color_provider), "Internal provider should be a ValueProvider")
assert(animation.is_value_provider(anim.color_provider), "Internal provider should be a value_provider")
# Test that color parameter is set to internal provider
var raw_color_param = anim.get_param("color")

View File

@ -1,4 +1,4 @@
# Unit tests for SequenceManager with multiple concurrent sequences
# Unit tests for sequence_manager with multiple concurrent sequences
#
# Command to run test is:
# ./berry -s -g -m lib/libesp32/berry_animation -e "import tasmota" lib/libesp32/berry_animation/tests/sequence_manager_layering_test.be
@ -7,7 +7,7 @@ import string
import animation
def test_multiple_sequence_managers()
print("=== Multiple SequenceManager Tests ===")
print("=== Multiple sequence_manager Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -80,7 +80,7 @@ def test_multiple_sequence_managers()
end
def test_sequence_manager_coordination()
print("=== SequenceManager Coordination Tests ===")
print("=== sequence_manager Coordination Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -145,7 +145,7 @@ def test_sequence_manager_coordination()
end
def test_sequence_manager_engine_integration()
print("=== SequenceManager Engine Integration Tests ===")
print("=== sequence_manager Engine Integration Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -203,7 +203,7 @@ def test_sequence_manager_engine_integration()
end
def test_sequence_manager_removal()
print("=== SequenceManager Removal Tests ===")
print("=== sequence_manager Removal Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -245,7 +245,7 @@ def test_sequence_manager_removal()
end
def test_sequence_manager_clear_all()
print("=== SequenceManager Clear All Tests ===")
print("=== sequence_manager Clear All Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -302,7 +302,7 @@ def test_sequence_manager_clear_all()
end
def test_sequence_manager_stress()
print("=== SequenceManager Stress Tests ===")
print("=== sequence_manager Stress Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -593,7 +593,7 @@ end
# Run all layering tests
def run_all_sequence_manager_layering_tests()
print("Starting SequenceManager Layering Tests...")
print("Starting sequence_manager Layering Tests...")
test_multiple_sequence_managers()
test_sequence_manager_coordination()
@ -607,7 +607,7 @@ def run_all_sequence_manager_layering_tests()
test_dsl_if_statement_nested()
test_dsl_if_vs_repeat_comparison()
print("\n🎉 All SequenceManager layering tests passed!")
print("\n🎉 All sequence_manager layering tests passed!")
return true
end

View File

@ -1,4 +1,4 @@
# Unit tests for the SequenceManager class
# Unit tests for the sequence_manager class
#
# Command to run test is:
# ./berry -s -g -m lib/libesp32/berry_animation -e "import tasmota" lib/libesp32/berry_animation/tests/sequence_manager_test.be
@ -9,10 +9,10 @@ import global
import tasmota
def test_sequence_manager_basic()
print("=== SequenceManager Basic Tests ===")
print("=== sequence_manager Basic Tests ===")
# Test SequenceManager class exists
assert(animation.sequence_manager != nil, "SequenceManager class should be defined")
# Test sequence_manager class exists
assert(animation.sequence_manager != nil, "sequence_manager class should be defined")
# Create strip and engine for testing
var strip = global.Leds(30)
@ -32,7 +32,7 @@ def test_sequence_manager_basic()
end
def test_sequence_manager_step_creation()
print("=== SequenceManager Step Creation Tests ===")
print("=== sequence_manager Step Creation Tests ===")
# Create test animation using new parameterized API
var strip = global.Leds(30)
@ -71,7 +71,7 @@ def test_sequence_manager_step_creation()
end
def test_sequence_manager_execution()
print("=== SequenceManager Execution Tests ===")
print("=== sequence_manager Execution Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -117,7 +117,7 @@ def test_sequence_manager_execution()
end
def test_sequence_manager_timing()
print("=== SequenceManager Timing Tests ===")
print("=== sequence_manager Timing Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -170,7 +170,7 @@ def test_sequence_manager_timing()
end
def test_sequence_manager_step_info()
print("=== SequenceManager Step Info Tests ===")
print("=== sequence_manager Step Info Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -199,7 +199,7 @@ def test_sequence_manager_step_info()
end
def test_sequence_manager_stop()
print("=== SequenceManager Stop Tests ===")
print("=== sequence_manager Stop Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -233,7 +233,7 @@ def test_sequence_manager_stop()
end
def test_sequence_manager_is_running()
print("=== SequenceManager Running State Tests ===")
print("=== sequence_manager Running State Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -270,7 +270,7 @@ def test_sequence_manager_is_running()
end
def test_sequence_manager_assignment_steps()
print("=== SequenceManager Assignment Steps Tests ===")
print("=== sequence_manager Assignment Steps Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -328,7 +328,7 @@ def test_sequence_manager_assignment_steps()
end
def test_sequence_manager_complex_sequence()
print("=== SequenceManager Complex Sequence Tests ===")
print("=== sequence_manager Complex Sequence Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -405,7 +405,7 @@ def test_sequence_manager_complex_sequence()
end
def test_sequence_manager_integration()
print("=== SequenceManager Integration Tests ===")
print("=== sequence_manager Integration Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -450,7 +450,7 @@ def test_sequence_manager_integration()
end
def test_sequence_manager_parametric_repeat_counts()
print("=== SequenceManager Parametric Repeat Count Tests ===")
print("=== sequence_manager Parametric Repeat Count Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -489,7 +489,7 @@ def test_sequence_manager_parametric_repeat_counts()
end
def test_sequence_manager_repeat_execution_with_functions()
print("=== SequenceManager Repeat Execution with Functions Tests ===")
print("=== sequence_manager Repeat Execution with Functions Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -532,7 +532,7 @@ def test_sequence_manager_repeat_execution_with_functions()
end
def test_sequence_manager_palette_size_simulation()
print("=== SequenceManager Palette Size Simulation Tests ===")
print("=== sequence_manager Palette Size Simulation Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -577,7 +577,7 @@ def test_sequence_manager_palette_size_simulation()
end
def test_sequence_manager_dynamic_repeat_changes()
print("=== SequenceManager Dynamic Repeat Changes Tests ===")
print("=== sequence_manager Dynamic Repeat Changes Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -634,7 +634,7 @@ def test_sequence_manager_dynamic_repeat_changes()
end
def test_sequence_manager_complex_parametric_scenario()
print("=== SequenceManager Complex Parametric Scenario Tests ===")
print("=== sequence_manager Complex Parametric Scenario Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -689,7 +689,7 @@ def test_sequence_manager_complex_parametric_scenario()
end
def test_sequence_manager_zero_iterations()
print("=== SequenceManager Zero Iterations Tests ===")
print("=== sequence_manager Zero Iterations Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -743,7 +743,7 @@ def test_sequence_manager_zero_iterations()
end
def test_sequence_manager_zero_palette_size()
print("=== SequenceManager Zero Palette Size Tests ===")
print("=== sequence_manager Zero Palette Size Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -811,7 +811,7 @@ def test_sequence_manager_zero_palette_size()
end
def test_sequence_manager_boolean_repeat_counts()
print("=== SequenceManager Boolean Repeat Count Tests ===")
print("=== sequence_manager Boolean Repeat Count Tests ===")
# Create strip and engine
var strip = global.Leds(30)
@ -920,7 +920,7 @@ def test_sequence_manager_boolean_repeat_counts()
end
def test_sequence_manager_false_conditional_immediate_skip()
print("=== SequenceManager False Conditional Immediate Skip Tests ===")
print("=== sequence_manager False Conditional Immediate Skip Tests ===")
# This test verifies that when a conditional subsequence (if block) has a false condition,
# the parent sequence immediately advances to the next step without waiting for a tick.
@ -1035,7 +1035,7 @@ def test_sequence_manager_false_conditional_immediate_skip()
end
def test_sequence_manager_all_false_conditionals_no_infinite_loop()
print("=== SequenceManager All False Conditionals No Infinite Loop Tests ===")
print("=== sequence_manager All False Conditionals No Infinite Loop Tests ===")
# This test verifies that when ALL conditional subsequences in a repeat-forever
# sequence are false, the sequence doesn't go into an infinite loop.
@ -1104,7 +1104,7 @@ end
# Run all tests
def run_all_sequence_manager_tests()
print("Starting SequenceManager Unit Tests...")
print("Starting sequence_manager Unit Tests...")
test_sequence_manager_basic()
test_sequence_manager_step_creation()
@ -1127,7 +1127,7 @@ def run_all_sequence_manager_tests()
test_sequence_manager_false_conditional_immediate_skip()
test_sequence_manager_all_false_conditionals_no_infinite_loop()
print("\n🎉 All SequenceManager tests passed!")
print("\n🎉 All sequence_manager tests passed!")
return true
end

View File

@ -56,11 +56,11 @@ blue_anim.loop = true
blue_anim.opacity = 200
print(f"Blue animation - priority: {blue_anim.priority}, duration: {blue_anim.duration}, loop: {blue_anim.loop}")
# Test 4: Create animation with ValueProvider
# Test 4: Create animation with value_provider
var solid_provider = animation.static_color(engine)
solid_provider.color = 0xFF00FF00 # Green
var green_anim = animation.solid(engine)
green_anim.color = solid_provider # Use ValueProvider as dynamic parameter
green_anim.color = solid_provider # Use value_provider as dynamic parameter
print("Green animation with color provider created")
# Test 5: Test rendering
@ -86,11 +86,11 @@ assert(anim.color == 0xFFFFFFFF, "Color parameter should be accessible")
assert(red_anim.color == 0xFFFF0000, "Red color should be set correctly")
assert(blue_anim.priority == 20, "Priority should be set correctly")
# Test ValueProvider integration
assert(animation.is_value_provider(solid_provider), "Should recognize ValueProvider")
# Use get_param to get raw ValueProvider (not resolved value)
# Test value_provider integration
assert(animation.is_value_provider(solid_provider), "Should recognize value_provider")
# Use get_param to get raw value_provider (not resolved value)
var raw_color_param = green_anim.get_param("color")
assert(raw_color_param == solid_provider, "Should store ValueProvider as parameter")
assert(raw_color_param == solid_provider, "Should store value_provider as parameter")
print("All parameterized solid() tests completed successfully!")
return true

View File

@ -86,7 +86,7 @@ def test_solid_color_provider()
# Create solid animation with color provider
var yellow_solid = animation.solid(engine)
yellow_solid.color = color_provider # Use ValueProvider as dynamic parameter
yellow_solid.color = color_provider # Use value_provider as dynamic parameter
yellow_solid.priority = 10
yellow_solid.duration = 0
yellow_solid.loop = false
@ -96,9 +96,9 @@ def test_solid_color_provider()
assert(yellow_solid != nil, "Should create animation with color provider")
assert(type(yellow_solid) == "instance", "Should be an instance")
# Verify ValueProvider is stored correctly
# Verify value_provider is stored correctly
var raw_color_param = yellow_solid.get_param("color")
assert(raw_color_param == color_provider, "Should store ValueProvider as parameter")
assert(raw_color_param == color_provider, "Should store value_provider as parameter")
print("✅ Solid with color provider test passed")
end
@ -165,7 +165,7 @@ def run_tests()
print("\nKey Achievements:")
print("- solid() uses engine-only constructor pattern")
print("- Parameters set via virtual member assignment")
print("- Full ValueProvider integration")
print("- Full value_provider integration")
print("- Engine-controlled timing system")
print("- Parameterized class system working correctly")
return true

View File

@ -1,14 +1,14 @@
# Test suite for StaticValueProvider class
# Test suite for static_value class
#
# This test verifies that the StaticValueProvider class works correctly
# This test verifies that the static_value class works correctly
# and follows the parameterized class specification.
import string
import animation
# Test the basic StaticValueProvider interface
# Test the basic static_value interface
def test_static_value_provider_interface()
print("Testing StaticValueProvider interface...")
print("Testing static_value interface...")
# Create engine for testing
var strip = global.Leds()
@ -25,12 +25,12 @@ def test_static_value_provider_interface()
assert(provider.produce_value("test", 1000) == 42, "Should return set value")
assert(provider.produce_value("test", 2000) == 42, "Should return same value regardless of time")
print("✓ StaticValueProvider interface test passed")
print("✓ static_value interface test passed")
end
# Test with different value types
def test_static_value_provider_types()
print("Testing StaticValueProvider with different types...")
print("Testing static_value with different types...")
# Create engine for testing
var strip = global.Leds()
@ -51,7 +51,7 @@ def test_static_value_provider_types()
color_provider.value = 0xFF00FF00
assert(color_provider.produce_value("test", 1000) == 0xFF00FF00, "Should handle color values")
print("✓ StaticValueProvider types test passed")
print("✓ static_value types test passed")
end
# Test produce_value method with different parameter names
@ -98,7 +98,7 @@ end
# Test parameterized object integration
def test_parameterized_object_integration()
print("Testing ParameterizedObject integration...")
print("Testing parameterized_object integration...")
# Create engine for testing
var strip = global.Leds()
@ -119,7 +119,7 @@ def test_parameterized_object_integration()
assert(provider.get_param("value", nil) == 777, "Should retrieve value via parameter system")
assert(provider.value == 777, "Virtual member should reflect parameter value")
print("✓ ParameterizedObject integration test passed")
print("✓ parameterized_object integration test passed")
end
# Test value changes
@ -160,7 +160,7 @@ def test_string_representation()
provider.value = 42
var str_repr = str(provider)
assert(string.find(str_repr, "StaticValueProvider") >= 0, "String representation should contain class name")
assert(string.find(str_repr, "static_value") >= 0, "String representation should contain class name")
assert(string.find(str_repr, "42") >= 0, "String representation should contain the value")
print("✓ String representation test passed")
@ -168,7 +168,7 @@ end
# Run all tests
def run_static_value_provider_tests()
print("=== StaticValueProvider Tests ===")
print("=== static_value Tests ===")
try
test_static_value_provider_interface()
@ -179,7 +179,7 @@ def run_static_value_provider_tests()
test_value_changes()
test_string_representation()
print("=== All StaticValueProvider tests passed! ===")
print("=== All static_value tests passed! ===")
return true
except .. as e, msg
print(f"Test failed: {e} - {msg}")

View File

@ -1,12 +1,12 @@
#!/usr/bin/env berry
# Test to verify that time_ms is correctly passed to ValueProvider methods
# Test to verify that time_ms is correctly passed to value_provider methods
# Mock the animation module
var animation = {}
# Define the ValueProvider base class
class ValueProvider
# Define the value_provider base class
class value_provider
def get_value(time_ms)
return nil
end
@ -16,8 +16,8 @@ class ValueProvider
end
end
# Define the StaticValueProvider with member() construct
class StaticValueProvider : ValueProvider
# Define the static_value with member() construct
class static_value : value_provider
var value
def init(value)
@ -46,9 +46,9 @@ end
def test_time_ms_requirement()
print("=== Testing time_ms Requirement ===")
# Test 1: StaticValueProvider universal methods accept time_ms
print("1. Testing StaticValueProvider universal methods...")
var static_provider = StaticValueProvider(42)
# Test 1: static_value universal methods accept time_ms
print("1. Testing static_value universal methods...")
var static_provider = static_value(42)
var pulse_size_method = static_provider.member("get_pulse_size")
assert(type(pulse_size_method) == "function", "Should return function")
@ -61,7 +61,7 @@ def test_time_ms_requirement()
# Test 2: Custom provider with time-aware methods
print("2. Testing custom provider with time-aware methods...")
class TimeAwareProvider : ValueProvider
class TimeAwareProvider : value_provider
var last_time_received
def init()
@ -107,7 +107,7 @@ def test_time_ms_requirement()
print("3. Testing parameter resolution with time_ms...")
def resolve_parameter(param_value, param_name, time_ms)
if isinstance(param_value, ValueProvider)
if isinstance(param_value, value_provider)
# Try specific method first using introspection
import introspect
var method_name = "get_" + param_name
@ -141,7 +141,7 @@ def test_time_ms_requirement()
print("=== All time_ms requirement tests passed! ===")
print()
print("Verified:")
print("- StaticValueProvider universal methods accept time_ms")
print("- static_value universal methods accept time_ms")
print("- Custom provider methods receive time_ms correctly")
print("- Parameter resolution always passes time_ms")
print("- Both specific and generic methods work with time_ms")

View File

@ -1,15 +1,15 @@
# Test suite for ValueProvider base class
# Test suite for value_provider base class
#
# This test verifies that the base ValueProvider class works correctly
# This test verifies that the base value_provider class works correctly
# and follows the parameterized class specification with produce_value() API.
import animation
import "./core/param_encoder" as encode_constraints
# Test the basic ValueProvider interface
# Test the basic value_provider interface
def test_value_provider_interface()
print("Testing ValueProvider interface...")
print("Testing value_provider interface...")
# Create engine for testing
var strip = global.Leds()
@ -25,12 +25,12 @@ def test_value_provider_interface()
assert(provider.engine != nil, "Provider should have engine reference")
assert(provider.engine == engine, "Provider should have correct engine reference")
print("✓ ValueProvider interface test passed")
print("✓ value_provider interface test passed")
end
# Test with a custom value provider
def test_custom_value_provider()
print("Testing custom ValueProvider...")
print("Testing custom value_provider...")
# Create engine for testing
var strip = global.Leds()
@ -64,7 +64,7 @@ def test_custom_value_provider()
# Test parameter access
assert(provider.multiplier == 2, "Should access parameter via virtual member")
print("✓ Custom ValueProvider test passed")
print("✓ Custom value_provider test passed")
end
# Test is_value_provider function
@ -77,7 +77,7 @@ def test_is_value_provider()
var base_provider = animation.value_provider(engine)
assert(animation.is_value_provider(base_provider) == true, "ValueProvider should be detected")
assert(animation.is_value_provider(base_provider) == true, "value_provider should be detected")
assert(animation.is_value_provider(42) == false, "Integer should not be detected")
assert(animation.is_value_provider("hello") == false, "String should not be detected")
assert(animation.is_value_provider(nil) == false, "nil should not be detected")
@ -87,7 +87,7 @@ end
# Test parameterized object integration
def test_parameterized_object_integration()
print("Testing ParameterizedObject integration...")
print("Testing parameterized_object integration...")
# Create engine for testing
var strip = global.Leds()
@ -106,7 +106,7 @@ def test_parameterized_object_integration()
# Test lifecycle method exists
assert(type(provider.start) == "function", "Should have start method")
print("✓ ParameterizedObject integration test passed")
print("✓ parameterized_object integration test passed")
end
# Test lifecycle methods
@ -159,9 +159,9 @@ def test_lifecycle_methods()
print("✓ Lifecycle methods test passed")
end
# Test value provider registration in EngineProxy
# Test value provider registration in engine_proxy
def test_value_provider_registration()
print("Testing ValueProvider registration in EngineProxy...")
print("Testing value_provider registration in engine_proxy...")
# Create a mock LED strip
var strip = Leds(30)
@ -216,12 +216,12 @@ def test_value_provider_registration()
assert(removed == true, "Value provider should be removed successfully")
assert(size(proxy.value_providers) == 0, "Proxy should have no value providers after remove")
print("✓ ValueProvider registration test passed")
print("✓ value_provider registration test passed")
end
# Test multiple value providers
def test_multiple_value_providers()
print("Testing multiple ValueProviders in EngineProxy...")
print("Testing multiple value_providers in engine_proxy...")
var strip = Leds(30)
var engine = animation.create_engine(strip)
@ -261,12 +261,12 @@ def test_multiple_value_providers()
osc2.stop()
osc3.stop()
print("✓ Multiple ValueProviders test passed")
print("✓ Multiple value_providers test passed")
end
# Test is_empty() includes value_providers
def test_is_empty_with_value_providers()
print("Testing is_empty() with ValueProviders...")
print("Testing is_empty() with value_providers...")
var strip = Leds(30)
var engine = animation.create_engine(strip)
@ -280,12 +280,12 @@ def test_is_empty_with_value_providers()
proxy.clear()
assert(proxy.is_empty() == true, "Proxy should be empty after clear")
print("✓ is_empty() with ValueProviders test passed")
print("✓ is_empty() with value_providers test passed")
end
# Run all tests
def run_value_provider_tests()
print("=== ValueProvider Base Class Tests ===")
print("=== value_provider Base Class Tests ===")
try
test_value_provider_interface()
@ -294,12 +294,12 @@ def run_value_provider_tests()
test_parameterized_object_integration()
test_lifecycle_methods()
print("\n=== ValueProvider Registration Tests ===")
print("\n=== value_provider Registration Tests ===")
test_value_provider_registration()
test_multiple_value_providers()
test_is_empty_with_value_providers()
print("\n=== All ValueProvider tests passed! ===")
print("\n=== All value_provider tests passed! ===")
return true
except .. as e, msg
print(f"Test failed: {e} - {msg}")