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 {
114 enum class Store : uint16_t
120 static constexpr uint32_t storeId = modes::store::derivateStoreId<modes::store::hash(
"GroupTyStoreId"), AllModesTy>;
135 assert(modeId < nbModes);
136 if constexpr (ctx.hasCustomRamp)
138 ctx.state.customRampMemory[modeId] = ctx.get_active_custom_ramp();
139 ctx.state.customIndexMemory[modeId] = ctx.get_active_custom_index();
146 assert(modeId < nbModes);
147 if constexpr (ctx.hasCustomRamp)
149 ctx.set_active_custom_ramp(ctx.state.customRampMemory[modeId]);
150 ctx.set_active_custom_index(ctx.state.customIndexMemory[modeId]);
156 template<
typename Mode>
static auto* LMBD_INLINE getStateOf(
auto& manager)
158 using StateTy =
typename Mode::StateTy;
159 using OptionalTy = std::optional<StateTy>;
161 StateTy* substate =
nullptr;
162 details::unroll<nbModes>([&](
auto Idx) LMBD_INLINE {
163 using ModeHere = ModeAt<Idx>;
164 constexpr bool isHere = std::is_same_v<ModeHere, Mode>;
166 if constexpr (isHere)
168 auto* state = manager.template getStateGroupOf<SelfTy>();
171 OptionalTy& opt = std::get<OptionalTy>(state->modeStates);
172 if (!opt.has_value())
177 StateTy& stateHere = *opt;
178 substate = &stateHere;
183 assert(substate !=
nullptr &&
"this should not have happened!");
192 static constexpr bool isGroupManager =
false;
194 static constexpr bool isModeManager =
true;
197 static void next_mode(
auto& ctx)
199 uint8_t modeIdBefore = ctx.get_active_mode(nbModes);
200 ctx.set_active_mode(modeIdBefore + 1, nbModes);
204 static void enter_mode(
auto& ctx)
210 uint8_t modeIdAfter = ctx.get_active_mode(nbModes);
211 ctx.state.load_ramps(ctx, modeIdAfter);
214 dispatch_mode(ctx, [](
auto mode) {
215 mode.on_enter_mode();
220 static void quit_mode(
auto& ctx)
223 uint8_t modeIdBefore = ctx.get_active_mode(nbModes);
225 ctx.state.save_ramps(ctx, modeIdBefore);
228 dispatch_mode(ctx, [](
auto mode) {
238 static void loop(
auto& ctx)
240 dispatch_mode(ctx, [](
auto mode) {
246 static void sunset_update(
auto& ctx,
float progress)
248 dispatch_mode(ctx, [&](
auto mode) {
249 mode.sunset_update(progress);
256 dispatch_mode(ctx, [&](
auto mode) {
257 mode.brightness_update(brightness);
262 static void custom_ramp_update(
auto& ctx, uint8_t rampValue)
264 dispatch_mode(ctx, [&](
auto mode) {
265 mode.custom_ramp_update(rampValue);
270 static bool custom_click(
auto& ctx, uint8_t nbClick)
273 dispatch_mode(ctx, [&](
auto mode) {
274 retVal = mode.custom_click(nbClick);
280 static bool custom_hold(
auto& ctx, uint8_t nbClickAndHold,
bool isEndOfHoldEvent, uint32_t holdDuration)
283 dispatch_mode(ctx, [&](
auto mode) {
284 retVal = mode.custom_hold(nbClickAndHold, isEndOfHoldEvent, holdDuration);
292 foreach_mode<true>(ctx, [](
auto mode) {
293 mode.power_on_sequence();
300 foreach_mode<true>(ctx, [](
auto mode) {
301 mode.power_off_sequence();
308 foreach_mode<true>(ctx, [](
auto mode) {
309 mode.write_parameters();
316 foreach_mode<true>(ctx, [](
auto mode) {
317 mode.read_parameters();
324 dispatch_mode(ctx, [](
auto mode) {
335template<
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:335
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:56
void user_thread()
Called at each tick of the secondary thread.
Definition: default_behavior.hpp:159
void read_parameters()
Called when system wants to read parameters from filesystem.
Definition: default_behavior.hpp:93
void power_on_sequence()
Called when the system powers on (must be non blocking function!)
Definition: default_behavior.hpp:31
void write_parameters()
Called when system wants to write parameters to filesystem.
Definition: default_behavior.hpp:87
void power_off_sequence()
Called when the system powers off (must be non blocking function!)
Definition: default_behavior.hpp:42
void loop()
Called at each tick of the main loop.
Definition: default_behavior.hpp:139
uint16_t brightness_t
Define the type of the brightness parameters.
Definition: constants.h:147
Definition: group_type.hpp:127
std::array< uint8_t, nbModes > customIndexMemory
Store the active index for each mode.
Definition: group_type.hpp:130
std::array< uint8_t, nbModes > customRampMemory
Store the ramp value for each mode.
Definition: group_type.hpp:129
AllStatesTy modeStates
Store the current group state.
Definition: group_type.hpp:128
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:133
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:144