From 30a31f40c4bf5d08caf8cc86dddf4d20d3d374bf Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Thu, 25 Dec 2025 20:20:55 +0100 Subject: [PATCH] Berry animation rename from crenel_position_animation to crenel_animation (#24257) --- lib/libesp32/berry_animation/README.md | 2 +- ..._6_30_shutter_central_rotating_colors.anim | 35 ++ .../chap_6_40_shutter_central_inoutin.anim | 50 ++ .../anim_tutorials/chap_7_10_crenel.anim | 10 + .../chap_7_20_crenel_nb_pulses.anim | 14 + .../anim_tutorials/chap_7_30_crenel_size.anim | 13 + .../chap_7_40_crenel_colors.anim | 13 + .../chap_7_50_crenel_opacity.anim | 23 + .../anim_tutorials/png/chap_6_30.png | Bin 0 -> 23374 bytes .../anim_tutorials/png/chap_6_40.png | Bin 0 -> 46585 bytes .../anim_tutorials/png/chap_7_10.png | Bin 0 -> 2011 bytes .../anim_tutorials/png/chap_7_20.png | Bin 0 -> 3876 bytes .../anim_tutorials/png/chap_7_30.png | Bin 0 -> 3835 bytes .../anim_tutorials/png/chap_7_40.png | Bin 0 -> 10291 bytes .../anim_tutorials/png/chap_7_50.png | Bin 0 -> 6556 bytes .../ANIMATION_CLASS_HIERARCHY.md | 10 +- .../berry_animation_docs/DSL_REFERENCE.md | 2 +- .../docs/ANIMATION_CLASS_HIERARCHY.md | 10 +- .../berry_animation/docs/DSL_REFERENCE.md | 2 +- lib/libesp32/berry_animation/src/animation.be | 4 +- .../src/animations/crenel_position.be | 2 +- .../src/solidify/solidified_animation.h | 442 +++++++++--------- .../tests/crenel_position_animation_test.be | 2 +- .../src/tests/crenel_position_color_test.be | 14 +- .../syntaxes/animation-dsl.tmLanguage.json | 2 +- 25 files changed, 404 insertions(+), 246 deletions(-) create mode 100644 lib/libesp32/berry_animation/anim_tutorials/chap_6_30_shutter_central_rotating_colors.anim create mode 100644 lib/libesp32/berry_animation/anim_tutorials/chap_6_40_shutter_central_inoutin.anim create mode 100644 lib/libesp32/berry_animation/anim_tutorials/chap_7_10_crenel.anim create mode 100644 lib/libesp32/berry_animation/anim_tutorials/chap_7_20_crenel_nb_pulses.anim create mode 100644 lib/libesp32/berry_animation/anim_tutorials/chap_7_30_crenel_size.anim create mode 100644 lib/libesp32/berry_animation/anim_tutorials/chap_7_40_crenel_colors.anim create mode 100644 lib/libesp32/berry_animation/anim_tutorials/chap_7_50_crenel_opacity.anim create mode 100644 lib/libesp32/berry_animation/anim_tutorials/png/chap_6_30.png create mode 100644 lib/libesp32/berry_animation/anim_tutorials/png/chap_6_40.png create mode 100644 lib/libesp32/berry_animation/anim_tutorials/png/chap_7_10.png create mode 100644 lib/libesp32/berry_animation/anim_tutorials/png/chap_7_20.png create mode 100644 lib/libesp32/berry_animation/anim_tutorials/png/chap_7_30.png create mode 100644 lib/libesp32/berry_animation/anim_tutorials/png/chap_7_40.png create mode 100644 lib/libesp32/berry_animation/anim_tutorials/png/chap_7_50.png diff --git a/lib/libesp32/berry_animation/README.md b/lib/libesp32/berry_animation/README.md index 416cbf8e0..6f9385f53 100644 --- a/lib/libesp32/berry_animation/README.md +++ b/lib/libesp32/berry_animation/README.md @@ -158,7 +158,7 @@ Animation|Description `pulsating_animation`|Breathing/pulsing effect with smooth transitions `breathe_animation`|Natural breathing effect with customizable curve `beacon_animation`|Pulse/highlight at specific position with optional slew -`crenel_position_animation`|Crenel/square wave pattern +`crenel_animation`|Crenel/square wave pattern `comet_animation`|Moving comet with fading tail `twinkle_animation`|Twinkling stars effect `fire_animation`|Realistic fire simulation diff --git a/lib/libesp32/berry_animation/anim_tutorials/chap_6_30_shutter_central_rotating_colors.anim b/lib/libesp32/berry_animation/anim_tutorials/chap_6_30_shutter_central_rotating_colors.anim new file mode 100644 index 000000000..e78c061c6 --- /dev/null +++ b/lib/libesp32/berry_animation/anim_tutorials/chap_6_30_shutter_central_rotating_colors.anim @@ -0,0 +1,35 @@ +# @desc Shutter central inout with rotating colors, using sequence + +# Define 'strip_len' to make calculations +set strip_len = strip_length() +set strip_len_2 = (strip_len + 1) / 2 # half length rounded + +# Set a global variable for 'period' +set period = 1.5s + +# Define shutter_size as a sawtootgh from 0 to strip_len +set shutter_size = sawtooth(min_value = 0, max_value = strip_len, + duration = period) + +# Define 2 color providers cycling through palette rainbow with white +# 'col2' is shifted by 1 color from 'col1' +color col1 = color_cycle(palette=PALETTE_RAINBOW_W, cycle_period=0) +color col2 = color_cycle(palette=PALETTE_RAINBOW_W, cycle_period=0) +col2.next = 1 # Writing 1 to 'next' actually advances the color + +# Using beacon_animation to move a shutter from in to out +animation shutter_inout_animation = beacon_animation( + color = col2 # Use two rotating colors + back_color = col1 # Use two rotating colors + pos = strip_len_2 - (shutter_size + 1) / 2 + beacon_size = shutter_size +) + +# Use sequence to advance after each shutter animation +sequence shutter_seq repeat forever { + restart shutter_size # Make sure that shutter_size is synced with the sequence + play shutter_inout_animation for period + col1.next = 1 # set 'col1' to next color + col2.next = 1 # set 'col2' to next color +} +run shutter_seq \ No newline at end of file diff --git a/lib/libesp32/berry_animation/anim_tutorials/chap_6_40_shutter_central_inoutin.anim b/lib/libesp32/berry_animation/anim_tutorials/chap_6_40_shutter_central_inoutin.anim new file mode 100644 index 000000000..c3fe34f0c --- /dev/null +++ b/lib/libesp32/berry_animation/anim_tutorials/chap_6_40_shutter_central_inoutin.anim @@ -0,0 +1,50 @@ +# @desc Shutter central inout and outin with rotating colors, using sequence + +# Define 'strip_len' to make calculations +set strip_len = strip_length() +set strip_len_2 = (strip_len + 1) / 2 # half length rounded + +# Set a global variable for 'period' +set period = 1.5s + +# Define shutter_size as a sawtootgh from 0 to strip_len +set shutter_size = sawtooth(min_value = 0, max_value = strip_len, + duration = period) + +# Define 2 color providers cycling through palette rainbow with white +# 'col2' is shifted by 1 color from 'col1' +color col1 = color_cycle(palette=PALETTE_RAINBOW_W, cycle_period=0) +color col2 = color_cycle(palette=PALETTE_RAINBOW_W, cycle_period=0) +col2.next = 1 # Writing 1 to 'next' actually advances the color + +# Using beacon_animation to move a shutter from in to out +animation shutter_inout_animation = beacon_animation( + color = col2 # Use two rotating colors + back_color = col1 # Use two rotating colors + pos = strip_len_2 - (shutter_size + 1) / 2 + beacon_size = shutter_size +) + +# Similar but out to in +animation shutter_outin_animation = beacon_animation( + color = col1 + back_color = col2 + pos = strip_len_2 - (strip_len - shutter_size + 1) / 2 + beacon_size = strip_len - shutter_size +) + +sequence shutter_seq repeat forever { + repeat col1.palette_size times { + restart shutter_size # Make sure that shutter_size is synced with the sequence + play shutter_inout_animation for period + col1.next = 1 # set 'col1' to next color + col2.next = 1 # set 'col2' to next color + } + repeat col1.palette_size times { + restart shutter_size # Make sure that shutter_size is synced with the sequence + play shutter_outin_animation for period + col1.next = 1 # set 'col1' to next color + col2.next = 1 # set 'col2' to next color + } +} +run shutter_seq \ No newline at end of file diff --git a/lib/libesp32/berry_animation/anim_tutorials/chap_7_10_crenel.anim b/lib/libesp32/berry_animation/anim_tutorials/chap_7_10_crenel.anim new file mode 100644 index 000000000..fde8e3741 --- /dev/null +++ b/lib/libesp32/berry_animation/anim_tutorials/chap_7_10_crenel.anim @@ -0,0 +1,10 @@ +# @desc Crenel static + +# Define a simple crenel 2+2 red/blue +animation back = crenel_animation( + color = red + back_color = blue + pulse_size = 2 + low_size = 2 +) +run back \ No newline at end of file diff --git a/lib/libesp32/berry_animation/anim_tutorials/chap_7_20_crenel_nb_pulses.anim b/lib/libesp32/berry_animation/anim_tutorials/chap_7_20_crenel_nb_pulses.anim new file mode 100644 index 000000000..5efa6ed72 --- /dev/null +++ b/lib/libesp32/berry_animation/anim_tutorials/chap_7_20_crenel_nb_pulses.anim @@ -0,0 +1,14 @@ +# @desc Crenel static with variable number of pulses + +# Move from 0 to 5 and back +set nb_pulse = triangle(min_value = 0, max_value = 5, duration = 2s) + +# Define a simple crenel 2+2 red/blue +animation back = crenel_animation( + color = red + back_color = blue + pulse_size = 2 + low_size = 2 + nb_pulse = nb_pulse +) +run back \ No newline at end of file diff --git a/lib/libesp32/berry_animation/anim_tutorials/chap_7_30_crenel_size.anim b/lib/libesp32/berry_animation/anim_tutorials/chap_7_30_crenel_size.anim new file mode 100644 index 000000000..f0d141c3a --- /dev/null +++ b/lib/libesp32/berry_animation/anim_tutorials/chap_7_30_crenel_size.anim @@ -0,0 +1,13 @@ +# @desc Crenel static with variable size + +# Move from 0 to 5 and back +set pulse_size = triangle(min_value = 0, max_value = 4, duration = 2s) + +# Define a simple crenel 2+2 red/blue +animation back = crenel_animation( + color = red + back_color = blue + pulse_size = pulse_size + low_size = 2 +) +run back \ No newline at end of file diff --git a/lib/libesp32/berry_animation/anim_tutorials/chap_7_40_crenel_colors.anim b/lib/libesp32/berry_animation/anim_tutorials/chap_7_40_crenel_colors.anim new file mode 100644 index 000000000..2567887f4 --- /dev/null +++ b/lib/libesp32/berry_animation/anim_tutorials/chap_7_40_crenel_colors.anim @@ -0,0 +1,13 @@ +# @desc Crenel static with variable color + +# Define a color attribute that cycles over time, cycle is 5 seconds +color rainbow_color = rich_palette(palette=PALETTE_RAINBOW_W2, cycle_period=5s) + +# Define a simple crenel 2+2 +animation back = crenel_animation( + color = rainbow_color + back_color = blue + pulse_size = 2 + low_size = 2 +) +run back \ No newline at end of file diff --git a/lib/libesp32/berry_animation/anim_tutorials/chap_7_50_crenel_opacity.anim b/lib/libesp32/berry_animation/anim_tutorials/chap_7_50_crenel_opacity.anim new file mode 100644 index 000000000..1ef3d328c --- /dev/null +++ b/lib/libesp32/berry_animation/anim_tutorials/chap_7_50_crenel_opacity.anim @@ -0,0 +1,23 @@ +# @desc Crenel used as opacity mask + +# Set a blue background with low priority (background) +animation back = solid(color = blue, priority = 20) +run back + +# Define a simple crenel 2+2 opaque/transparent +animation mask = crenel_animation( + color = white # plain color since it's used as opacity mask + back_color = transparent # background is transparent + pulse_size = 2 + low_size = 2 +) + +# Define a smooth palette using PALETTE_RAINBOW_W (7 colors + white) +color rainbow_rich_color = rich_palette(palette=PALETTE_RAINBOW_W, cycle_period=0) +# Define a gradient across the whole strip and use crenel as opacity mask +animation pattern = palette_gradient_animation( + color_source = rainbow_rich_color # use the rainow pattern + shift_period = 2s # shifting over 2s + opacity = mask # mask it with crenel pattern +) +run pattern \ No newline at end of file diff --git a/lib/libesp32/berry_animation/anim_tutorials/png/chap_6_30.png b/lib/libesp32/berry_animation/anim_tutorials/png/chap_6_30.png new file mode 100644 index 0000000000000000000000000000000000000000..8149a277bd6e3ea7d169b9ce6592115f1236311a GIT binary patch literal 23374 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 M=S5C8XZywdKWgkCu>b%7 literal 0 HcmV?d00001 diff --git a/lib/libesp32/berry_animation/anim_tutorials/png/chap_6_40.png b/lib/libesp32/berry_animation/anim_tutorials/png/chap_6_40.png new file mode 100644 index 0000000000000000000000000000000000000000..b833db5f9a24dbbfd0e3e04c5d8d05b0a8baf29c GIT binary patch literal 46585 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 WSyT9Bn8DuzFSXERyy8V4rvD9{H%OoW literal 0 HcmV?d00001 diff --git a/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_10.png b/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_10.png new file mode 100644 index 0000000000000000000000000000000000000000..043fe2fc3c2f98729addb46baefc811939415efb GIT binary patch literal 2011 zcmeAS@N?(olHy`uVBq!ia0vp^?|_(#gAGV-wocjxq&O0jLwtZVKM*r;%Z48WQc`IU zF^~{g1Bd|z&de_u7}jJyY6bFqJY5_^DsH{KY{Isqy_^9auUcswx zkX!&NAF$-cTbY(1x509w05x6k^?-3Nk_!Z}yTB}?PZr4qLezA@+WhVxNG=e@?t@F}f(eFcYffzMiAY<@b2+0NF*j;dY(I1dIVd+4EnlA9+ zzaoL;0!i#HFuQox8p#Dx)O3N!f}C6=7f54w!EJZBOGqw|p{5J|1}ymmG@HTG)z4*} HQ$iB}UI3YA literal 0 HcmV?d00001 diff --git a/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_20.png b/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_20.png new file mode 100644 index 0000000000000000000000000000000000000000..31a5eb4ff97e0425957168bc18f577b86b9b41ec GIT binary patch literal 3876 zcmb`Ke@qis9Ka7au!FV~MxhieMHCSf1bgk2WTmc9h(^KSj0j_FgUJGdnVZwhF_8UA zlsL2LhBDn4&KbqHZVM<&2f-LO8HmWR=O#ZoK^FwaQZz_!@31fXCcgjrn!LX2ebe{( z+ztXbIrrfve2Otn-@76&{&x0g^meCgIbb< zB3UJ`m~v6?EmEW9h{~FN5d^7(ZN9kiN-g{PpuS%<>KOjB>AqE{DypbB_W8xa>Wtce z4&T}UNtoCaiIT9fVxJ;}uInD*0osR*w(sLx0Gg$OuDQEo5TJd@XhX)g9Vn9HzG^=a zogB;rDbh_hh2JD>O6>92vF0;&N6hXY4yV|x=Utmd%A<@yyzQsiO94*j{XG}jl$lT5 z_~$z#x!pU@u)My5V9}%%wrjC=`t8 zklvK?I;hC%V&atK^WP9|LW1Jz(7UQU~OQZ3K)cw4fI#LQh|Y*ra{Q@vT|S$ zK{ntmnqFWKNz-69`|E#zfmri|ccOlO*-2oap=r=0M1BAaqR0k(gw2E^cuLS>11eL( z_})bLc8(@1Z~}W7C@i3=(Dgmrg9gWIlNhqXKDq&{S+81CL0WJZ(4yt98H7uS7wg^gC%4GF2gc`BDfag=L&(= zT4}Fv!~zt=6%io~13jOJ>uRj9l&ZqWiNC}g<4RaYR^ZgP-$oI%ADFEs-o>DJuAFBk^m1L?; b*WL)It30L7?^`pA#$&S5*O{AFzgY7h?qV@c literal 0 HcmV?d00001 diff --git a/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_30.png b/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_30.png new file mode 100644 index 0000000000000000000000000000000000000000..37c3084d5f83846bdbd44204412ff2ad625465dc GIT binary patch literal 3835 zcmb`~c}!C=90%|>88A1710BQRV2X+-2<~knkue+~L5L%0yz%A`2}yob9n!V3=ZC~5%oRJVC6)VLI z!$@PN852?c0Tr>x1wCI5TXGduqQy&-rlZ;y6=qgR>nBtxSN!=5fAsqc_{HzXRHt_g zb1v<50eTk^YcwRSw{|?fBxTfYPL}H4FxOgP=I+E7PY+&Cp4lkB_Bh}e$8lS@&MvvP zu~I!hqH=4N0Tn@0epcQb_XU}9&p9J(CFokbC_t|XqE0C?p_cd+%M3}V?uXT2cShzG zVR~V|ceu8^v3Pxui&OleS1BuhRDH>oOfl!$UZ$MpZinkXOw7;Di`*uuao#2oDR7Ym ziWC*g1uGG64H2~f-igdx3%N?b3#suoK~yi`oyoi|`b-VrU8wONJM;Pj-j&Q-A8Z_p zT4wZhzUW`x+fCb{ZtYq){NUa|^ZjREH?+05OOro!E3S2$&D^VA_M4w2nb`lUQUBYT zRM{W_PD2|0(ztaXftY53s)RCpH}DfsLQY_14<82!+-N44d1KWPkU&aKptHZXp_YWc zQE>k+L3{DEvYVUs%oeJ0Pn_?_slV?#xhE_9M?t&&XnmFbt;#ZwI0iXr4D=VT4hH@J zvTscb#mRVIM$h+XjA{bD2ie!A7O8;mNzV`QxKj-Lfn=ZSUGN#TOz-ReLD&x!qlJ$# zG~4a%g0JPK#5?K+VQuxT)Kw+dC#_5W-rUosIQz3cw>_n;F7%`fEqa2cel^ax;N>X& z$c7BLXTkD{R-nttx>gfZ1avQ2`lUjzD?nF}b?#J83edf2>3Z4t0HEVpNVxm85ATKn zT}exqbnn{;bRV+L#rQq~`VdgqAM!fwe z@JEn+wzO<6YTTM*!c4g!$LNuDuKrjG~z!Gkz!D(f9&Z&*&&#i8r*eLj(_KKC(Y z09E6tnxh{J7kiehY99J~0afd$da-zi3|)`^tva&$Jf_PI)Jcx2w^zS|OKT`u)o3iG XK%MNUs(KQK7gQ!TD#3Uma#8*-Uv~!3 literal 0 HcmV?d00001 diff --git a/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_40.png b/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_40.png new file mode 100644 index 0000000000000000000000000000000000000000..a1dae722a67ddc339b3285d0e540d08244ddd23d GIT binary patch literal 10291 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 literal 0 HcmV?d00001 diff --git a/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_50.png b/lib/libesp32/berry_animation/anim_tutorials/png/chap_7_50.png new file mode 100644 index 0000000000000000000000000000000000000000..c5581fb9d08db656cfeba90c5eca9dfe8a167793 GIT binary patch literal 6556 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 T+g1is0kb=D%<8#?SKPk=b}*J$ literal 0 HcmV?d00001 diff --git a/lib/libesp32/berry_animation/berry_animation_docs/ANIMATION_CLASS_HIERARCHY.md b/lib/libesp32/berry_animation/berry_animation_docs/ANIMATION_CLASS_HIERARCHY.md index f4b085590..e07eeed40 100644 --- a/lib/libesp32/berry_animation/berry_animation_docs/ANIMATION_CLASS_HIERARCHY.md +++ b/lib/libesp32/berry_animation/berry_animation_docs/ANIMATION_CLASS_HIERARCHY.md @@ -906,7 +906,7 @@ The full period of the pattern is `pulse_size + low_size` pixels. **Status Indicators:** ```berry # Slow blinking pattern for status indication -animation status_indicator = crenel_position_animation( +animation status_indicator = crenel_animation( color=green, pulse_size=1, low_size=9 @@ -916,7 +916,7 @@ animation status_indicator = crenel_position_animation( **Rhythmic Effects:** ```berry # Fast rhythmic pattern -animation rhythm_pattern = crenel_position_animation( +animation rhythm_pattern = crenel_animation( color=red, pulse_size=2, low_size=2 @@ -927,7 +927,7 @@ animation rhythm_pattern = crenel_position_animation( ```berry # Decorative border pattern color gold = 0xFFFFD700 -animation border_pattern = crenel_position_animation( +animation border_pattern = crenel_animation( color=gold, pulse_size=3, low_size=1, @@ -938,7 +938,7 @@ animation border_pattern = crenel_position_animation( **Progress Indicators:** ```berry # Progress bar with limited pulses -animation progress_bar = crenel_position_animation( +animation progress_bar = crenel_animation( color=0xFF0080FF, pulse_size=2, low_size=1, @@ -954,7 +954,7 @@ animation progress_bar = crenel_position_animation( - **Framework Integration**: Seamless integration with animation engine - **Testing**: Comprehensive test suite covering edge cases and performance -**Factory**: `animation.crenel_position_animation(engine)` +**Factory**: `animation.crenel_animation(engine)` ### RichPaletteAnimation diff --git a/lib/libesp32/berry_animation/berry_animation_docs/DSL_REFERENCE.md b/lib/libesp32/berry_animation/berry_animation_docs/DSL_REFERENCE.md index ab430e906..77c422013 100644 --- a/lib/libesp32/berry_animation/berry_animation_docs/DSL_REFERENCE.md +++ b/lib/libesp32/berry_animation/berry_animation_docs/DSL_REFERENCE.md @@ -1435,7 +1435,7 @@ Animation classes create visual effects on LED strips: | `solid` | Solid color fill | | `pulsating_animation` | Pulsing brightness effect | | `beacon_animation` | Positioned pulse effect | -| `crenel_position_animation` | Square wave pulse at specific position | +| `crenel_animation` | Square wave pulse at specific position | | `breathe_animation` | Breathing/fading effect | | `comet_animation` | Moving comet with trailing tail | | `fire_animation` | Realistic fire simulation | diff --git a/lib/libesp32/berry_animation/docs/ANIMATION_CLASS_HIERARCHY.md b/lib/libesp32/berry_animation/docs/ANIMATION_CLASS_HIERARCHY.md index 4b9551599..c4813456c 100644 --- a/lib/libesp32/berry_animation/docs/ANIMATION_CLASS_HIERARCHY.md +++ b/lib/libesp32/berry_animation/docs/ANIMATION_CLASS_HIERARCHY.md @@ -916,7 +916,7 @@ The full period of the pattern is `pulse_size + low_size` pixels. **Status Indicators:** ```berry # Slow blinking pattern for status indication -animation status_indicator = crenel_position_animation( +animation status_indicator = crenel_animation( color=green, pulse_size=1, low_size=9 @@ -926,7 +926,7 @@ animation status_indicator = crenel_position_animation( **Rhythmic Effects:** ```berry # Fast rhythmic pattern -animation rhythm_pattern = crenel_position_animation( +animation rhythm_pattern = crenel_animation( color=red, pulse_size=2, low_size=2 @@ -937,7 +937,7 @@ animation rhythm_pattern = crenel_position_animation( ```berry # Decorative border pattern color gold = 0xFFFFD700 -animation border_pattern = crenel_position_animation( +animation border_pattern = crenel_animation( color=gold, pulse_size=3, low_size=1, @@ -948,7 +948,7 @@ animation border_pattern = crenel_position_animation( **Progress Indicators:** ```berry # Progress bar with limited pulses -animation progress_bar = crenel_position_animation( +animation progress_bar = crenel_animation( color=0xFF0080FF, pulse_size=2, low_size=1, @@ -964,7 +964,7 @@ animation progress_bar = crenel_position_animation( - **Framework Integration**: Seamless integration with animation engine - **Testing**: Comprehensive test suite covering edge cases and performance -**Factory**: `animation.crenel_position_animation(engine)` +**Factory**: `animation.crenel_animation(engine)` ### RichPaletteAnimation diff --git a/lib/libesp32/berry_animation/docs/DSL_REFERENCE.md b/lib/libesp32/berry_animation/docs/DSL_REFERENCE.md index ab430e906..77c422013 100644 --- a/lib/libesp32/berry_animation/docs/DSL_REFERENCE.md +++ b/lib/libesp32/berry_animation/docs/DSL_REFERENCE.md @@ -1435,7 +1435,7 @@ Animation classes create visual effects on LED strips: | `solid` | Solid color fill | | `pulsating_animation` | Pulsing brightness effect | | `beacon_animation` | Positioned pulse effect | -| `crenel_position_animation` | Square wave pulse at specific position | +| `crenel_animation` | Square wave pulse at specific position | | `breathe_animation` | Breathing/fading effect | | `comet_animation` | Moving comet with trailing tail | | `fire_animation` | Realistic fire simulation | diff --git a/lib/libesp32/berry_animation/src/animation.be b/lib/libesp32/berry_animation/src/animation.be index 1e63e3496..1ba885bf6 100644 --- a/lib/libesp32/berry_animation/src/animation.be +++ b/lib/libesp32/berry_animation/src/animation.be @@ -139,8 +139,8 @@ import "animations/solid" as solid_impl register_to_animation(solid_impl) import "animations/beacon" as beacon_animation register_to_animation(beacon_animation) -import "animations/crenel_position" as crenel_position_animation -register_to_animation(crenel_position_animation) +import "animations/crenel_position" as crenel_animation +register_to_animation(crenel_animation) import "animations/breathe" as breathe_animation register_to_animation(breathe_animation) import "animations/palette_pattern" as palette_pattern_animation diff --git a/lib/libesp32/berry_animation/src/animations/crenel_position.be b/lib/libesp32/berry_animation/src/animations/crenel_position.be index 763c2a750..ce3176c68 100644 --- a/lib/libesp32/berry_animation/src/animations/crenel_position.be +++ b/lib/libesp32/berry_animation/src/animations/crenel_position.be @@ -121,4 +121,4 @@ class CrenelPositionAnimation : animation.animation end end -return {'crenel_position_animation': CrenelPositionAnimation} +return {'crenel_animation': CrenelPositionAnimation} diff --git a/lib/libesp32/berry_animation/src/solidify/solidified_animation.h b/lib/libesp32/berry_animation/src/solidify/solidified_animation.h index fe210f6ba..f247030bb 100644 --- a/lib/libesp32/berry_animation/src/solidify/solidified_animation.h +++ b/lib/libesp32/berry_animation/src/solidify/solidified_animation.h @@ -14846,32 +14846,36 @@ be_local_class(OscillatorValueProvider, ); /******************************************************************** -** Solidified function: create_closure_value +** Solidified function: pulsating_animation ********************************************************************/ -be_local_closure(create_closure_value, /* name */ +be_local_closure(pulsating_animation, /* name */ be_nested_proto( - 5, /* nstack */ - 2, /* argc */ + 4, /* nstack */ + 1, /* argc */ 0, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ + ( &(const bvalue[ 5]) { /* constants */ /* K0 */ be_nested_str_weak(animation), - /* K1 */ be_nested_str_weak(closure_value), - /* K2 */ be_nested_str_weak(closure), + /* K1 */ be_nested_str_weak(breathe_animation), + /* K2 */ be_nested_str_weak(curve_factor), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_str_weak(period), }), - be_str_weak(create_closure_value), + be_str_weak(pulsating_animation), &be_const_str_solidified, - ( &(const binstruction[ 6]) { /* code */ - 0xB80A0000, // 0000 GETNGBL R2 K0 - 0x8C080501, // 0001 GETMET R2 R2 K1 - 0x5C100000, // 0002 MOVE R4 R0 - 0x7C080400, // 0003 CALL R2 2 - 0x900A0401, // 0004 SETMBR R2 K2 R1 - 0x80040400, // 0005 RET 1 R2 + ( &(const binstruction[ 8]) { /* code */ + 0xB8060000, // 0000 GETNGBL R1 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x5C0C0000, // 0002 MOVE R3 R0 + 0x7C040400, // 0003 CALL R1 2 + 0x90060503, // 0004 SETMBR R1 K2 K3 + 0x540A03E7, // 0005 LDINT R2 1000 + 0x90060802, // 0006 SETMBR R1 K4 R2 + 0x80040200, // 0007 RET 1 R1 }) ) ); @@ -15479,195 +15483,39 @@ be_local_closure(solid, /* name */ ); /*******************************************************************/ -// compact class 'CrenelPositionAnimation' ktab size: 19, total: 24 (saved 40 bytes) -static const bvalue be_ktab_class_CrenelPositionAnimation[19] = { - /* K0 */ be_nested_str_weak(back_color), - /* K1 */ be_nested_str_weak(pos), - /* K2 */ be_nested_str_weak(pulse_size), - /* K3 */ be_nested_str_weak(low_size), - /* K4 */ be_nested_str_weak(nb_pulse), - /* K5 */ be_nested_str_weak(color), - /* K6 */ be_const_int(-16777216), - /* K7 */ be_nested_str_weak(fill_pixels), - /* K8 */ be_nested_str_weak(pixels), - /* K9 */ be_const_int(0), - /* K10 */ be_const_int(1), - /* K11 */ be_nested_str_weak(set_pixel_color), - /* K12 */ be_nested_str_weak(get_param), - /* K13 */ be_nested_str_weak(animation), - /* K14 */ be_nested_str_weak(is_value_provider), - /* K15 */ be_nested_str_weak(0x_X2508x), - /* K16 */ be_nested_str_weak(CrenelPositionAnimation_X28color_X3D_X25s_X2C_X20pos_X3D_X25s_X2C_X20pulse_size_X3D_X25s_X2C_X20low_size_X3D_X25s_X2C_X20nb_pulse_X3D_X25s_X2C_X20priority_X3D_X25s_X2C_X20running_X3D_X25s_X29), - /* K17 */ be_nested_str_weak(priority), - /* K18 */ be_nested_str_weak(is_running), -}; - - -extern const bclass be_class_CrenelPositionAnimation; /******************************************************************** -** Solidified function: render +** Solidified function: create_closure_value ********************************************************************/ -be_local_closure(class_CrenelPositionAnimation_render, /* name */ +be_local_closure(create_closure_value, /* name */ be_nested_proto( - 16, /* nstack */ - 4, /* argc */ - 10, /* varg */ + 5, /* nstack */ + 2, /* argc */ + 0, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - &be_ktab_class_CrenelPositionAnimation, /* shared constants */ - be_str_weak(render), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str_weak(animation), + /* K1 */ be_nested_str_weak(closure_value), + /* K2 */ be_nested_str_weak(closure), + }), + be_str_weak(create_closure_value), &be_const_str_solidified, - ( &(const binstruction[64]) { /* code */ - 0x88100100, // 0000 GETMBR R4 R0 K0 - 0x88140101, // 0001 GETMBR R5 R0 K1 - 0x88180102, // 0002 GETMBR R6 R0 K2 - 0x881C0103, // 0003 GETMBR R7 R0 K3 - 0x88200104, // 0004 GETMBR R8 R0 K4 - 0x88240105, // 0005 GETMBR R9 R0 K5 - 0x60280009, // 0006 GETGBL R10 G9 - 0x002C0C07, // 0007 ADD R11 R6 R7 - 0x7C280200, // 0008 CALL R10 1 - 0x202C0906, // 0009 NE R11 R4 K6 - 0x782E0003, // 000A JMPF R11 #000F - 0x8C2C0307, // 000B GETMET R11 R1 K7 - 0x88340308, // 000C GETMBR R13 R1 K8 - 0x5C380800, // 000D MOVE R14 R4 - 0x7C2C0600, // 000E CALL R11 3 - 0x182C1509, // 000F LE R11 R10 K9 - 0x782E0000, // 0010 JMPF R11 #0012 - 0x5828000A, // 0011 LDCONST R10 K10 - 0x1C2C1109, // 0012 EQ R11 R8 K9 - 0x782E0001, // 0013 JMPF R11 #0016 - 0x502C0200, // 0014 LDBOOL R11 1 0 - 0x80041600, // 0015 RET 1 R11 - 0x142C1109, // 0016 LT R11 R8 K9 - 0x782E0006, // 0017 JMPF R11 #001F - 0x002C0A06, // 0018 ADD R11 R5 R6 - 0x042C170A, // 0019 SUB R11 R11 K10 - 0x102C160A, // 001A MOD R11 R11 R10 - 0x042C1606, // 001B SUB R11 R11 R6 - 0x002C170A, // 001C ADD R11 R11 K10 - 0x5C141600, // 001D MOVE R5 R11 - 0x70020007, // 001E JMP #0027 - 0x442C1400, // 001F NEG R11 R10 - 0x142C0A0B, // 0020 LT R11 R5 R11 - 0x782E0004, // 0021 JMPF R11 #0027 - 0x202C1109, // 0022 NE R11 R8 K9 - 0x782E0002, // 0023 JMPF R11 #0027 - 0x00140A0A, // 0024 ADD R5 R5 R10 - 0x0420110A, // 0025 SUB R8 R8 K10 - 0x7001FFF7, // 0026 JMP #001F - 0x142C0A03, // 0027 LT R11 R5 R3 - 0x782E0014, // 0028 JMPF R11 #003E - 0x202C1109, // 0029 NE R11 R8 K9 - 0x782E0012, // 002A JMPF R11 #003E - 0x582C0009, // 002B LDCONST R11 K9 - 0x14300B09, // 002C LT R12 R5 K9 - 0x78320001, // 002D JMPF R12 #0030 - 0x44300A00, // 002E NEG R12 R5 - 0x5C2C1800, // 002F MOVE R11 R12 - 0x14301606, // 0030 LT R12 R11 R6 - 0x78320008, // 0031 JMPF R12 #003B - 0x00300A0B, // 0032 ADD R12 R5 R11 - 0x14301803, // 0033 LT R12 R12 R3 - 0x78320005, // 0034 JMPF R12 #003B - 0x8C30030B, // 0035 GETMET R12 R1 K11 - 0x00380A0B, // 0036 ADD R14 R5 R11 - 0x5C3C1200, // 0037 MOVE R15 R9 - 0x7C300600, // 0038 CALL R12 3 - 0x002C170A, // 0039 ADD R11 R11 K10 - 0x7001FFF4, // 003A JMP #0030 - 0x00140A0A, // 003B ADD R5 R5 R10 - 0x0420110A, // 003C SUB R8 R8 K10 - 0x7001FFE8, // 003D JMP #0027 - 0x502C0200, // 003E LDBOOL R11 1 0 - 0x80041600, // 003F RET 1 R11 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: tostring -********************************************************************/ -be_local_closure(class_CrenelPositionAnimation_tostring, /* name */ - be_nested_proto( - 12, /* nstack */ - 1, /* argc */ - 10, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - &be_ktab_class_CrenelPositionAnimation, /* shared constants */ - be_str_weak(tostring), - &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x4C040000, // 0000 LDNIL R1 - 0x8C08010C, // 0001 GETMET R2 R0 K12 - 0x58100005, // 0002 LDCONST R4 K5 + ( &(const binstruction[ 6]) { /* code */ + 0xB80A0000, // 0000 GETNGBL R2 K0 + 0x8C080501, // 0001 GETMET R2 R2 K1 + 0x5C100000, // 0002 MOVE R4 R0 0x7C080400, // 0003 CALL R2 2 - 0xB80E1A00, // 0004 GETNGBL R3 K13 - 0x8C0C070E, // 0005 GETMET R3 R3 K14 - 0x5C140400, // 0006 MOVE R5 R2 - 0x7C0C0400, // 0007 CALL R3 2 - 0x780E0004, // 0008 JMPF R3 #000E - 0x600C0008, // 0009 GETGBL R3 G8 - 0x5C100400, // 000A MOVE R4 R2 - 0x7C0C0200, // 000B CALL R3 1 - 0x5C040600, // 000C MOVE R1 R3 - 0x70020004, // 000D JMP #0013 - 0x600C0018, // 000E GETGBL R3 G24 - 0x5810000F, // 000F LDCONST R4 K15 - 0x88140105, // 0010 GETMBR R5 R0 K5 - 0x7C0C0400, // 0011 CALL R3 2 - 0x5C040600, // 0012 MOVE R1 R3 - 0x600C0018, // 0013 GETGBL R3 G24 - 0x58100010, // 0014 LDCONST R4 K16 - 0x5C140200, // 0015 MOVE R5 R1 - 0x88180101, // 0016 GETMBR R6 R0 K1 - 0x881C0102, // 0017 GETMBR R7 R0 K2 - 0x88200103, // 0018 GETMBR R8 R0 K3 - 0x88240104, // 0019 GETMBR R9 R0 K4 - 0x88280111, // 001A GETMBR R10 R0 K17 - 0x882C0112, // 001B GETMBR R11 R0 K18 - 0x7C0C1000, // 001C CALL R3 8 - 0x80040600, // 001D RET 1 R3 + 0x900A0401, // 0004 SETMBR R2 K2 R1 + 0x80040400, // 0005 RET 1 R2 }) ) ); /*******************************************************************/ - -/******************************************************************** -** Solidified class: CrenelPositionAnimation -********************************************************************/ -extern const bclass be_class_Animation; -be_local_class(CrenelPositionAnimation, - 0, - &be_class_Animation, - be_nested_map(3, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(PARAMS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { - be_const_map( * be_nested_map(5, - ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(nb_pulse, -1), be_const_bytes_instance(0400FF) }, - { be_const_key_weak(low_size, 4), be_const_bytes_instance(0500000003) }, - { be_const_key_weak(pos, 1), be_const_bytes_instance(040000) }, - { be_const_key_weak(pulse_size, -1), be_const_bytes_instance(0500000001) }, - { be_const_key_weak(back_color, -1), be_const_bytes_instance(0402000000FF) }, - })) ) } )) }, - { be_const_key_weak(render, 2), be_const_closure(class_CrenelPositionAnimation_render_closure) }, - { be_const_key_weak(tostring, -1), be_const_closure(class_CrenelPositionAnimation_tostring_closure) }, - })), - be_str_weak(CrenelPositionAnimation) -); // compact class 'TwinkleAnimation' ktab size: 40, total: 64 (saved 192 bytes) static const bvalue be_ktab_class_TwinkleAnimation[40] = { /* K0 */ be_nested_str_weak(get_param), @@ -17895,44 +17743,196 @@ be_local_closure(twinkle_gentle, /* name */ ); /*******************************************************************/ +// compact class 'CrenelPositionAnimation' ktab size: 19, total: 24 (saved 40 bytes) +static const bvalue be_ktab_class_CrenelPositionAnimation[19] = { + /* K0 */ be_nested_str_weak(back_color), + /* K1 */ be_nested_str_weak(pos), + /* K2 */ be_nested_str_weak(pulse_size), + /* K3 */ be_nested_str_weak(low_size), + /* K4 */ be_nested_str_weak(nb_pulse), + /* K5 */ be_nested_str_weak(color), + /* K6 */ be_const_int(-16777216), + /* K7 */ be_nested_str_weak(fill_pixels), + /* K8 */ be_nested_str_weak(pixels), + /* K9 */ be_const_int(0), + /* K10 */ be_const_int(1), + /* K11 */ be_nested_str_weak(set_pixel_color), + /* K12 */ be_nested_str_weak(get_param), + /* K13 */ be_nested_str_weak(animation), + /* K14 */ be_nested_str_weak(is_value_provider), + /* K15 */ be_nested_str_weak(0x_X2508x), + /* K16 */ be_nested_str_weak(CrenelPositionAnimation_X28color_X3D_X25s_X2C_X20pos_X3D_X25s_X2C_X20pulse_size_X3D_X25s_X2C_X20low_size_X3D_X25s_X2C_X20nb_pulse_X3D_X25s_X2C_X20priority_X3D_X25s_X2C_X20running_X3D_X25s_X29), + /* K17 */ be_nested_str_weak(priority), + /* K18 */ be_nested_str_weak(is_running), +}; + + +extern const bclass be_class_CrenelPositionAnimation; /******************************************************************** -** Solidified function: pulsating_animation +** Solidified function: render ********************************************************************/ -be_local_closure(pulsating_animation, /* name */ +be_local_closure(class_CrenelPositionAnimation_render, /* name */ be_nested_proto( - 4, /* nstack */ - 1, /* argc */ - 0, /* varg */ + 16, /* nstack */ + 4, /* argc */ + 10, /* varg */ 0, /* has upvals */ NULL, /* no upvals */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_nested_str_weak(animation), - /* K1 */ be_nested_str_weak(breathe_animation), - /* K2 */ be_nested_str_weak(curve_factor), - /* K3 */ be_const_int(1), - /* K4 */ be_nested_str_weak(period), - }), - be_str_weak(pulsating_animation), + &be_ktab_class_CrenelPositionAnimation, /* shared constants */ + be_str_weak(render), &be_const_str_solidified, - ( &(const binstruction[ 8]) { /* code */ - 0xB8060000, // 0000 GETNGBL R1 K0 - 0x8C040301, // 0001 GETMET R1 R1 K1 - 0x5C0C0000, // 0002 MOVE R3 R0 - 0x7C040400, // 0003 CALL R1 2 - 0x90060503, // 0004 SETMBR R1 K2 K3 - 0x540A03E7, // 0005 LDINT R2 1000 - 0x90060802, // 0006 SETMBR R1 K4 R2 - 0x80040200, // 0007 RET 1 R1 + ( &(const binstruction[64]) { /* code */ + 0x88100100, // 0000 GETMBR R4 R0 K0 + 0x88140101, // 0001 GETMBR R5 R0 K1 + 0x88180102, // 0002 GETMBR R6 R0 K2 + 0x881C0103, // 0003 GETMBR R7 R0 K3 + 0x88200104, // 0004 GETMBR R8 R0 K4 + 0x88240105, // 0005 GETMBR R9 R0 K5 + 0x60280009, // 0006 GETGBL R10 G9 + 0x002C0C07, // 0007 ADD R11 R6 R7 + 0x7C280200, // 0008 CALL R10 1 + 0x202C0906, // 0009 NE R11 R4 K6 + 0x782E0003, // 000A JMPF R11 #000F + 0x8C2C0307, // 000B GETMET R11 R1 K7 + 0x88340308, // 000C GETMBR R13 R1 K8 + 0x5C380800, // 000D MOVE R14 R4 + 0x7C2C0600, // 000E CALL R11 3 + 0x182C1509, // 000F LE R11 R10 K9 + 0x782E0000, // 0010 JMPF R11 #0012 + 0x5828000A, // 0011 LDCONST R10 K10 + 0x1C2C1109, // 0012 EQ R11 R8 K9 + 0x782E0001, // 0013 JMPF R11 #0016 + 0x502C0200, // 0014 LDBOOL R11 1 0 + 0x80041600, // 0015 RET 1 R11 + 0x142C1109, // 0016 LT R11 R8 K9 + 0x782E0006, // 0017 JMPF R11 #001F + 0x002C0A06, // 0018 ADD R11 R5 R6 + 0x042C170A, // 0019 SUB R11 R11 K10 + 0x102C160A, // 001A MOD R11 R11 R10 + 0x042C1606, // 001B SUB R11 R11 R6 + 0x002C170A, // 001C ADD R11 R11 K10 + 0x5C141600, // 001D MOVE R5 R11 + 0x70020007, // 001E JMP #0027 + 0x442C1400, // 001F NEG R11 R10 + 0x142C0A0B, // 0020 LT R11 R5 R11 + 0x782E0004, // 0021 JMPF R11 #0027 + 0x202C1109, // 0022 NE R11 R8 K9 + 0x782E0002, // 0023 JMPF R11 #0027 + 0x00140A0A, // 0024 ADD R5 R5 R10 + 0x0420110A, // 0025 SUB R8 R8 K10 + 0x7001FFF7, // 0026 JMP #001F + 0x142C0A03, // 0027 LT R11 R5 R3 + 0x782E0014, // 0028 JMPF R11 #003E + 0x202C1109, // 0029 NE R11 R8 K9 + 0x782E0012, // 002A JMPF R11 #003E + 0x582C0009, // 002B LDCONST R11 K9 + 0x14300B09, // 002C LT R12 R5 K9 + 0x78320001, // 002D JMPF R12 #0030 + 0x44300A00, // 002E NEG R12 R5 + 0x5C2C1800, // 002F MOVE R11 R12 + 0x14301606, // 0030 LT R12 R11 R6 + 0x78320008, // 0031 JMPF R12 #003B + 0x00300A0B, // 0032 ADD R12 R5 R11 + 0x14301803, // 0033 LT R12 R12 R3 + 0x78320005, // 0034 JMPF R12 #003B + 0x8C30030B, // 0035 GETMET R12 R1 K11 + 0x00380A0B, // 0036 ADD R14 R5 R11 + 0x5C3C1200, // 0037 MOVE R15 R9 + 0x7C300600, // 0038 CALL R12 3 + 0x002C170A, // 0039 ADD R11 R11 K10 + 0x7001FFF4, // 003A JMP #0030 + 0x00140A0A, // 003B ADD R5 R5 R10 + 0x0420110A, // 003C SUB R8 R8 K10 + 0x7001FFE8, // 003D JMP #0027 + 0x502C0200, // 003E LDBOOL R11 1 0 + 0x80041600, // 003F RET 1 R11 }) ) ); /*******************************************************************/ +/******************************************************************** +** Solidified function: tostring +********************************************************************/ +be_local_closure(class_CrenelPositionAnimation_tostring, /* name */ + be_nested_proto( + 12, /* nstack */ + 1, /* argc */ + 10, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + &be_ktab_class_CrenelPositionAnimation, /* shared constants */ + be_str_weak(tostring), + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0x4C040000, // 0000 LDNIL R1 + 0x8C08010C, // 0001 GETMET R2 R0 K12 + 0x58100005, // 0002 LDCONST R4 K5 + 0x7C080400, // 0003 CALL R2 2 + 0xB80E1A00, // 0004 GETNGBL R3 K13 + 0x8C0C070E, // 0005 GETMET R3 R3 K14 + 0x5C140400, // 0006 MOVE R5 R2 + 0x7C0C0400, // 0007 CALL R3 2 + 0x780E0004, // 0008 JMPF R3 #000E + 0x600C0008, // 0009 GETGBL R3 G8 + 0x5C100400, // 000A MOVE R4 R2 + 0x7C0C0200, // 000B CALL R3 1 + 0x5C040600, // 000C MOVE R1 R3 + 0x70020004, // 000D JMP #0013 + 0x600C0018, // 000E GETGBL R3 G24 + 0x5810000F, // 000F LDCONST R4 K15 + 0x88140105, // 0010 GETMBR R5 R0 K5 + 0x7C0C0400, // 0011 CALL R3 2 + 0x5C040600, // 0012 MOVE R1 R3 + 0x600C0018, // 0013 GETGBL R3 G24 + 0x58100010, // 0014 LDCONST R4 K16 + 0x5C140200, // 0015 MOVE R5 R1 + 0x88180101, // 0016 GETMBR R6 R0 K1 + 0x881C0102, // 0017 GETMBR R7 R0 K2 + 0x88200103, // 0018 GETMBR R8 R0 K3 + 0x88240104, // 0019 GETMBR R9 R0 K4 + 0x88280111, // 001A GETMBR R10 R0 K17 + 0x882C0112, // 001B GETMBR R11 R0 K18 + 0x7C0C1000, // 001C CALL R3 8 + 0x80040600, // 001D RET 1 R3 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified class: CrenelPositionAnimation +********************************************************************/ +extern const bclass be_class_Animation; +be_local_class(CrenelPositionAnimation, + 0, + &be_class_Animation, + be_nested_map(3, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(PARAMS, -1), be_const_simple_instance(be_nested_simple_instance(&be_class_map, { + be_const_map( * be_nested_map(5, + ( (struct bmapnode*) &(const bmapnode[]) { + { be_const_key_weak(nb_pulse, -1), be_const_bytes_instance(0400FF) }, + { be_const_key_weak(low_size, 4), be_const_bytes_instance(0500000003) }, + { be_const_key_weak(pos, 1), be_const_bytes_instance(040000) }, + { be_const_key_weak(pulse_size, -1), be_const_bytes_instance(0500000001) }, + { be_const_key_weak(back_color, -1), be_const_bytes_instance(0402000000FF) }, + })) ) } )) }, + { be_const_key_weak(render, 2), be_const_closure(class_CrenelPositionAnimation_render_closure) }, + { be_const_key_weak(tostring, -1), be_const_closure(class_CrenelPositionAnimation_tostring_closure) }, + })), + be_str_weak(CrenelPositionAnimation) +); + /******************************************************************** ** Solidified function: noise_fractal ********************************************************************/ @@ -18969,7 +18969,7 @@ be_local_module(animation, "animation", be_nested_map(98, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key_weak(noise_single_color, 33), be_const_closure(noise_single_color_closure) }, + { be_const_key_weak(noise_single_color, 35), be_const_closure(noise_single_color_closure) }, { be_const_key_weak(pulsating_animation, -1), be_const_closure(pulsating_animation_closure) }, { be_const_key_weak(elastic, 16), be_const_closure(elastic_closure) }, { be_const_key_weak(TRIANGLE, -1), be_const_int(2) }, @@ -18986,12 +18986,12 @@ be_local_module(animation, { be_const_key_weak(square, 47), be_const_closure(square_closure) }, { be_const_key_weak(wave_single_sine, -1), be_const_closure(wave_single_sine_closure) }, { be_const_key_weak(_math, 55), be_const_class(be_class_AnimationMath) }, - { be_const_key_weak(SAWTOOTH, 31), be_const_int(1) }, + { be_const_key_weak(SAWTOOTH, 32), be_const_int(1) }, { be_const_key_weak(register_event_handler, -1), be_const_closure(register_event_handler_closure) }, { be_const_key_weak(init, -1), be_const_closure(animation_init_closure) }, - { be_const_key_weak(gradient_two_color_linear, 35), be_const_closure(gradient_two_color_linear_closure) }, + { be_const_key_weak(gradient_two_color_linear, 38), be_const_closure(gradient_two_color_linear_closure) }, { be_const_key_weak(breathe_animation, 97), be_const_class(be_class_BreatheAnimation) }, - { be_const_key_weak(gradient_rainbow_radial, 38), be_const_closure(gradient_rainbow_radial_closure) }, + { be_const_key_weak(gradient_rainbow_radial, 79), be_const_closure(gradient_rainbow_radial_closure) }, { be_const_key_weak(EASE_IN, -1), be_const_int(6) }, { be_const_key_weak(LINEAR, -1), be_const_int(1) }, { be_const_key_weak(color_provider, -1), be_const_class(be_class_ColorProvider) }, @@ -19000,14 +19000,14 @@ be_local_module(animation, { be_const_key_weak(COSINE, -1), be_const_int(4) }, { be_const_key_weak(static_color, 60), be_const_class(be_class_StaticColorProvider) }, { be_const_key_weak(noise_fractal, 72), be_const_closure(noise_fractal_closure) }, + { be_const_key_weak(PALETTE_RAINBOW, -1), be_const_bytes_instance(FFFC0000FFFF8000FFFFFF00FF00FF00FF00FFFFFF0080FFFF8000FF) }, { be_const_key_weak(SQUARE, -1), be_const_int(3) }, { be_const_key_weak(twinkle_gentle, -1), be_const_closure(twinkle_gentle_closure) }, - { be_const_key_weak(parameterized_object, -1), be_const_class(be_class_ParameterizedObject) }, { be_const_key_weak(twinkle_intense, -1), be_const_closure(twinkle_intense_closure) }, - { be_const_key_weak(twinkle_animation, -1), be_const_class(be_class_TwinkleAnimation) }, + { be_const_key_weak(parameterized_object, -1), be_const_class(be_class_ParameterizedObject) }, { be_const_key_weak(cosine_osc, -1), be_const_closure(cosine_osc_closure) }, { be_const_key_weak(version_string, -1), be_const_closure(animation_version_string_closure) }, - { be_const_key_weak(linear, -1), be_const_closure(linear_closure) }, + { be_const_key_weak(twinkle_animation, -1), be_const_class(be_class_TwinkleAnimation) }, { be_const_key_weak(sequence_manager, -1), be_const_class(be_class_SequenceManager) }, { be_const_key_weak(init_strip, -1), be_const_closure(animation_init_strip_closure) }, { be_const_key_weak(list_user_functions, 48), be_const_closure(list_user_functions_closure) }, @@ -19042,17 +19042,17 @@ be_local_module(animation, { be_const_key_weak(rich_palette_animation, 89), be_const_class(be_class_RichPaletteAnimation) }, { be_const_key_weak(animation, -1), be_const_class(be_class_Animation) }, { be_const_key_weak(wave_animation, -1), be_const_class(be_class_WaveAnimation) }, - { be_const_key_weak(VERSION, 83), be_const_int(65536) }, + { be_const_key_weak(VERSION, 31), be_const_int(65536) }, { be_const_key_weak(SINE, 25), be_const_int(5) }, { be_const_key_weak(PALETTE_FIRE, -1), be_const_bytes_instance(FF000000FF800000FFFF0000FFFF8000FFFFFF00) }, { be_const_key_weak(gradient_animation, -1), be_const_class(be_class_GradientAnimation) }, - { be_const_key_weak(wave_rainbow_sine, 32), be_const_closure(wave_rainbow_sine_closure) }, + { be_const_key_weak(wave_rainbow_sine, 33), be_const_closure(wave_rainbow_sine_closure) }, { be_const_key_weak(sawtooth, -1), be_const_closure(sawtooth_closure) }, - { be_const_key_weak(crenel_position_animation, -1), be_const_class(be_class_CrenelPositionAnimation) }, + { be_const_key_weak(linear, -1), be_const_closure(linear_closure) }, { be_const_key_weak(sine_osc, 85), be_const_closure(sine_osc_closure) }, { be_const_key_weak(static_value, -1), be_const_class(be_class_StaticValueProvider) }, { be_const_key_weak(get_user_function, -1), be_const_closure(get_user_function_closure) }, - { be_const_key_weak(PALETTE_RAINBOW, -1), be_const_bytes_instance(FFFC0000FFFF8000FFFFFF00FF00FF00FF00FFFFFF0080FFFF8000FF) }, + { be_const_key_weak(crenel_animation, -1), be_const_class(be_class_CrenelPositionAnimation) }, { be_const_key_weak(fire_animation, 90), be_const_class(be_class_FireAnimation) }, { be_const_key_weak(gradient_rainbow_linear, -1), be_const_closure(gradient_rainbow_linear_closure) }, { be_const_key_weak(comet_animation, 59), be_const_class(be_class_CometAnimation) }, diff --git a/lib/libesp32/berry_animation/src/tests/crenel_position_animation_test.be b/lib/libesp32/berry_animation/src/tests/crenel_position_animation_test.be index aa155cdee..955e9d6d4 100644 --- a/lib/libesp32/berry_animation/src/tests/crenel_position_animation_test.be +++ b/lib/libesp32/berry_animation/src/tests/crenel_position_animation_test.be @@ -31,7 +31,7 @@ def run_tests() var engine = animation.create_engine(strip) # Test 1: Basic construction with new parameterized pattern - var crenel = animation.crenel_position_animation(engine) + var crenel = animation.crenel_animation(engine) test_assert(crenel != nil, "Crenel position animation creation") # Set parameters via virtual member assignment diff --git a/lib/libesp32/berry_animation/src/tests/crenel_position_color_test.be b/lib/libesp32/berry_animation/src/tests/crenel_position_color_test.be index 94e429b4f..412372895 100644 --- a/lib/libesp32/berry_animation/src/tests/crenel_position_color_test.be +++ b/lib/libesp32/berry_animation/src/tests/crenel_position_color_test.be @@ -18,7 +18,7 @@ def test_crenel_with_integer_color() var red_color = 0xFFFF0000 # Red # Create animation with new parameterized pattern - var crenel = animation.crenel_position_animation(engine) + var crenel = animation.crenel_animation(engine) # Set parameters via virtual member assignment crenel.color = red_color @@ -60,7 +60,7 @@ def test_crenel_with_color_provider() color_provider.color = blue_color # Create animation with new parameterized pattern - var crenel = animation.crenel_position_animation(engine) + var crenel = animation.crenel_animation(engine) # Set parameters via virtual member assignment crenel.color = color_provider # ColorProvider @@ -102,7 +102,7 @@ def test_crenel_with_dynamic_color_provider() palette_provider.cycle_period = 2000 # 2 second cycle # Create animation with new parameterized pattern - var crenel = animation.crenel_position_animation(engine) + var crenel = animation.crenel_animation(engine) # Set parameters via virtual member assignment crenel.color = palette_provider # dynamic ColorProvider @@ -150,7 +150,7 @@ def test_crenel_with_generic_value_provider() static_provider.value = 0xFFFF00FF # Magenta # Create animation with new parameterized pattern - var crenel = animation.crenel_position_animation(engine) + var crenel = animation.crenel_animation(engine) # Set parameters via virtual member assignment crenel.color = static_provider # generic ValueProvider @@ -187,7 +187,7 @@ def test_crenel_set_color_methods() var frame = animation.frame_buffer(5) # Create animation with new parameterized pattern - var crenel = animation.crenel_position_animation(engine) + var crenel = animation.crenel_animation(engine) # Set initial parameters crenel.color = 0xFFFF0000 # red @@ -231,7 +231,7 @@ def test_crenel_tostring() var engine = animation.create_engine(strip) # Test with integer color - var crenel_int = animation.crenel_position_animation(engine) + var crenel_int = animation.crenel_animation(engine) crenel_int.color = 0xFFFF0000 crenel_int.back_color = 0xFF000000 crenel_int.pos = 0 @@ -252,7 +252,7 @@ def test_crenel_tostring() var color_provider = animation.static_color(engine) color_provider.color = 0xFF00FF00 - var crenel_provider = animation.crenel_position_animation(engine) + var crenel_provider = animation.crenel_animation(engine) crenel_provider.color = color_provider crenel_provider.back_color = 0xFF000000 crenel_provider.pos = 0 diff --git a/lib/libesp32/berry_animation/tools/tasmota.animation-dsl-1.2.1/syntaxes/animation-dsl.tmLanguage.json b/lib/libesp32/berry_animation/tools/tasmota.animation-dsl-1.2.1/syntaxes/animation-dsl.tmLanguage.json index 36e4d6563..dd6419cd8 100644 --- a/lib/libesp32/berry_animation/tools/tasmota.animation-dsl-1.2.1/syntaxes/animation-dsl.tmLanguage.json +++ b/lib/libesp32/berry_animation/tools/tasmota.animation-dsl-1.2.1/syntaxes/animation-dsl.tmLanguage.json @@ -192,7 +192,7 @@ "patterns": [ { "name": "entity.name.function.animation.animation-dsl", - "match": "\\b(solid|pulsating_animation|beacon_animation|comet_animation|rich_palette_animation|twinkle_animation|breathe_animation|fire_animation|crenel_position_animation)\\b" + "match": "\\b(solid|pulsating_animation|beacon_animation|comet_animation|rich_palette_animation|twinkle_animation|breathe_animation|fire_animation|crenel_animation)\\b" } ] },