// // Created by m on 7/27/17. // #include #include "json_helper.hpp" #include "layers.hpp" #include "util.hpp" namespace wm { using json = nlohmann::json; surface_id_to_layer::surface_id_to_layer(nlohmann::json const &j) { // DB(j); if (j["type"] == "range") { this->id_min = get(j["first_surface_id"]); this->id_max = get(j["last_surface_id"]); } else { this->id_min = this->id_max = get(j["surface_id"]); } this->name = j["name"].get(); this->layer_id = get(j["layer_id"]); } struct result to_surface_id_to_layer_map( nlohmann::json const &j) { DB(j); try { surface_id_to_layer_map stl{}; auto m = j["mappings"]; stl.layers.reserve(m.size()); std::transform( std::cbegin(m), std::cend(m), std::inserter(stl.mapping, stl.mapping.end()), [&stl](nlohmann::json const &j) { auto k = surface_id_to_layer(j); stl.layers.push_back(unsigned(k.layer_id)); return k; }); // XXX need to sort layers? for (auto i : stl.mapping) { if (i.name.empty()) { return Err( "Found mapping w/o name"); } if (i.layer_id == -1 || i.id_min == -1 || i.id_max == -1) { return Err( "Found invalid/unset IDs in mapping"); } } // Check lookup auto jtests = j.value("tests", json()); if (! jtests.empty()) { DB("Embedded tests..."); std::vector> tests; tests.reserve(jtests.size()); std::transform(std::cbegin(jtests), std::cend(jtests), std::back_inserter(tests), [](json const &j) { return std::make_pair(get(j["surface_id"]), get(j["expect_layer_id"])); }); for (auto sid : tests) { int lid = stl.get_layer_for_surface(sid.first).value_or(-1); DB("this=" << sid.first << ", that=" << lid << ", expect=" << sid.second); if (lid != sid.second) { return Err( "ID Map embedded test failed!"); } } } return Ok(stl); } catch (std::exception &e) { return Err(e.what()); } } // Helper to allow std::lower_bound with a int key only inline bool operator<(struct surface_id_to_layer const &a, int b) { return a.id_max < b; } optional surface_id_to_layer_map::get_layer_for_surface(int surface_id) { auto i = std::lower_bound(std::cbegin(this->mapping), std::cend(this->mapping), surface_id); if (i != this->mapping.end()) { // std::less only checks for surface_id_to_layer::id_max, so check // that we are actually inside of an interval here. if (i->id_min <= surface_id) { return optional(i->layer_id); } } return nullopt; } } // namespace wm