Berry animation add SINE transition in rich_color_palette and add WLED palettes (#24029)

This commit is contained in:
s-hadinger 2025-10-18 19:09:16 +02:00 committed by GitHub
parent 2b63276cdb
commit 623dea884f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 2367 additions and 1907 deletions

View File

@ -0,0 +1,57 @@
# Generated Berry code from Animation DSL
# Source: template_cylon_generic.anim
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
import animation
# Cylon Red Eye
# Automatically adapts to the length of the strip
# Template function: cylon_effect
def cylon_effect_template(engine, eye_color_, duration_, back_color_)
var strip_len_ = animation.strip_length(engine)
var eye_animation_ = animation.beacon_animation(engine)
eye_animation_.color = eye_color_
eye_animation_.back_color = back_color_
eye_animation_.pos = (def (engine)
var provider = animation.cosine_osc(engine)
provider.min_value = (-1)
provider.max_value = animation.create_closure_value(engine, def (engine) return animation.resolve(strip_len_) - 2 end)
provider.duration = duration_
return provider
end)(engine)
eye_animation_.beacon_size = 3 # small 3 pixels eye
eye_animation_.slew_size = 2 # with 2 pixel shading around
eye_animation_.priority = 5
engine.add(eye_animation_)
end
animation.register_user_function('cylon_effect', cylon_effect_template)
#- Original DSL source:
# Cylon Red Eye
# Automatically adapts to the length of the strip
template cylon_effect {
param eye_color type color
param duration type time
param back_color type color
set strip_len = strip_length()
animation eye_animation = beacon_animation(
color = eye_color
back_color = back_color
pos = cosine_osc(min_value = -1, max_value = strip_len - 2, duration = duration)
beacon_size = 3 # small 3 pixels eye
slew_size = 2 # with 2 pixel shading around
priority = 5
)
run eye_animation
}
-#

View File

@ -0,0 +1,110 @@
# Generated Berry code from Animation DSL
# Source: test_shutter_rainbow_central.anim
#
# This file was automatically generated by compile_all_examples.sh
# Do not edit manually - changes will be overwritten
import animation
# Demo Shutter Rainbow
#
# Shutter from center to both left and right
# Template function: shutter_central
def shutter_central_template(engine, colors_, duration_)
var strip_len_ = animation.strip_length(engine)
var shutter_size_ = (def (engine)
var provider = animation.sawtooth(engine)
provider.min_value = 0
provider.max_value = strip_len_
provider.duration = duration_
return provider
end)(engine)
var col1_ = animation.color_cycle(engine)
col1_.palette = colors_
col1_.cycle_period = 0
var col2_ = animation.color_cycle(engine)
col2_.palette = colors_
col2_.cycle_period = 0
col2_.next = 1
# shutter moving from left to right
var shutter_central_animation_ = animation.beacon_animation(engine)
shutter_central_animation_.color = col2_
shutter_central_animation_.back_color = col1_
shutter_central_animation_.pos = animation.create_closure_value(engine, def (engine) return animation.resolve(strip_len_) - animation.resolve(shutter_size_) / 2 end)
shutter_central_animation_.beacon_size = shutter_size_
shutter_central_animation_.slew_size = 0
shutter_central_animation_.priority = 5
var shutter_seq_ = animation.SequenceManager(engine, -1)
.push_closure_step(def (engine) shutter_size_.start(engine.time_ms) end)
.push_play_step(shutter_central_animation_, animation.resolve(duration_))
.push_closure_step(def (engine) col1_.next = 1 end)
.push_closure_step(def (engine) col2_.next = 1 end)
engine.add(shutter_seq_)
end
animation.register_user_function('shutter_central', shutter_central_template)
# Auto-generated strip initialization (using Tasmota configuration)
var engine = animation.init_strip()
var rainbow_with_white_ = bytes(
"FFFF0000"
"FFFFA500"
"FFFFFF00"
"FF008000" # comma left on-purpose to test transpiler
"FF0000FF" # need for a lighter blue
"FF4B0082"
"FFFFFFFF"
)
shutter_central_template(engine, rainbow_with_white_, 1500)
engine.run()
#- Original DSL source:
# Demo Shutter Rainbow
#
# Shutter from center to both left and right
template shutter_central {
param colors type palette
param duration
set strip_len = strip_length()
set shutter_size = sawtooth(min_value = 0, max_value = strip_len, duration = duration)
color col1 = color_cycle(palette=colors, cycle_period=0)
color col2 = color_cycle(palette=colors, cycle_period=0)
col2.next = 1
# shutter moving from left to right
animation shutter_central_animation = beacon_animation(
color = col2
back_color = col1
pos = strip_len - shutter_size / 2
beacon_size = shutter_size
slew_size = 0
priority = 5
)
sequence shutter_seq repeat forever {
restart shutter_size
play shutter_central_animation for duration
col1.next = 1
col2.next = 1
}
run shutter_seq
}
palette rainbow_with_white = [ red
orange
yellow
green, # comma left on-purpose to test transpiler
blue # need for a lighter blue
indigo
white
]
shutter_central(rainbow_with_white, 1.5s)
-#

View File

@ -3,18 +3,10 @@
template cylon_effect { template cylon_effect {
param eye_color type color param eye_color type color
param duration type time
param back_color type color param back_color type color
param duration
set aaa = abs2(45) + 2
set strip_len = strip_length() set strip_len = strip_length()
set strip_len_div_2 = abs(strip_len / 2)
set strip_len2 = strip_length(is_running=0) # artifically putting an argument to cause a closure
set osc1 = sawtooth()
set osc2 = triangle()
set osc3 = scale(osc1 + osc2, 0, 200, 0, 255)
set osc9 = sawtooth() + triangle() # this should fail
animation eye_animation = beacon_animation( animation eye_animation = beacon_animation(
color = eye_color color = eye_color

View File

@ -3,48 +3,43 @@
# Shutter from center to both left and right # Shutter from center to both left and right
template shutter_central { template shutter_central {
param colors type palette param colors type palette
param duration param duration
set strip_len = strip_length() set strip_len = strip_length()
set strip_len2 = (strip_len + 1) / 2 set shutter_size = sawtooth(min_value = 0, max_value = strip_len, duration = duration)
# the following is highly discouraged because it creates a new value provider at each tick
set strip_len3 = 1 + strip_length() color col1 = color_cycle(palette=colors, cycle_period=0)
set strip_len4 = (strip_length() + 1) / 2 color col2 = color_cycle(palette=colors, cycle_period=0)
set shutter_size = sawtooth(min_value = 0, max_value = strip_len, duration = duration) col2.next = 1
color col1 = color_cycle(palette=colors, cycle_period=0) # shutter moving from left to right
color col2 = color_cycle(palette=colors, cycle_period=0) animation shutter_central_animation = beacon_animation(
color = col2
back_color = col1
pos = strip_len - shutter_size / 2
beacon_size = shutter_size
slew_size = 0
priority = 5
)
sequence shutter_seq repeat forever {
restart shutter_size
play shutter_central_animation for duration
col1.next = 1
col2.next = 1 col2.next = 1
# shutter moving from left to right
animation shutter_central_animation = beacon_animation(
color = col2
back_color = col1
pos = strip_len3 - shutter_size / 2
beacon_size = shutter_size
slew_size = 0
priority = 5
)
sequence shutter_seq repeat forever {
restart shutter_size
play shutter_central_animation for duration
col1.next = 1
col2.next = 1
}
run shutter_seq
} }
palette rainbow_with_white = [ red run shutter_seq
orange }
yellow
green, # comma left on-purpose to test transpiler palette rainbow_with_white = [ red
blue # need for a lighter blue orange
indigo yellow
white green, # comma left on-purpose to test transpiler
] blue # need for a lighter blue
indigo
shutter_central(rainbow_with_white, 1.5s) white
]
shutter_central(rainbow_with_white, 1.5s)

View File

@ -281,7 +281,7 @@ Generates colors from predefined palettes with smooth transitions and profession
|-----------|------|---------|-------------|-------------| |-----------|------|---------|-------------|-------------|
| `palette` | bytes | rainbow palette | - | Palette bytes or predefined palette constant | | `palette` | bytes | rainbow palette | - | Palette bytes or predefined palette constant |
| `cycle_period` | int | 5000 | min: 0 | Cycle time in ms (0 = value-based only) | | `cycle_period` | int | 5000 | min: 0 | Cycle time in ms (0 = value-based only) |
| `transition_type` | int | 1 | enum: [0,1] | 0=linear, 1=sine/smooth | | `transition_type` | int | animation.LINEAR | enum: [animation.LINEAR, animation.SINE] | LINEAR=constant speed, SINE=smooth ease-in/ease-out |
| `brightness` | int | 255 | 0-255 | Overall brightness scaling | | `brightness` | int | 255 | 0-255 | Overall brightness scaling |
| `range_min` | int | 0 | - | Minimum value for value-based mapping | | `range_min` | int | 0 | - | Minimum value for value-based mapping |
| `range_max` | int | 100 | - | Maximum value for value-based mapping | | `range_max` | int | 100 | - | Maximum value for value-based mapping |
@ -300,27 +300,26 @@ Generates colors from predefined palettes with smooth transitions and profession
#### Usage Examples #### Usage Examples
```berry ```berry
# Rainbow palette with smooth transitions # Rainbow palette with smooth ease-in/ease-out transitions
color rainbow_colors = rich_palette( color rainbow_colors = rich_palette(
palette=PALETTE_RAINBOW, palette=PALETTE_RAINBOW,
cycle_period=5s, cycle_period=5s,
transition_type=1, transition_type=SINE,
brightness=255 brightness=255
) )
# Fire effect with linear transitions # Fire effect with linear (constant speed) transitions
color fire_colors = rich_palette( color fire_colors = rich_palette(
palette=PALETTE_FIRE, palette=PALETTE_FIRE,
cycle_period=3s, cycle_period=3s,
transition_type=0, transition_type=LINEAR,
brightness=200 brightness=200
) )
# Ocean waves with smooth, slow transitions # Ocean waves with default linear transitions
color ocean_colors = rich_palette( color ocean_colors = rich_palette(
palette=PALETTE_OCEAN, palette=PALETTE_OCEAN,
cycle_period=8s, cycle_period=8s,
transition_type=1,
brightness=180 brightness=180
) )
``` ```
@ -789,7 +788,7 @@ Creates smooth color transitions using rich palette data with direct parameter a
|-----------|------|---------|-------------|-------------| |-----------|------|---------|-------------|-------------|
| `palette` | bytes | rainbow palette | - | Palette bytes or predefined palette | | `palette` | bytes | rainbow palette | - | Palette bytes or predefined palette |
| `cycle_period` | int | 5000 | min: 0 | Cycle time in ms (0 = value-based only) | | `cycle_period` | int | 5000 | min: 0 | Cycle time in ms (0 = value-based only) |
| `transition_type` | int | 1 | enum: [0,1] | 0=linear, 1=sine | | `transition_type` | int | animation.LINEAR | enum: [animation.LINEAR, animation.SINE] | LINEAR=constant speed, SINE=smooth ease-in/ease-out |
| `brightness` | int | 255 | 0-255 | Overall brightness scaling | | `brightness` | int | 255 | 0-255 | Overall brightness scaling |
| `range_min` | int | 0 | - | Minimum value for value-based mapping | | `range_min` | int | 0 | - | Minimum value for value-based mapping |
| `range_max` | int | 100 | - | Maximum value for value-based mapping | | `range_max` | int | 100 | - | Maximum value for value-based mapping |

View File

@ -165,8 +165,6 @@ register_to_animation(wave_animation)
# Import palette examples # Import palette examples
import "animations/palettes" as palettes import "animations/palettes" as palettes
register_to_animation(palettes) register_to_animation(palettes)
# import "animations/all_wled_palettes" as all_wled_palettes
# register_to_animation(all_wled_palettes)
# Import specialized animation classes # Import specialized animation classes
import "animations/rich_palette_animation" as rich_palette_animation import "animations/rich_palette_animation" as rich_palette_animation

View File

@ -56,6 +56,9 @@ register_to_dsl(dsl_named_colors)
import "webui/animation_web_ui.be" as animation_web_ui import "webui/animation_web_ui.be" as animation_web_ui
register_to_dsl(animation_web_ui) register_to_dsl(animation_web_ui)
import "dsl/all_wled_palettes" as all_wled_palettes
register_to_dsl(all_wled_palettes)
# Main DSL compilation function # Main DSL compilation function
# Compiles DSL source code to Berry code # Compiles DSL source code to Berry code
# #

View File

@ -22,7 +22,7 @@ class RichPaletteColorProvider : animation.color_provider
static var PARAMS = encode_constraints({ static var PARAMS = encode_constraints({
"palette": {"type": "bytes", "default": nil}, # Palette bytes or predefined palette constant "palette": {"type": "bytes", "default": nil}, # Palette bytes or predefined palette constant
"cycle_period": {"min": 0, "default": 5000}, # 5 seconds default, 0 = value-based only "cycle_period": {"min": 0, "default": 5000}, # 5 seconds default, 0 = value-based only
"transition_type": {"enum": [animation.LINEAR, animation.SINE], "default": animation.SINE}, "transition_type": {"enum": [animation.LINEAR, animation.SINE], "default": animation.LINEAR},
"brightness": {"min": 0, "max": 255, "default": 255}, "brightness": {"min": 0, "max": 255, "default": 255},
"range_min": {"default": 0}, "range_min": {"default": 0},
"range_max": {"default": 255} "range_max": {"default": 255}
@ -173,6 +173,43 @@ class RichPaletteColorProvider : animation.color_provider
return trgb return trgb
end end
# Interpolate a value between two points using the selected transition type
#
# @param value: int - Current value to interpolate
# @param from_min: int - Start of range
# @param from_max: int - End of range
# @param to_min: int - Start of output range
# @param to_max: int - End of output range
# @return int - Interpolated value
def _interpolate(value, from_min, from_max, to_min, to_max)
var transition_type = self.transition_type
if transition_type == animation.SINE
# Cosine interpolation for smooth transitions
# Map value to 0..255 range first
var t = tasmota.scale_uint(value, from_min, from_max, 0, 255)
# Map to angle range for cosine: 0 -> 16384 (180 degrees)
# We use cosine from 180° to 0° which gives us 0->1 smooth curve
var angle = tasmota.scale_uint(t, 0, 255, 16384, 0)
# tasmota.sine_int returns -4096 to 4096 for angle 0-32767
# At angle 16384 (180°): sine_int returns 0 (actually cosine = -1)
# At angle 0 (0°): sine_int returns 0 (cosine = 1)
# We need to shift by 8192 to get cosine behavior
var cos_val = tasmota.sine_int(angle + 8192) # -4096 to 4096
# Map cosine from -4096..4096 to 0..255
var normalized = tasmota.scale_int(cos_val, -4096, 4096, 0, 255)
# Finally map to output range
return tasmota.scale_int(normalized, 0, 255, to_min, to_max)
else
# Default to linear interpolation (for LINEAR mode or any unknown type)
return tasmota.scale_uint(value, from_min, from_max, to_min, to_max)
end
end
# Produce a color value for any parameter name (optimized version from Animate_palette) # Produce a color value for any parameter name (optimized version from Animate_palette)
# #
# @param name: string - Parameter name being requested (ignored) # @param name: string - Parameter name being requested (ignored)
@ -231,10 +268,10 @@ class RichPaletteColorProvider : animation.color_provider
var t0 = self.slots_arr[idx] var t0 = self.slots_arr[idx]
var t1 = self.slots_arr[idx + 1] var t1 = self.slots_arr[idx + 1]
# Use tasmota.scale_uint for efficiency (from Animate_palette) # Use interpolation based on transition_type (LINEAR or SINE)
var r = tasmota.scale_uint(past, t0, t1, (bgrt0 >> 8) & 0xFF, (bgrt1 >> 8) & 0xFF) var r = self._interpolate(past, t0, t1, (bgrt0 >> 8) & 0xFF, (bgrt1 >> 8) & 0xFF)
var g = tasmota.scale_uint(past, t0, t1, (bgrt0 >> 16) & 0xFF, (bgrt1 >> 16) & 0xFF) var g = self._interpolate(past, t0, t1, (bgrt0 >> 16) & 0xFF, (bgrt1 >> 16) & 0xFF)
var b = tasmota.scale_uint(past, t0, t1, (bgrt0 >> 24) & 0xFF, (bgrt1 >> 24) & 0xFF) var b = self._interpolate(past, t0, t1, (bgrt0 >> 24) & 0xFF, (bgrt1 >> 24) & 0xFF)
# Use light_state for proper brightness calculation (from Animate_palette) # Use light_state for proper brightness calculation (from Animate_palette)
var light_state = self.light_state var light_state = self.light_state
@ -242,7 +279,7 @@ class RichPaletteColorProvider : animation.color_provider
var bri0 = light_state.bri var bri0 = light_state.bri
light_state.set_rgb((bgrt1 >> 8) & 0xFF, (bgrt1 >> 16) & 0xFF, (bgrt1 >> 24) & 0xFF) light_state.set_rgb((bgrt1 >> 8) & 0xFF, (bgrt1 >> 16) & 0xFF, (bgrt1 >> 24) & 0xFF)
var bri1 = light_state.bri var bri1 = light_state.bri
var bri2 = tasmota.scale_uint(past, t0, t1, bri0, bri1) var bri2 = self._interpolate(past, t0, t1, bri0, bri1)
light_state.set_rgb(r, g, b) light_state.set_rgb(r, g, b)
light_state.set_bri(bri2) light_state.set_bri(bri2)
@ -294,10 +331,10 @@ class RichPaletteColorProvider : animation.color_provider
var t0 = self.value_arr[idx] var t0 = self.value_arr[idx]
var t1 = self.value_arr[idx + 1] var t1 = self.value_arr[idx + 1]
# Use tasmota.scale_uint for efficiency (from Animate_palette) # Use interpolation based on transition_type (LINEAR or SINE)
var r = tasmota.scale_uint(value, t0, t1, (bgrt0 >> 8) & 0xFF, (bgrt1 >> 8) & 0xFF) var r = self._interpolate(value, t0, t1, (bgrt0 >> 8) & 0xFF, (bgrt1 >> 8) & 0xFF)
var g = tasmota.scale_uint(value, t0, t1, (bgrt0 >> 16) & 0xFF, (bgrt1 >> 16) & 0xFF) var g = self._interpolate(value, t0, t1, (bgrt0 >> 16) & 0xFF, (bgrt1 >> 16) & 0xFF)
var b = tasmota.scale_uint(value, t0, t1, (bgrt0 >> 24) & 0xFF, (bgrt1 >> 24) & 0xFF) var b = self._interpolate(value, t0, t1, (bgrt0 >> 24) & 0xFF, (bgrt1 >> 24) & 0xFF)
# Apply brightness scaling (from Animate_palette) # Apply brightness scaling (from Animate_palette)
if brightness != 255 if brightness != 255

View File

@ -2237,30 +2237,197 @@ be_local_class(Token,
be_str_weak(Token) be_str_weak(Token)
); );
extern const bclass be_class_MockEngine; extern const bclass be_class_WLED_Palettes;
/******************************************************************** /********************************************************************
** Solidified function: init ** Solidified class: WLED_Palettes
********************************************************************/ ********************************************************************/
be_local_closure(class_MockEngine_init, /* name */ be_local_class(WLED_Palettes,
0,
NULL,
be_nested_map(1,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(map, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, {
be_const_map( * be_nested_map(59,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(Red_X20_X26_X20Blue, 38), be_const_bytes_instance(00290E631F80184A3FE322325F841F4C7F2F1D669F6D2F65BFB04264DF813968FF54306C) },
{ be_const_key_weak(Red_X20Tide, -1), be_const_bytes_instance(00FB2E001CFF8B192BF69E3F3AF6D87B54F35E0A72B1410B8CFFF173A8B1410BC4FAE99ED8FF5E06FF7E0804) },
{ be_const_key_weak(C9_X202, 5), be_const_bytes_instance(00067E022D067E022E041E725A041E725BFF050087FF050088C43902B4C43902B5895502FF895502) },
{ be_const_key_weak(Aqua_X20Flash, -1), be_const_bytes_instance(000000004282F2F560FFFF357CFFFFFF99FFFF35BC82F2F5FF000000) },
{ be_const_key_weak(Icefire, -1), be_const_bytes_instance(000000003B003375770066FF952699FFB456CCFFD9A7E6FFFFFFFFFF) },
{ be_const_key_weak(Hult, 15), be_const_bytes_instance(00FBD8FC30FFC0FF59EF5FF1A03399D9D818B8AEFF18B8AE) },
{ be_const_key_weak(Yelmag, 47), be_const_bytes_instance(000000002A71000054FF00007FFF0075AAFF00FFD4FF8075FFFFFF00) },
{ be_const_key_weak(Red_X20Flash, -1), be_const_bytes_instance(0000000063F20C0882FDE4A39BF20C08FF000000) },
{ be_const_key_weak(Beech, -1), be_const_bytes_instance(00FFFEEC0CFFFEEC16FFFEEC1ADFE0B21CC0C37C1CB0FFE7327BFBEC474AF6F15D21E1E47800CCD78504A8B2880A848F8833BDD4D0179FC9FF0081BE) },
{ be_const_key_weak(Landscape, -1), be_const_bytes_instance(00000000251F59134C48B22B7F96EB0580BAEA7782DEE9FC99C5DBE7CC84B3FDFF1C6BE1) },
{ be_const_key_weak(Rewhi, -1), be_const_bytes_instance(00B1A0C748CD9E9559E99B656BFF5F3F8DC0626DFF84659F) },
{ be_const_key_weak(C9_X20New, -1), be_const_bytes_instance(00FF05003CFF05003DC4390278C4390279067E02B4067E02B5041E72FF041E72) },
{ be_const_key_weak(Jul, 37), be_const_bytes_instance(00E2060C5E1A604E8482BD5EFFB10309) },
{ be_const_key_weak(Cyane, -1), be_const_bytes_instance(003D9B2C195FAE4D3C84C1715D9AA67D6AAF8A886DB7798971C2688A74E1B3A57CFFFFC0A8A7DACBFF54B6D7) },
{ be_const_key_weak(C9, -1), be_const_bytes_instance(00B804003CB8040041902C027D902C0282046002BE046002C3070758FF070758) },
{ be_const_key_weak(Light_X20Pink, -1), be_const_bytes_instance(004F206D195A28753366307C4C8D87B966B4DEF86DD0ECFC72EDFAFF7ACEC8EF95B195DEB7BB82CBFFC66FB8) },
{ be_const_key_weak(Lite_X20Light, -1), be_const_bytes_instance(0000000009141516282E2B31422E2B31653D1041FF000000) },
{ be_const_key_weak(Orange_X20_X26_X20Teal, 50), be_const_bytes_instance(0000965C3700965CC8FF4800FFFF4800) },
{ be_const_key_weak(Sunset2, -1), be_const_bytes_instance(00AF793E1D80673C4454543A44F8B83761EFCC5D7CE6E185B2667D81FF001A7D) },
{ be_const_key_weak(Toxy_X20Reaf, 9), be_const_bytes_instance(0002EF7EFF9123D9) },
{ be_const_key_weak(Aurora_X202, -1), be_const_bytes_instance(0011B10D4079F2058019AD79C0FA4D7FFFAB65DD) },
{ be_const_key_weak(Vintage, 44), be_const_bytes_instance(00291218334900164CA5AA2665FFBD507F8B382899490016E5291218FF291218) },
{ be_const_key_weak(Fire, 3), be_const_bytes_instance(000000002E4D000060B100006CC4260977D74C1392EB731DAEFF9929BCFFB229CAFFCC29DAFFE629EAFFFF29F4FFFF8FFFFFFFFF) },
{ be_const_key_weak(Rivendell, 29), be_const_bytes_instance(0018452C65496946A5818C61F2C8CCA6FFC8CCA6) },
{ be_const_key_weak(Blink_X20Red, -1), be_const_bytes_instance(000407042B28193E4C3D0F246DCF27607FFF9CB8A5B949CFCC6942F0FF4D1D4E) },
{ be_const_key_weak(Magred, -1), be_const_bytes_instance(000000003F7100757FFF00FFBFFF0075FFFF0000) },
{ be_const_key_weak(Semi_X20Blue, -1), be_const_bytes_instance(000000000C18042635370854502B309F771F59ED91323BA6BA471E62E91F0F2DFF000000) },
{ be_const_key_weak(Analogous, 39), be_const_bytes_instance(002600FF3F5600FF7F8B00FFBFC40075FFFF0000) },
{ be_const_key_weak(Sakura, 20), be_const_bytes_instance(00C4130A41FF452D82DF2D48C3FF5267FFDF0D11) },
{ be_const_key_weak(Pastel, -1), be_const_bytes_instance(003D87B82481BCA957CBF19B64E4ED8D6BFFE87F73FBCA8278F8AC8580FBCA82B4FFE87FDFFFF278FFFFFC71) },
{ be_const_key_weak(Candy2, -1), be_const_bytes_instance(006D6666192A31473079605449F1D61A59D8682C822A3147A3FFB12FBAF1D61AD36D6666FF14130D) },
{ be_const_key_weak(Red_X20Reaf, -1), be_const_bytes_instance(002444726895C3F8BCFF0000FF5E0E09) },
{ be_const_key_weak(Red_X20Shift, 40), be_const_bytes_instance(0062165D2D67164963C02D3884EBBB3BAFE4551AC9E43830FF020002) },
{ be_const_key_weak(Grintage, -1), be_const_bytes_instance(001D0803354C0100688E601C99D3BF3DFF75812A) },
{ be_const_key_weak(Pink_X20Candy, 14), be_const_bytes_instance(00FFFFFF2D3240FF70F210BA8CFFFFFF9BF210BAC4740DA6FFFFFFFF) },
{ be_const_key_weak(Temperature, 12), be_const_bytes_instance(00145CAB0E0F6FBA1C068ED32A02A1E33810B5EF4626BCC95456CCC8638BDBB071B6E57D7FC4E63F8DF1F0169BFEDE1EAAFBC704B8F79D09C6F3720FE2D51E1DF0972623FF972623) },
{ be_const_key_weak(Departure, -1), be_const_bytes_instance(003522002A5633003F936C3154D4A66C6AEBD4B474FFFFFF8ABFFFC19454FF58AA00FF00BF00C000D4008000FF008000) },
{ be_const_key_weak(Candy, -1), be_const_bytes_instance(00F3F2170FF2A8268E6F1597C64A1696FF000075) },
{ be_const_key_weak(Retro_X20Clown, 46), be_const_bytes_instance(00F2A82675E24E50FFA136E1) },
{ be_const_key_weak(Beach, 26), be_const_bytes_instance(000C2D001365560226CF80043FF3C512426DC492FF052707) },
{ be_const_key_weak(Sunset, -1), be_const_bytes_instance(00B5000016DA550033FFAA0055D3554D87A700A9C64900BCFF0000CF) },
{ be_const_key_weak(Yelblu, -1), be_const_bytes_instance(000000FF3F0080FF7F00FFFFBF71FF75FFFFFF00) },
{ be_const_key_weak(Atlantica, -1), be_const_bytes_instance(00001C70322060FF6400F32D960C5F52C819BE5FFF28AA50) },
{ be_const_key_weak(Sherbet, -1), be_const_bytes_instance(00FF66292BFF8C5A56FF335A7FFF99A9AAFFFFF9D171FF55FF9DFF89) },
{ be_const_key_weak(Orangery, -1), be_const_bytes_instance(00FF5F171EFF52003CDF0D085A902C0278FF6E1196FF4500B49E0D0BD2F15211FFD52504) },
{ be_const_key_weak(Yellowout, -1), be_const_bytes_instance(00DEBF08FF753401) },
{ be_const_key_weak(April_X20Night, -1), be_const_bytes_instance(0001052D0A01052D1905A9AF2801052D3D01052D4C2DAF1F5B01052D7001052D7FF996058F01052DA201052DB2FF5C00C101052DD601052DE5DF2D48F401052DFF01052D) },
{ be_const_key_weak(Aurora, -1), be_const_bytes_instance(0001052D4000C8178000FF00AA00F32DC8008707FF01052D) },
{ be_const_key_weak(Magenta, 28), be_const_bytes_instance(000000002A000075540000FF7F7100FFAAFF00FFD4FF80FFFFFFFFFF) },
{ be_const_key_weak(Autumn, 18), be_const_bytes_instance(005A0E05338B290D54B4461168C0CA7D70B189037ABEC8837CC0CA7C87B189038EC2CB76A3B14411CC80230CF94A0502FF4A0502) },
{ be_const_key_weak(Drywet, -1), be_const_bytes_instance(007761212AEBC75854A9EE7C7F25EEE8AA0778ECD41B01AFFF043365) },
{ be_const_key_weak(Hult64, -1), be_const_bytes_instance(0018B8AE4208A296687C890782B2BA16967C8907C9069C90EF008075FF008075) },
{ be_const_key_weak(Yelblu_X20Hot, -1), be_const_bytes_instance(002B1E393A4900777A57004A9EC53916B7DA751BDBEFB120FFF6F71B) },
{ be_const_key_weak(Traffic_X20Light, 13), be_const_bytes_instance(000000005500FF00AAFFFF00FFFF0000) },
{ be_const_key_weak(Splash, 34), be_const_bytes_instance(00BA3FFF7FE30955AFEACDD5DDCD26B0FFCD26B0) },
{ be_const_key_weak(Breeze, -1), be_const_bytes_instance(00103033591BA6AF99C5E9FFFF009198) },
{ be_const_key_weak(Tertiary, -1), be_const_bytes_instance(000019FF3F268C757F56FF00BFA78C13FFFF1929) },
{ be_const_key_weak(Tiamat, 27), be_const_bytes_instance(0001020E21020523640D875C782BFFC18CF707F9A0C111D0B427FF9AC804D5ECDC27FC87F0C1D5FDFFFFF9FF) },
{ be_const_key_weak(Fairy_X20Reaf, 31), be_const_bytes_instance(00DC13BBA00CE1DBDBCBF2DFFFFFFFFF) },
})) ) } )) },
})),
be_str_weak(WLED_Palettes)
);
/********************************************************************
** Solidified function: compile_file
********************************************************************/
be_local_closure(compile_file, /* name */
be_nested_proto( be_nested_proto(
1, /* nstack */ 13, /* nstack */
1, /* argc */ 1, /* argc */
2, /* varg */ 0, /* varg */
0, /* has upvals */ 0, /* has upvals */
NULL, /* no upvals */ NULL, /* no upvals */
0, /* has sup protos */ 0, /* has sup protos */
NULL, /* no sub protos */ NULL, /* no sub protos */
1, /* has constants */ 1, /* has constants */
( &(const bvalue[ 2]) { /* constants */ ( &(const bvalue[25]) { /* constants */
/* K0 */ be_nested_str_weak(time_ms), /* K0 */ be_nested_str_weak(string),
/* K1 */ be_const_int(0), /* K1 */ be_nested_str_weak(animation_dsl),
/* K2 */ be_nested_str_weak(endswith),
/* K3 */ be_nested_str_weak(_X2Eanim),
/* K4 */ be_nested_str_weak(Input_X20file_X20must_X20have_X20_X2Eanim_X20extension_X3A_X20_X25s),
/* K5 */ be_nested_str_weak(invalid_filename),
/* K6 */ be_const_int(0),
/* K7 */ be_nested_str_weak(_X2Ebe),
/* K8 */ be_nested_str_weak(r),
/* K9 */ be_nested_str_weak(Cannot_X20open_X20input_X20file_X3A_X20_X25s),
/* K10 */ be_nested_str_weak(io_error),
/* K11 */ be_nested_str_weak(read),
/* K12 */ be_nested_str_weak(close),
/* K13 */ be_nested_str_weak(compile),
/* K14 */ be_nested_str_weak(DSL_X20compilation_X20failed_X20for_X3A_X20_X25s),
/* K15 */ be_nested_str_weak(dsl_compilation_error),
/* K16 */ be_nested_str_weak(_X23_X20Generated_X20Berry_X20code_X20from_X20Animation_X20DSL_X0A),
/* K17 */ be_nested_str_weak(_X23_X20Source_X3A_X20_X25s_X0A),
/* K18 */ be_nested_str_weak(_X23_X20Generated_X20automatically_X20by_X20animation_dsl_X2Ecompile_file_X28_X29_X0A),
/* K19 */ be_nested_str_weak(_X23_X20_X0A),
/* K20 */ be_nested_str_weak(_X23_X20Do_X20not_X20edit_X20manually_X20_X2D_X20changes_X20will_X20be_X20overwritten_X0A),
/* K21 */ be_nested_str_weak(_X0A),
/* K22 */ be_nested_str_weak(w),
/* K23 */ be_nested_str_weak(Cannot_X20create_X20output_X20file_X3A_X20_X25s),
/* K24 */ be_nested_str_weak(write),
}), }),
be_str_weak(init), be_str_weak(compile_file),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */ ( &(const binstruction[71]) { /* code */
0x90020101, // 0000 SETMBR R0 K0 K1 0xA4060000, // 0000 IMPORT R1 K0
0x80000000, // 0001 RET 0 0xA40A0200, // 0001 IMPORT R2 K1
0x8C0C0302, // 0002 GETMET R3 R1 K2
0x5C140000, // 0003 MOVE R5 R0
0x58180003, // 0004 LDCONST R6 K3
0x7C0C0600, // 0005 CALL R3 3
0x740E0004, // 0006 JMPT R3 #000C
0x600C0018, // 0007 GETGBL R3 G24
0x58100004, // 0008 LDCONST R4 K4
0x5C140000, // 0009 MOVE R5 R0
0x7C0C0400, // 000A CALL R3 2
0xB0060A03, // 000B RAISE 1 K5 R3
0x540DFFF9, // 000C LDINT R3 -6
0x400E0C03, // 000D CONNECT R3 K6 R3
0x940C0003, // 000E GETIDX R3 R0 R3
0x00100707, // 000F ADD R4 R3 K7
0x60140011, // 0010 GETGBL R5 G17
0x5C180000, // 0011 MOVE R6 R0
0x581C0008, // 0012 LDCONST R7 K8
0x7C140400, // 0013 CALL R5 2
0x4C180000, // 0014 LDNIL R6
0x1C180A06, // 0015 EQ R6 R5 R6
0x781A0004, // 0016 JMPF R6 #001C
0x60180018, // 0017 GETGBL R6 G24
0x581C0009, // 0018 LDCONST R7 K9
0x5C200000, // 0019 MOVE R8 R0
0x7C180400, // 001A CALL R6 2
0xB0061406, // 001B RAISE 1 K10 R6
0x8C180B0B, // 001C GETMET R6 R5 K11
0x7C180200, // 001D CALL R6 1
0x8C1C0B0C, // 001E GETMET R7 R5 K12
0x7C1C0200, // 001F CALL R7 1
0x8C1C050D, // 0020 GETMET R7 R2 K13
0x5C240C00, // 0021 MOVE R9 R6
0x7C1C0400, // 0022 CALL R7 2
0x4C200000, // 0023 LDNIL R8
0x1C200E08, // 0024 EQ R8 R7 R8
0x78220004, // 0025 JMPF R8 #002B
0x60200018, // 0026 GETGBL R8 G24
0x5824000E, // 0027 LDCONST R9 K14
0x5C280000, // 0028 MOVE R10 R0
0x7C200400, // 0029 CALL R8 2
0xB0061E08, // 002A RAISE 1 K15 R8
0x60200018, // 002B GETGBL R8 G24
0x58240011, // 002C LDCONST R9 K17
0x5C280000, // 002D MOVE R10 R0
0x7C200400, // 002E CALL R8 2
0x00222008, // 002F ADD R8 K16 R8
0x00201112, // 0030 ADD R8 R8 K18
0x00201113, // 0031 ADD R8 R8 K19
0x00201114, // 0032 ADD R8 R8 K20
0x00201115, // 0033 ADD R8 R8 K21
0x60240011, // 0034 GETGBL R9 G17
0x5C280800, // 0035 MOVE R10 R4
0x582C0016, // 0036 LDCONST R11 K22
0x7C240400, // 0037 CALL R9 2
0x4C280000, // 0038 LDNIL R10
0x1C28120A, // 0039 EQ R10 R9 R10
0x782A0004, // 003A JMPF R10 #0040
0x60280018, // 003B GETGBL R10 G24
0x582C0017, // 003C LDCONST R11 K23
0x5C300800, // 003D MOVE R12 R4
0x7C280400, // 003E CALL R10 2
0xB006140A, // 003F RAISE 1 K10 R10
0x8C281318, // 0040 GETMET R10 R9 K24
0x00301007, // 0041 ADD R12 R8 R7
0x7C280400, // 0042 CALL R10 2
0x8C28130C, // 0043 GETMET R10 R9 K12
0x7C280200, // 0044 CALL R10 1
0x50280200, // 0045 LDBOOL R10 1 0
0x80041400, // 0046 RET 1 R10
}) })
) )
); );
@ -2268,45 +2435,52 @@ be_local_closure(class_MockEngine_init, /* name */
/******************************************************************** /********************************************************************
** Solidified function: get_strip_length ** Solidified function: is_keyword
********************************************************************/ ********************************************************************/
be_local_closure(class_MockEngine_get_strip_length, /* name */ be_local_closure(is_keyword, /* name */
be_nested_proto( be_nested_proto(
2, /* nstack */ 5, /* nstack */
1, /* argc */ 1, /* argc */
2, /* varg */ 0, /* varg */
0, /* has upvals */ 0, /* has upvals */
NULL, /* no upvals */ NULL, /* no upvals */
0, /* has sup protos */ 0, /* has sup protos */
NULL, /* no sub protos */ NULL, /* no sub protos */
0, /* has constants */ 1, /* has constants */
NULL, /* no const */ ( &(const bvalue[ 4]) { /* constants */
be_str_weak(get_strip_length), /* K0 */ be_nested_str_weak(animation_dsl),
/* K1 */ be_nested_str_weak(Token),
/* K2 */ be_nested_str_weak(keywords),
/* K3 */ be_nested_str_weak(stop_iteration),
}),
be_str_weak(is_keyword),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */ ( &(const binstruction[19]) { /* code */
0x5406001D, // 0000 LDINT R1 30 0xA4060000, // 0000 IMPORT R1 K0
0x80040200, // 0001 RET 1 R1 0x60080010, // 0001 GETGBL R2 G16
0x880C0301, // 0002 GETMBR R3 R1 K1
0x880C0702, // 0003 GETMBR R3 R3 K2
0x7C080200, // 0004 CALL R2 1
0xA8020007, // 0005 EXBLK 0 #000E
0x5C0C0400, // 0006 MOVE R3 R2
0x7C0C0000, // 0007 CALL R3 0
0x1C100003, // 0008 EQ R4 R0 R3
0x78120002, // 0009 JMPF R4 #000D
0x50100200, // 000A LDBOOL R4 1 0
0xA8040001, // 000B EXBLK 1 1
0x80040800, // 000C RET 1 R4
0x7001FFF7, // 000D JMP #0006
0x58080003, // 000E LDCONST R2 K3
0xAC080200, // 000F CATCH R2 1 0
0xB0080000, // 0010 RAISE 2 R0 R0
0x50080000, // 0011 LDBOOL R2 0 0
0x80040400, // 0012 RET 1 R2
}) })
) )
); );
/*******************************************************************/ /*******************************************************************/
/********************************************************************
** Solidified class: MockEngine
********************************************************************/
be_local_class(MockEngine,
1,
NULL,
be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(time_ms, 1), be_const_var(0) },
{ be_const_key_weak(init, -1), be_const_closure(class_MockEngine_init_closure) },
{ be_const_key_weak(get_strip_length, -1), be_const_closure(class_MockEngine_get_strip_length_closure) },
})),
be_str_weak(MockEngine)
);
/******************************************************************** /********************************************************************
** Solidified function: compile_dsl_source ** Solidified function: compile_dsl_source
********************************************************************/ ********************************************************************/
@ -3542,53 +3716,6 @@ be_local_class(SymbolTable,
})), })),
be_str_weak(SymbolTable) be_str_weak(SymbolTable)
); );
/********************************************************************
** Solidified function: is_keyword
********************************************************************/
be_local_closure(is_keyword, /* name */
be_nested_proto(
5, /* nstack */
1, /* argc */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str_weak(animation_dsl),
/* K1 */ be_nested_str_weak(Token),
/* K2 */ be_nested_str_weak(keywords),
/* K3 */ be_nested_str_weak(stop_iteration),
}),
be_str_weak(is_keyword),
&be_const_str_solidified,
( &(const binstruction[19]) { /* code */
0xA4060000, // 0000 IMPORT R1 K0
0x60080010, // 0001 GETGBL R2 G16
0x880C0301, // 0002 GETMBR R3 R1 K1
0x880C0702, // 0003 GETMBR R3 R3 K2
0x7C080200, // 0004 CALL R2 1
0xA8020007, // 0005 EXBLK 0 #000E
0x5C0C0400, // 0006 MOVE R3 R2
0x7C0C0000, // 0007 CALL R3 0
0x1C100003, // 0008 EQ R4 R0 R3
0x78120002, // 0009 JMPF R4 #000D
0x50100200, // 000A LDBOOL R4 1 0
0xA8040001, // 000B EXBLK 1 1
0x80040800, // 000C RET 1 R4
0x7001FFF7, // 000D JMP #0006
0x58080003, // 000E LDCONST R2 K3
0xAC080200, // 000F CATCH R2 1 0
0xB0080000, // 0010 RAISE 2 R0 R0
0x50080000, // 0011 LDBOOL R2 0 0
0x80040400, // 0012 RET 1 R2
})
)
);
/*******************************************************************/
// compact class 'Lexer' ktab size: 109, total: 288 (saved 1432 bytes) // compact class 'Lexer' ktab size: 109, total: 288 (saved 1432 bytes)
static const bvalue be_ktab_class_Lexer[109] = { static const bvalue be_ktab_class_Lexer[109] = {
/* K0 */ be_nested_str_weak(position), /* K0 */ be_nested_str_weak(position),
@ -5849,125 +5976,75 @@ be_local_closure(load_file, /* name */
/*******************************************************************/ /*******************************************************************/
extern const bclass be_class_MockEngine;
/******************************************************************** /********************************************************************
** Solidified function: compile_file ** Solidified function: init
********************************************************************/ ********************************************************************/
be_local_closure(compile_file, /* name */ be_local_closure(class_MockEngine_init, /* name */
be_nested_proto( be_nested_proto(
13, /* nstack */ 1, /* nstack */
1, /* argc */ 1, /* argc */
0, /* varg */ 2, /* varg */
0, /* has upvals */ 0, /* has upvals */
NULL, /* no upvals */ NULL, /* no upvals */
0, /* has sup protos */ 0, /* has sup protos */
NULL, /* no sub protos */ NULL, /* no sub protos */
1, /* has constants */ 1, /* has constants */
( &(const bvalue[25]) { /* constants */ ( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str_weak(string), /* K0 */ be_nested_str_weak(time_ms),
/* K1 */ be_nested_str_weak(animation_dsl), /* K1 */ be_const_int(0),
/* K2 */ be_nested_str_weak(endswith),
/* K3 */ be_nested_str_weak(_X2Eanim),
/* K4 */ be_nested_str_weak(Input_X20file_X20must_X20have_X20_X2Eanim_X20extension_X3A_X20_X25s),
/* K5 */ be_nested_str_weak(invalid_filename),
/* K6 */ be_const_int(0),
/* K7 */ be_nested_str_weak(_X2Ebe),
/* K8 */ be_nested_str_weak(r),
/* K9 */ be_nested_str_weak(Cannot_X20open_X20input_X20file_X3A_X20_X25s),
/* K10 */ be_nested_str_weak(io_error),
/* K11 */ be_nested_str_weak(read),
/* K12 */ be_nested_str_weak(close),
/* K13 */ be_nested_str_weak(compile),
/* K14 */ be_nested_str_weak(DSL_X20compilation_X20failed_X20for_X3A_X20_X25s),
/* K15 */ be_nested_str_weak(dsl_compilation_error),
/* K16 */ be_nested_str_weak(_X23_X20Generated_X20Berry_X20code_X20from_X20Animation_X20DSL_X0A),
/* K17 */ be_nested_str_weak(_X23_X20Source_X3A_X20_X25s_X0A),
/* K18 */ be_nested_str_weak(_X23_X20Generated_X20automatically_X20by_X20animation_dsl_X2Ecompile_file_X28_X29_X0A),
/* K19 */ be_nested_str_weak(_X23_X20_X0A),
/* K20 */ be_nested_str_weak(_X23_X20Do_X20not_X20edit_X20manually_X20_X2D_X20changes_X20will_X20be_X20overwritten_X0A),
/* K21 */ be_nested_str_weak(_X0A),
/* K22 */ be_nested_str_weak(w),
/* K23 */ be_nested_str_weak(Cannot_X20create_X20output_X20file_X3A_X20_X25s),
/* K24 */ be_nested_str_weak(write),
}), }),
be_str_weak(compile_file), be_str_weak(init),
&be_const_str_solidified, &be_const_str_solidified,
( &(const binstruction[71]) { /* code */ ( &(const binstruction[ 2]) { /* code */
0xA4060000, // 0000 IMPORT R1 K0 0x90020101, // 0000 SETMBR R0 K0 K1
0xA40A0200, // 0001 IMPORT R2 K1 0x80000000, // 0001 RET 0
0x8C0C0302, // 0002 GETMET R3 R1 K2
0x5C140000, // 0003 MOVE R5 R0
0x58180003, // 0004 LDCONST R6 K3
0x7C0C0600, // 0005 CALL R3 3
0x740E0004, // 0006 JMPT R3 #000C
0x600C0018, // 0007 GETGBL R3 G24
0x58100004, // 0008 LDCONST R4 K4
0x5C140000, // 0009 MOVE R5 R0
0x7C0C0400, // 000A CALL R3 2
0xB0060A03, // 000B RAISE 1 K5 R3
0x540DFFF9, // 000C LDINT R3 -6
0x400E0C03, // 000D CONNECT R3 K6 R3
0x940C0003, // 000E GETIDX R3 R0 R3
0x00100707, // 000F ADD R4 R3 K7
0x60140011, // 0010 GETGBL R5 G17
0x5C180000, // 0011 MOVE R6 R0
0x581C0008, // 0012 LDCONST R7 K8
0x7C140400, // 0013 CALL R5 2
0x4C180000, // 0014 LDNIL R6
0x1C180A06, // 0015 EQ R6 R5 R6
0x781A0004, // 0016 JMPF R6 #001C
0x60180018, // 0017 GETGBL R6 G24
0x581C0009, // 0018 LDCONST R7 K9
0x5C200000, // 0019 MOVE R8 R0
0x7C180400, // 001A CALL R6 2
0xB0061406, // 001B RAISE 1 K10 R6
0x8C180B0B, // 001C GETMET R6 R5 K11
0x7C180200, // 001D CALL R6 1
0x8C1C0B0C, // 001E GETMET R7 R5 K12
0x7C1C0200, // 001F CALL R7 1
0x8C1C050D, // 0020 GETMET R7 R2 K13
0x5C240C00, // 0021 MOVE R9 R6
0x7C1C0400, // 0022 CALL R7 2
0x4C200000, // 0023 LDNIL R8
0x1C200E08, // 0024 EQ R8 R7 R8
0x78220004, // 0025 JMPF R8 #002B
0x60200018, // 0026 GETGBL R8 G24
0x5824000E, // 0027 LDCONST R9 K14
0x5C280000, // 0028 MOVE R10 R0
0x7C200400, // 0029 CALL R8 2
0xB0061E08, // 002A RAISE 1 K15 R8
0x60200018, // 002B GETGBL R8 G24
0x58240011, // 002C LDCONST R9 K17
0x5C280000, // 002D MOVE R10 R0
0x7C200400, // 002E CALL R8 2
0x00222008, // 002F ADD R8 K16 R8
0x00201112, // 0030 ADD R8 R8 K18
0x00201113, // 0031 ADD R8 R8 K19
0x00201114, // 0032 ADD R8 R8 K20
0x00201115, // 0033 ADD R8 R8 K21
0x60240011, // 0034 GETGBL R9 G17
0x5C280800, // 0035 MOVE R10 R4
0x582C0016, // 0036 LDCONST R11 K22
0x7C240400, // 0037 CALL R9 2
0x4C280000, // 0038 LDNIL R10
0x1C28120A, // 0039 EQ R10 R9 R10
0x782A0004, // 003A JMPF R10 #0040
0x60280018, // 003B GETGBL R10 G24
0x582C0017, // 003C LDCONST R11 K23
0x5C300800, // 003D MOVE R12 R4
0x7C280400, // 003E CALL R10 2
0xB006140A, // 003F RAISE 1 K10 R10
0x8C281318, // 0040 GETMET R10 R9 K24
0x00301007, // 0041 ADD R12 R8 R7
0x7C280400, // 0042 CALL R10 2
0x8C28130C, // 0043 GETMET R10 R9 K12
0x7C280200, // 0044 CALL R10 1
0x50280200, // 0045 LDBOOL R10 1 0
0x80041400, // 0046 RET 1 R10
}) })
) )
); );
/*******************************************************************/ /*******************************************************************/
/********************************************************************
** Solidified function: get_strip_length
********************************************************************/
be_local_closure(class_MockEngine_get_strip_length, /* name */
be_nested_proto(
2, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
0, /* has constants */
NULL, /* no const */
be_str_weak(get_strip_length),
&be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */
0x5406001D, // 0000 LDINT R1 30
0x80040200, // 0001 RET 1 R1
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: MockEngine
********************************************************************/
be_local_class(MockEngine,
1,
NULL,
be_nested_map(3,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(time_ms, 1), be_const_var(0) },
{ be_const_key_weak(init, -1), be_const_closure(class_MockEngine_init_closure) },
{ be_const_key_weak(get_strip_length, -1), be_const_closure(class_MockEngine_get_strip_length_closure) },
})),
be_str_weak(MockEngine)
);
// ktab too big for class 'SimpleDSLTranspiler' - skipping // ktab too big for class 'SimpleDSLTranspiler' - skipping
extern const bclass be_class_SimpleDSLTranspiler; extern const bclass be_class_SimpleDSLTranspiler;
@ -16076,17 +16153,22 @@ be_local_class(AnimationWebUI,
********************************************************************/ ********************************************************************/
be_local_module(animation_dsl, be_local_module(animation_dsl,
"animation_dsl", "animation_dsl",
be_nested_map(17, be_nested_map(18,
( (struct bmapnode*) &(const bmapnode[]) { ( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(animation_web_ui, -1), be_const_class(be_class_AnimationWebUI) },
{ be_const_key_weak(MockEngine, 14), be_const_class(be_class_MockEngine) },
{ be_const_key_weak(compile_dsl, -1), be_const_closure(compile_dsl_closure) },
{ be_const_key_weak(is_keyword, -1), be_const_closure(is_keyword_closure) },
{ be_const_key_weak(Token, -1), be_const_class(be_class_Token) },
{ be_const_key_weak(create_lexer, -1), be_const_class(be_class_Lexer) }, { be_const_key_weak(create_lexer, -1), be_const_class(be_class_Lexer) },
{ be_const_key_weak(animation_web_ui, -1), be_const_class(be_class_AnimationWebUI) },
{ be_const_key_weak(SimpleDSLTranspiler, -1), be_const_class(be_class_SimpleDSLTranspiler) },
{ be_const_key_weak(compile_dsl, 8), be_const_closure(compile_dsl_closure) },
{ be_const_key_weak(Token, -1), be_const_class(be_class_Token) },
{ be_const_key_weak(VERSION, -1), be_const_int(65536) },
{ be_const_key_weak(compile, -1), be_const_closure(compile_dsl_source_closure) }, { be_const_key_weak(compile, -1), be_const_closure(compile_dsl_source_closure) },
{ be_const_key_weak(compile_file, 9), be_const_closure(compile_file_closure) }, { be_const_key_weak(_symbol_table, 1), be_const_class(be_class_SymbolTable) },
{ be_const_key_weak(named_colors, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { { be_const_key_weak(execute, -1), be_const_closure(execute_closure) },
{ be_const_key_weak(MockEngine, -1), be_const_class(be_class_MockEngine) },
{ be_const_key_weak(wled_palettes, 3), be_const_class(be_class_WLED_Palettes) },
{ be_const_key_weak(compile_file, 16), be_const_closure(compile_file_closure) },
{ be_const_key_weak(is_color_name, -1), be_const_closure(is_color_name_closure) },
{ be_const_key_weak(named_colors, 5), be_const_simple_instance(be_nested_simple_instance(&be_class_map, {
be_const_map( * be_nested_map(37, be_const_map( * be_nested_map(37,
( (struct bmapnode*) &(const bmapnode[]) { ( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(brown, -1), be_const_int(-5952982) }, { be_const_key_weak(brown, -1), be_const_int(-5952982) },
@ -16128,13 +16210,9 @@ be_local_module(animation_dsl,
{ be_const_key_weak(maroon, -1), be_const_int(-8388608) }, { be_const_key_weak(maroon, -1), be_const_int(-8388608) },
})) ) } )) }, })) ) } )) },
{ be_const_key_weak(load_file, -1), be_const_closure(load_file_closure) }, { be_const_key_weak(load_file, -1), be_const_closure(load_file_closure) },
{ be_const_key_weak(_symbol_entry, 6), be_const_class(be_class_SymbolEntry) },
{ be_const_key_weak(is_color_name, 7), be_const_closure(is_color_name_closure) },
{ be_const_key_weak(execute, 0), be_const_closure(execute_closure) },
{ be_const_key_weak(init, -1), be_const_closure(animation_dsl_init_closure) }, { be_const_key_weak(init, -1), be_const_closure(animation_dsl_init_closure) },
{ be_const_key_weak(VERSION, -1), be_const_int(65536) }, { be_const_key_weak(is_keyword, -1), be_const_closure(is_keyword_closure) },
{ be_const_key_weak(_symbol_table, 13), be_const_class(be_class_SymbolTable) }, { be_const_key_weak(_symbol_entry, 12), be_const_class(be_class_SymbolEntry) },
{ be_const_key_weak(SimpleDSLTranspiler, -1), be_const_class(be_class_SimpleDSLTranspiler) },
})) }))
); );
BE_EXPORT_VARIABLE be_define_const_native_module(animation_dsl); BE_EXPORT_VARIABLE be_define_const_native_module(animation_dsl);

View File

@ -44,8 +44,13 @@ class RichPaletteAnimationTest
self.test_palette_properties() self.test_palette_properties()
self.test_css_gradient() self.test_css_gradient()
self.test_cycle_period_zero() self.test_cycle_period_zero()
self.test_sine_mode()
self.test_sine_mode_value_based()
print(f"animation.solid with RichPaletteColorProvider Tests: {self.passed} passed, {self.failed} failed") print(f"animation.solid with RichPaletteColorProvider Tests: {self.passed} passed, {self.failed} failed")
if self.failed > 0
raise "test_failed"
end
end end
def assert_equal(actual, expected, test_name) def assert_equal(actual, expected, test_name)
@ -85,7 +90,7 @@ class RichPaletteAnimationTest
var custom_provider = animation.rich_palette(mock_engine) var custom_provider = animation.rich_palette(mock_engine)
custom_provider.palette = custom_palette custom_provider.palette = custom_palette
custom_provider.cycle_period = 2000 custom_provider.cycle_period = 2000
custom_provider.transition_type = animation.LINEAR custom_provider.transition_type = animation.SINE
custom_provider.brightness = 128 custom_provider.brightness = 128
var anim2 = animation.solid(mock_engine) var anim2 = animation.solid(mock_engine)
@ -97,7 +102,7 @@ class RichPaletteAnimationTest
# Check provider properties directly on the provider object # Check provider properties directly on the provider object
self.assert_equal(custom_provider.cycle_period, 2000, "Custom cycle period is 2000ms") self.assert_equal(custom_provider.cycle_period, 2000, "Custom cycle period is 2000ms")
self.assert_equal(custom_provider.transition_type, animation.LINEAR, "Custom transition type is linear") self.assert_equal(custom_provider.transition_type, animation.SINE, "Custom transition type is sine")
self.assert_equal(custom_provider.brightness, 128, "Custom brightness is 128") self.assert_equal(custom_provider.brightness, 128, "Custom brightness is 128")
end end
@ -157,7 +162,6 @@ class RichPaletteAnimationTest
# Test the rainbow factory method # Test the rainbow factory method
var provider = animation.rich_palette_rainbow(mock_engine) var provider = animation.rich_palette_rainbow(mock_engine)
provider.cycle_period = 5000 provider.cycle_period = 5000
provider.transition_type = animation.SINE # sine
provider.brightness = 255 provider.brightness = 255
var anim = animation.solid(mock_engine) var anim = animation.solid(mock_engine)
@ -171,7 +175,7 @@ class RichPaletteAnimationTest
# Check provider properties directly on the provider object # Check provider properties directly on the provider object
self.assert_equal(provider.cycle_period, 5000, "Cycle period is 5000ms") self.assert_equal(provider.cycle_period, 5000, "Cycle period is 5000ms")
self.assert_equal(provider.transition_type, animation.SINE, "Transition type is sine") self.assert_equal(provider.transition_type, animation.LINEAR, "Default transition type is linear")
self.assert_equal(provider.brightness, 255, "Brightness is 255") self.assert_equal(provider.brightness, 255, "Brightness is 255")
# Check animation properties # Check animation properties
@ -278,6 +282,107 @@ class RichPaletteAnimationTest
# Note: Colors may be the same depending on palette resolution, so just check they're valid # Note: Colors may be the same depending on palette resolution, so just check they're valid
self.assert_equal(time_color_0 != 0, true, "Time-based color at 0 is valid") self.assert_equal(time_color_0 != 0, true, "Time-based color at 0 is valid")
end end
def test_sine_mode()
# Test SINE mode for smooth ease-in/ease-out transitions
var palette = bytes("00FF0000" "FF0000FF") # Red at 0, Blue at 255
# Create LINEAR provider
var provider_linear = animation.rich_palette(mock_engine)
provider_linear.palette = palette
provider_linear.cycle_period = 1000
provider_linear.transition_type = animation.LINEAR
provider_linear.brightness = 255
provider_linear.start(0)
# Create SINE provider
var provider_sine = animation.rich_palette(mock_engine)
provider_sine.palette = palette
provider_sine.cycle_period = 1000
provider_sine.transition_type = animation.SINE
provider_sine.brightness = 255
provider_sine.start(0)
# Test that transition_type is set correctly
self.assert_equal(provider_linear.transition_type, animation.LINEAR, "LINEAR mode is set")
self.assert_equal(provider_sine.transition_type, animation.SINE, "SINE mode is set")
# Test at 0% - should be identical (Red)
var linear_0 = provider_linear.produce_value("color", 0)
var sine_0 = provider_sine.produce_value("color", 0)
self.assert_equal(linear_0, sine_0, "LINEAR and SINE identical at 0%")
# Test at 10% - SINE should have less blue (slower start)
var linear_100 = provider_linear.produce_value("color", 100)
var sine_100 = provider_sine.produce_value("color", 100)
var linear_blue_100 = linear_100 & 0xFF
var sine_blue_100 = sine_100 & 0xFF
self.assert_equal(linear_blue_100 > sine_blue_100, true, "SINE slower than LINEAR at 10%")
# Test at 25% - SINE should still be slower
var linear_250 = provider_linear.produce_value("color", 250)
var sine_250 = provider_sine.produce_value("color", 250)
var linear_blue_250 = linear_250 & 0xFF
var sine_blue_250 = sine_250 & 0xFF
self.assert_equal(linear_blue_250 > sine_blue_250, true, "SINE slower than LINEAR at 25%")
# Test at 50% - both should be at midpoint (approximately)
var linear_500 = provider_linear.produce_value("color", 500)
var sine_500 = provider_sine.produce_value("color", 500)
# Colors should be very close at midpoint
self.assert_approx_equal(linear_500, sine_500, "LINEAR and SINE similar at 50%")
# Test ease-in behavior: change from 0-100ms should be smaller than 100-250ms for SINE
var sine_blue_0 = sine_0 & 0xFF
var change_0_100 = sine_blue_100 - sine_blue_0
var change_100_250 = sine_blue_250 - sine_blue_100
self.assert_equal(change_0_100 < change_100_250, true, "SINE has ease-in (slow start)")
end
def test_sine_mode_value_based()
# Test SINE mode with value-based interpolation
var palette = bytes("00FF0000" "FF0000FF") # Red to Blue
var provider = animation.rich_palette(mock_engine)
provider.palette = palette
provider.cycle_period = 0 # Value-based mode
provider.transition_type = animation.SINE
provider.range_min = 0
provider.range_max = 100
provider.start()
# Get colors at different values
var color_0 = provider.get_color_for_value(0, 0)
var color_25 = provider.get_color_for_value(25, 0)
var color_50 = provider.get_color_for_value(50, 0)
var color_75 = provider.get_color_for_value(75, 0)
var color_100 = provider.get_color_for_value(100, 0)
# Extract blue channel
var blue_0 = color_0 & 0xFF
var blue_25 = color_25 & 0xFF
var blue_50 = color_50 & 0xFF
var blue_75 = color_75 & 0xFF
var blue_100 = color_100 & 0xFF
# Test that we have a smooth S-curve
# Change from 0-25 should be smaller than 25-50 (ease-in)
var change_0_25 = blue_25 - blue_0
var change_25_50 = blue_50 - blue_25
self.assert_equal(change_0_25 < change_25_50, true, "Value-based SINE has ease-in")
# Change from 50-75 should be larger than 75-100 (ease-out)
var change_50_75 = blue_75 - blue_50
var change_75_100 = blue_100 - blue_75
self.assert_equal(change_50_75 > change_75_100, true, "Value-based SINE has ease-out")
# Midpoint should be approximately 128
self.assert_approx_equal(blue_50, 128, "Value-based SINE midpoint is ~128")
end
end end
# Run the tests # Run the tests