|
- static const char *TAG = "presets";
- #include <esp_log.h>
-
- #include <cJSON.h>
-
- #include "gamma.hpp"
- #include "presets.hpp"
- #include "utils.hpp"
-
-
- /* Sadly, need to define these here */
-
- extern Pattern* json_gradient_pattern(cJSON *pattern, const Presets::ColorMap &colors);
- extern Pattern* json_random_pattern(cJSON *pattern, const Presets::ColorMap &colors);
- extern Pattern* json_sparkle_pattern(cJSON *pattern, const Presets::ColorMap &colors);
-
- namespace Presets {
-
- /* Factory */
-
- typedef Pattern* (*PatternGenerator)(cJSON*, const Presets::ColorMap&);
-
- static const std::map <std::string, PatternGenerator> generators {
- {"gradient", json_gradient_pattern},
- {"random", json_random_pattern},
- {"sparkle", json_sparkle_pattern},
- };
-
-
- /* Preset Map */
-
- std::map <std::string, const Pattern*> map;
-
- const Pattern* find(const std::string &name) {
- auto e = map.find(name);
- return e == map.end() ? NULL : e->second;
- }
-
- std::map<std::string, const Pattern*>::const_iterator map_begin() {
- return map.begin();
- }
-
- std::map<std::string, const Pattern*>::const_iterator map_end() {
- return map.end();
- }
-
- static inline cJSON* load_json(const char *path) {
- return cJSON_Parse(read_file(path).c_str());
- }
-
-
- /* Preset Loader */
-
- static Color json_raw_color(cJSON *json) {
- if (json->type != cJSON_Array) {
- ESP_LOGE(TAG, "Not an array: %s", json->string);
- return {0, 0, 0};
- }
- int count = cJSON_GetArraySize(json);
- if (count != 3) {
- ESP_LOGE(TAG, "Wrong size for %s: %d", json->string, count);
- return {0, 0, 0};
- }
- // TODO: Number checks for array elements?
- return Color{
- (uint8_t)cJSON_GetArrayItem(json, 0)->valueint,
- (uint8_t)cJSON_GetArrayItem(json, 1)->valueint,
- (uint8_t)cJSON_GetArrayItem(json, 2)->valueint
- };
- }
-
- Color json_color(cJSON *json, const ColorMap &colors) {
- if (json->type == cJSON_Array) return json_raw_color(json);
- if (json->type != cJSON_String) {
- ESP_LOGE(TAG, "Not a string: %s", json->string);
- return {0, 0, 0};
- }
- auto iter = colors.find(json->valuestring);
- if (iter == colors.end()) {
- ESP_LOGE(TAG, "Not a color: %s", json->valuestring);
- return {0, 0, 0};
- }
- return iter->second;
- }
-
-
- static Pattern* json_pattern(cJSON *json, const ColorMap &colors) {
- if (json->type != cJSON_Object) {
- ESP_LOGE(TAG, "Not an object: %s", json->string);
- return NULL;
- }
-
- cJSON *pattern = json->child;
- std::string type(pattern->string);
-
- auto iter = generators.find(type);
- if (iter == generators.end()) {
- ESP_LOGE(TAG, "Unknown pattern type: %s", type.c_str());
- return NULL;
- }
-
- return iter->second(pattern, colors);
- }
-
- void reload() {
- if (generators.empty()) {
- ESP_LOGE(TAG, "No pattern generators defined!");
- return;
- }
-
- ColorMap colors;
- cJSON *jcolors = load_json("/spiffs/colors.json");
- if (!jcolors) {
- ESP_LOGW(TAG, "No preset colors!");
- } else {
- cJSON *jcolor;
- cJSON_ArrayForEach(jcolor, jcolors) {
- Color color = json_color(jcolor, colors);
- colors[jcolor->string] = Gamma::wrong_single(color);
- }
- cJSON_Delete(jcolors);
- }
-
- for (const auto &k_v : map) delete k_v.second;
- map.clear();
-
- cJSON *jpresets = load_json("/spiffs/presets.json");
- if (!jpresets) {
- ESP_LOGE(TAG, "No preset patterns!");
- } else {
- cJSON *jpreset;
- cJSON_ArrayForEach(jpreset, jpresets) {
- Pattern *pattern = json_pattern(jpreset, colors);
- if (pattern) {
- ESP_LOGI(TAG, "Creating preset: %s", jpreset->string);
- map[jpreset->string] = pattern;
- }
- }
- cJSON_Delete(jpresets);
- }
- }
-
- } // Presets
|