FastLED 3.10.9
Loading...
Searching...
No Matches
singleton.cpp.hpp
Go to the documentation of this file.
1#include "fl/stl/singleton.h"
2#include "fl/stl/cstring.h"
3#include "platforms/is_platform.h" // IWYU pragma: keep
4#ifdef FL_IS_ESP8266
5#include "fastled_progmem.h"
6#endif
7
8namespace fl {
9namespace detail {
10
11namespace {
13 const char* key;
14 void* value;
15 };
16 static constexpr int REGISTRY_MAX = 128;
17 // FL_LINT_ALLOW_GLOBAL(singleton registry backing — cannot itself live inside a Singleton<T>, which would be self-referential)
19 // FL_LINT_ALLOW_GLOBAL(singleton registry backing — see above)
20 static int registry_count = 0;
21
22 // Keys are FL_PRETTY_FUNCTION strings. The ESP8266 core's linker script
23 // places __PRETTY_FUNCTION__ in flash (.irom0.text), which only allows
24 // aligned 32-bit loads, so a byte-wise strcmp() faults with
25 // LoadStoreError. pgm_read_byte() is safe for both RAM and flash there.
26 bool keys_equal(const char* a, const char* b) FL_NO_EXCEPT {
27 if (a == b) {
28 return true;
29 }
30#ifdef FL_IS_ESP8266
31 for (;; ++a, ++b) {
32 const char ca = static_cast<char>(FL_PGM_READ_BYTE_NEAR(a));
33 const char cb = static_cast<char>(FL_PGM_READ_BYTE_NEAR(b));
34 if (ca != cb) {
35 return false;
36 }
37 if (ca == '\0') {
38 return true;
39 }
40 }
41#else
42 return fl::strcmp(a, b) == 0;
43#endif
44 }
45} // anonymous namespace
46
47void* singleton_registry_get(const char* key) FL_NO_EXCEPT {
48 for (int i = 0; i < registry_count; i++) {
49 if (keys_equal(registry[i].key, key)) {
50 return registry[i].value;
51 }
52 }
53 return nullptr;
54}
55
56void singleton_registry_set(const char* key, void* value) FL_NO_EXCEPT {
57 // Check if already registered (update)
58 for (int i = 0; i < registry_count; i++) {
59 if (keys_equal(registry[i].key, key)) {
60 registry[i].value = value;
61 return;
62 }
63 }
64 // Add new entry
65 if (registry_count < REGISTRY_MAX) {
66 registry[registry_count++] = {key, value};
67 }
68}
69
70} // namespace detail
71} // namespace fl
#define FL_PGM_READ_BYTE_NEAR(x)
Read a byte (8-bit) from PROGMEM memory.
Wrapper definitions to allow seamless use of PROGMEM in environments that have it.
bool keys_equal(const char *a, const char *b) FL_NO_EXCEPT
static RegistryEntry registry[REGISTRY_MAX]
void * singleton_registry_get(const char *key) FL_NO_EXCEPT
void singleton_registry_set(const char *key, void *value) FL_NO_EXCEPT
Compile-time linker keep-alive hook for a single fl::Bus.
Definition bus_info.h:57
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
constexpr int type_rank< T >::value
FASTLED_FORCE_INLINE int strcmp(const char *s1, const char *s2) FL_NO_EXCEPT
Definition cstring.h:60
Base definition for an LED controller.