25template<
typename AllModes>
static constexpr bool verifyGroup()
27 constexpr bool inheritsFromBasicMode = details::allOf<AllModes>::inheritsFromBasicMode;
28 static_assert(inheritsFromBasicMode,
"All modes must inherit from modes::BasicMode!");
30 constexpr bool stateDefaultConstructible = details::allOf<AllModes>::stateDefaultConstructible;
31 static_assert(stateDefaultConstructible,
"All states must be default constructible!");
34 acc |= !inheritsFromBasicMode;
35 acc |= !stateDefaultConstructible;
40template<typename AllModes, bool earlyFail = verifyGroup<AllModes>()>
struct GroupTy
43 using SelfTy = GroupTy<AllModes>;
44 using AllModesTy = AllModes;
45 using AllStatesTy = details::StateTyFrom<AllModes>;
46 static constexpr uint8_t nbModes {std::tuple_size_v<AllModesTy>};
49 static_assert(nbModes < 32,
"Maximum of 31 modes has been exceeded.");
51 template<u
int8_t Idx>
using ModeAtRaw = std::tuple_element_t<Idx, AllModesTy>;
52 template<u
int8_t Idx>
using ModeAt = std::conditional_t<!earlyFail, ModeAtRaw<Idx>, BasicMode>;
55 using HasAnyMode = details::anyOf<AllModesTy, earlyFail>;
56 static constexpr bool hasSunsetAnimation = HasAnyMode::hasSunsetAnimation;
57 static constexpr bool hasBrightCallback = HasAnyMode::hasBrightCallback;
58 static constexpr bool hasSystemCallbacks = HasAnyMode::hasSystemCallbacks;
59 static constexpr bool requireUserThread = HasAnyMode::requireUserThread;
60 static constexpr bool hasCustomRamp = HasAnyMode::hasCustomRamp;
61 static constexpr bool hasButtonCustomUI = HasAnyMode::hasButtonCustomUI;
64 static constexpr auto everySunsetCallback = HasAnyMode::everySunsetCallback;
65 static constexpr auto everyBrightCallback = HasAnyMode::everyBrightCallback;
66 static constexpr auto everySystemCallbacks = HasAnyMode::everySystemCallbacks;
67 static constexpr auto everyRequireUserThread = HasAnyMode::everyRequireUserThread;
68 static constexpr auto everyCustomRamp = HasAnyMode::everyCustomRamp;
69 static constexpr auto everyButtonCustomUI = HasAnyMode::everyButtonCustomUI;
73 GroupTy(
const GroupTy&) =
delete;
74 GroupTy& operator=(
const GroupTy&) =
delete;
77 template<
typename CallBack>
static void LMBD_INLINE dispatch_mode(
auto& ctx, CallBack&& cb)
79 uint8_t modeId = ctx.get_active_mode(nbModes);
81 details::unroll<nbModes>([&](
auto Idx) LMBD_INLINE {
90 template<
bool systemCallbacksOnly,
typename CallBack>
static void LMBD_INLINE foreach_mode(
auto& ctx, CallBack&& cb)
92 if constexpr (systemCallbacksOnly)
94 details::unroll<nbModes>([&](
auto Idx) LMBD_INLINE {
95 if constexpr (ModeAt<Idx>::hasSystemCallbacks)
103 details::unroll<nbModes>([&](
auto Idx) LMBD_INLINE {
110 template<
bool systemCallbacksOnly,
typename CallBack>
static void LMBD_INLINE iterate_mode(
auto& ctx, CallBack&& cb)
112 if constexpr (systemCallbacksOnly)
114 details::unroll<nbModes>([&](
auto Idx) LMBD_INLINE {
115 if constexpr (ModeAt<Idx>::hasSystemCallbacks)
123 details::unroll<nbModes>([&](
auto Idx) LMBD_INLINE {
134 enum class Store : uint16_t
140 static constexpr uint32_t storeId = modes::store::derivateStoreId<modes::store::hash(
"GroupTyStoreId"), AllModesTy>;
155 assert(modeId < nbModes);
156 if constexpr (ctx.hasCustomRamp)
158 ctx.state.customRampMemory[modeId] = ctx.get_active_custom_ramp();
159 ctx.state.customIndexMemory[modeId] = ctx.get_active_custom_index();
166 assert(modeId < nbModes);
167 if constexpr (ctx.hasCustomRamp)
169 ctx.set_active_custom_ramp(ctx.state.customRampMemory[modeId]);
170 ctx.set_active_custom_index(ctx.state.customIndexMemory[modeId]);
176 template<
typename Mode>
static auto* LMBD_INLINE getStateOf(
auto& manager)
178 using StateTy =
typename Mode::StateTy;
179 using OptionalTy = std::optional<StateTy>;
181 StateTy* substate =
nullptr;
182 details::unroll<nbModes>([&](
auto Idx) LMBD_INLINE {
183 using ModeHere = ModeAt<Idx>;
184 constexpr bool isHere = std::is_same_v<ModeHere, Mode>;
186 if constexpr (isHere)
188 auto* state = manager.template getStateGroupOf<SelfTy>();
191 OptionalTy& opt = std::get<OptionalTy>(state->modeStates);
192 if (!opt.has_value())
197 StateTy& stateHere = *opt;
198 substate = &stateHere;
203 assert(substate !=
nullptr &&
"this should not have happened!");
212 static constexpr bool isGroupManager =
false;
214 static constexpr bool isModeManager =
true;
217 static void next_mode(
auto& ctx)
219 uint8_t modeIdBefore = ctx.get_active_mode(nbModes);
220 ctx.set_active_mode(modeIdBefore + 1, nbModes);
224 static void enter_mode(
auto& ctx)
230 uint8_t modeIdAfter = ctx.get_active_mode(nbModes);
231 ctx.state.load_ramps(ctx, modeIdAfter);
234 dispatch_mode(ctx, [](
auto mode) {
235 mode.on_enter_mode();
240 static void quit_mode(
auto& ctx)
243 uint8_t modeIdBefore = ctx.get_active_mode(nbModes);
245 ctx.state.save_ramps(ctx, modeIdBefore);
248 dispatch_mode(ctx, [](
auto mode) {
258 static void loop(
auto& ctx)
260 dispatch_mode(ctx, [](
auto mode) {
266 static void sunset_update(
auto& ctx,
float progress)
268 dispatch_mode(ctx, [&](
auto mode) {
269 mode.sunset_update(progress);
276 dispatch_mode(ctx, [&](
auto mode) {
277 mode.brightness_update(brightness);
282 static void custom_ramp_update(
auto& ctx, uint8_t rampValue)
284 dispatch_mode(ctx, [&](
auto mode) {
285 mode.custom_ramp_update(rampValue);
290 static bool custom_click(
auto& ctx, uint8_t nbClick)
293 dispatch_mode(ctx, [&](
auto mode) {
294 retVal = mode.custom_click(nbClick);
300 static bool custom_hold(
auto& ctx, uint8_t nbClickAndHold,
bool isEndOfHoldEvent, uint32_t holdDuration)
303 dispatch_mode(ctx, [&](
auto mode) {
304 retVal = mode.custom_hold(nbClickAndHold, isEndOfHoldEvent, holdDuration);
309 static std::array<uint8_t, nbModes> get_custom_ramp_default_value(
auto& ctx)
311 std::array<uint8_t, nbModes> defaultValues;
312 defaultValues.fill(0);
314 iterate_mode<false>(ctx, [&defaultValues](
auto mode,
const size_t index) {
315 if constexpr (mode.hasCustomRamp)
317 defaultValues[index] = mode.get_custom_ramp_default_value();
320 return defaultValues;
326 foreach_mode<true>(ctx, [](
auto mode) {
327 mode.power_on_sequence();
334 foreach_mode<true>(ctx, [](
auto mode) {
335 mode.power_off_sequence();
342 foreach_mode<true>(ctx, [](
auto mode) {
343 mode.write_parameters();
350 foreach_mode<true>(ctx, [](
auto mode) {
351 mode.read_parameters();
358 dispatch_mode(ctx, [](
auto mode) {
369template<
typename... Modes>
using GroupFor = GroupTy<std::tuple<Modes...>>;
Define assertions helpers.
ContextTy and associated definitions.
modes::ManagerFor and associated definitions
Basic interface types to implement custom user modes.
brightness_t get_saved_brightness()
Return the saved brightness level. This shoudl be the prefered option in all computations.
Definition: brightness_handle.cpp:64
Contains basic interface types to implement custom user modes.
Definition: control_fixed_modes.hpp:12
GroupTy< std::tuple< Modes... > > GroupFor
Group together many different modes::BasicMode.
Definition: group_type.hpp:369
static auto context_as(auto &ctx)
Bind provided context to another modes::BasicMode.
Definition: context_type.hpp:25
void brightness_update(const brightness_t brightness)
Called when the system changes the LED strip brightness.
Definition: default_behavior.hpp:59
void user_thread()
Called at each tick of the secondary thread.
Definition: default_behavior.hpp:206
void read_parameters()
Called when system wants to read parameters from filesystem.
Definition: default_behavior.hpp:96
void power_on_sequence()
Called when the system powers on (must be non blocking function!)
Definition: default_behavior.hpp:34
void write_parameters()
Called when system wants to write parameters to filesystem.
Definition: default_behavior.hpp:90
void power_off_sequence()
Called when the system powers off (must be non blocking function!)
Definition: default_behavior.hpp:45
void loop()
Called at each tick of the main loop.
Definition: default_behavior.hpp:186
uint16_t brightness_t
Define the type of the brightness parameters.
Definition: constants.h:147
Definition: group_type.hpp:147
std::array< uint8_t, nbModes > customIndexMemory
Store the active index for each mode.
Definition: group_type.hpp:150
std::array< uint8_t, nbModes > customRampMemory
Store the ramp value for each mode.
Definition: group_type.hpp:149
AllStatesTy modeStates
Store the current group state.
Definition: group_type.hpp:148
void LMBD_INLINE save_ramps(auto &ctx, uint8_t modeId)
If a mode signaled that it has a ramp, save it.
Definition: group_type.hpp:153
void LMBD_INLINE load_ramps(auto &ctx, uint8_t modeId)
If a mode signaled that it has a ramp, load it.
Definition: group_type.hpp:164