ESP32 Native version of Blinky, featureful controller code for WS2811/WS2812/NeoPixels
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

144 行
3.7KB

  1. static const char *TAG = "presets";
  2. #include <esp_log.h>
  3. #include <cJSON.h>
  4. #include "gamma.hpp"
  5. #include "presets.hpp"
  6. #include "utils.hpp"
  7. /* Sadly, need to define these here */
  8. extern Pattern* json_gradient_pattern(cJSON *pattern, const Presets::ColorMap &colors);
  9. extern Pattern* json_random_pattern(cJSON *pattern, const Presets::ColorMap &colors);
  10. extern Pattern* json_sparkle_pattern(cJSON *pattern, const Presets::ColorMap &colors);
  11. namespace Presets {
  12. /* Factory */
  13. typedef Pattern* (*PatternGenerator)(cJSON*, const Presets::ColorMap&);
  14. static const std::map <std::string, PatternGenerator> generators {
  15. {"gradient", json_gradient_pattern},
  16. {"random", json_random_pattern},
  17. {"sparkle", json_sparkle_pattern},
  18. };
  19. /* Preset Map */
  20. std::map <std::string, const Pattern*> map;
  21. const Pattern* find(const std::string &name) {
  22. auto e = map.find(name);
  23. return e == map.end() ? NULL : e->second;
  24. }
  25. std::map<std::string, const Pattern*>::const_iterator map_begin() {
  26. return map.begin();
  27. }
  28. std::map<std::string, const Pattern*>::const_iterator map_end() {
  29. return map.end();
  30. }
  31. static inline cJSON* load_json(const char *path) {
  32. return cJSON_Parse(read_file(path).c_str());
  33. }
  34. /* Preset Loader */
  35. static Color json_raw_color(cJSON *json) {
  36. if (json->type != cJSON_Array) {
  37. ESP_LOGE(TAG, "Not an array: %s", json->string);
  38. return {0, 0, 0};
  39. }
  40. int count = cJSON_GetArraySize(json);
  41. if (count != 3) {
  42. ESP_LOGE(TAG, "Wrong size for %s: %d", json->string, count);
  43. return {0, 0, 0};
  44. }
  45. // TODO: Number checks for array elements?
  46. return Color{
  47. (uint8_t)cJSON_GetArrayItem(json, 0)->valueint,
  48. (uint8_t)cJSON_GetArrayItem(json, 1)->valueint,
  49. (uint8_t)cJSON_GetArrayItem(json, 2)->valueint
  50. };
  51. }
  52. Color json_color(cJSON *json, const ColorMap &colors) {
  53. if (json->type == cJSON_Array) return json_raw_color(json);
  54. if (json->type != cJSON_String) {
  55. ESP_LOGE(TAG, "Not a string: %s", json->string);
  56. return {0, 0, 0};
  57. }
  58. auto iter = colors.find(json->valuestring);
  59. if (iter == colors.end()) {
  60. ESP_LOGE(TAG, "Not a color: %s", json->valuestring);
  61. return {0, 0, 0};
  62. }
  63. return iter->second;
  64. }
  65. static Pattern* json_pattern(cJSON *json, const ColorMap &colors) {
  66. if (json->type != cJSON_Object) {
  67. ESP_LOGE(TAG, "Not an object: %s", json->string);
  68. return NULL;
  69. }
  70. cJSON *pattern = json->child;
  71. std::string type(pattern->string);
  72. auto iter = generators.find(type);
  73. if (iter == generators.end()) {
  74. ESP_LOGE(TAG, "Unknown pattern type: %s", type.c_str());
  75. return NULL;
  76. }
  77. return iter->second(pattern, colors);
  78. }
  79. void reload() {
  80. if (generators.empty()) {
  81. ESP_LOGE(TAG, "No pattern generators defined!");
  82. return;
  83. }
  84. ColorMap colors;
  85. cJSON *jcolors = load_json("/spiffs/colors.json");
  86. if (!jcolors) {
  87. ESP_LOGW(TAG, "No preset colors!");
  88. } else {
  89. cJSON *jcolor;
  90. cJSON_ArrayForEach(jcolor, jcolors) {
  91. Color color = json_color(jcolor, colors);
  92. colors[jcolor->string] = Gamma::wrong_single(color);
  93. }
  94. cJSON_Delete(jcolors);
  95. }
  96. for (const auto &k_v : map) delete k_v.second;
  97. map.clear();
  98. cJSON *jpresets = load_json("/spiffs/presets.json");
  99. if (!jpresets) {
  100. ESP_LOGE(TAG, "No preset patterns!");
  101. } else {
  102. cJSON *jpreset;
  103. cJSON_ArrayForEach(jpreset, jpresets) {
  104. Pattern *pattern = json_pattern(jpreset, colors);
  105. if (pattern) {
  106. ESP_LOGI(TAG, "Creating preset: %s", jpreset->string);
  107. map[jpreset->string] = pattern;
  108. }
  109. }
  110. cJSON_Delete(jpresets);
  111. }
  112. }
  113. } // Presets