1 #include <mbgl/renderer/style_diff.hpp>
2 #include <mbgl/style/layer_impl.hpp>
3 #include <mbgl/util/immutable.hpp>
4 #include <mbgl/util/variant.hpp>
5 #include <mbgl/util/longest_common_subsequence.hpp>
6
7 namespace mbgl {
8
9 template <class T, class Eq>
diff(const Immutable<std::vector<T>> & a,const Immutable<std::vector<T>> & b,const Eq & eq)10 StyleDifference<T> diff(const Immutable<std::vector<T>>& a,
11 const Immutable<std::vector<T>>& b,
12 const Eq& eq) {
13 StyleDifference<T> result;
14
15 if (a == b) {
16 return result;
17 }
18
19 std::vector<T> lcs;
20
21 longest_common_subsequence(a->begin(), a->end(), b->begin(), b->end(), std::back_inserter(lcs), eq);
22
23 auto aIt = a->begin();
24 auto bIt = b->begin();
25 auto lIt = lcs.begin();
26
27 while (aIt != a->end() || bIt != b->end()) {
28 if (aIt != a->end() && (lIt == lcs.end() || !eq(*lIt, *aIt))) {
29 result.removed.emplace((*aIt)->id, *aIt);
30 aIt++;
31 } else if (bIt != b->end() && (lIt == lcs.end() || !eq(*lIt, *bIt))) {
32 result.added.emplace((*bIt)->id, *bIt);
33 bIt++;
34 } else {
35 if (aIt->get() != bIt->get()) {
36 result.changed.emplace((*bIt)->id, StyleChange<T> { *aIt, *bIt });
37 }
38 aIt++;
39 bIt++;
40 lIt++;
41 }
42 }
43
44 return result;
45 }
46
diffImages(const Immutable<std::vector<ImmutableImage>> & a,const Immutable<std::vector<ImmutableImage>> & b)47 ImageDifference diffImages(const Immutable<std::vector<ImmutableImage>>& a,
48 const Immutable<std::vector<ImmutableImage>>& b) {
49 return diff(a, b, [] (const ImmutableImage& lhs, const ImmutableImage& rhs) {
50 return lhs->id == rhs->id;
51 });
52 }
53
diffSources(const Immutable<std::vector<ImmutableSource>> & a,const Immutable<std::vector<ImmutableSource>> & b)54 SourceDifference diffSources(const Immutable<std::vector<ImmutableSource>>& a,
55 const Immutable<std::vector<ImmutableSource>>& b) {
56 return diff(a, b, [] (const ImmutableSource& lhs, const ImmutableSource& rhs) {
57 return std::tie(lhs->id, lhs->type)
58 == std::tie(rhs->id, rhs->type);
59 });
60 }
61
diffLayers(const Immutable<std::vector<ImmutableLayer>> & a,const Immutable<std::vector<ImmutableLayer>> & b)62 LayerDifference diffLayers(const Immutable<std::vector<ImmutableLayer>>& a,
63 const Immutable<std::vector<ImmutableLayer>>& b) {
64 return diff(a, b, [] (const ImmutableLayer& lhs, const ImmutableLayer& rhs) {
65 return std::tie(lhs->id, lhs->type)
66 == std::tie(rhs->id, rhs->type);
67 });
68 }
69
hasLayoutDifference(const LayerDifference & layerDiff,const std::string & layerID)70 bool hasLayoutDifference(const LayerDifference& layerDiff, const std::string& layerID) {
71 if (layerDiff.added.count(layerID))
72 return true;
73 const auto it = layerDiff.changed.find(layerID);
74 if (it == layerDiff.changed.end())
75 return false;
76 return it->second.before->hasLayoutDifference(*it->second.after);
77 }
78
79 } // namespace mbgl
80