#include "storyline_compare.h" using namespace compare; using namespace xast_parse; using namespace std; Compare::Compare(const QHash>& graph) : _graph_base(graph) {} const QHash>& compare::Compare::graphBind() const { return _graph_base; } QList> Compare::changeCompare(Type _type, const QHash>& g_old) const { QList> values; for (auto& type : _graph_base.keys()) { if (g_old.contains(type)) { auto story_new = _graph_base[type]; auto story_old = g_old[type]; auto story_new_temp = story_new->firstChild(); QList fragmets_define; while (story_new_temp) { if (story_new_temp->type() == SliceType::FragmentDefines) { auto fragm = std::dynamic_pointer_cast(story_new_temp); fragmets_define << fragm->name(); } story_new_temp = story_new_temp->nextSlice(); } for (auto fragm : fragmets_define) { auto fragm_this = std::dynamic_pointer_cast(story_new->getFragment(fragm)); auto fragm_peer = std::dynamic_pointer_cast(story_old->getFragment(fragm)); if (fragm_peer) { if (_type == Type::FragmentAlter) { if (fragment_check(fragm_this, fragm_peer)) values << fragm_this; } else { if (upstream_check(fragm_this, fragm_peer)) values << fragm_this; } } } } } return values; } bool Compare::fragment_check(std::shared_ptr a, std::shared_ptr b) const { auto texts_a = a->getTextNode(); auto texts_b = b->getTextNode(); if (texts_a->getLines() != texts_b->getLines()) return true; auto slices_a = a->referSlices(); auto slices_b = b->referSlices(); if (slices_a.size() != slices_b.size()) return true; auto get_label = [](std::shared_ptr v) -> QString { switch (v->type()) { case SliceType::StoryDefines: { auto cast_it = std::dynamic_pointer_cast(v); return "s:" + cast_it->name(); }break; default: { auto cast_it = std::dynamic_pointer_cast(v); return "a:" + cast_it->name(); }break; } }; std::sort(slices_a.begin(), slices_a.end(), [&](std::shared_ptra, std::shared_ptrb) { auto parent_a = a->parentSlice(); auto parent_b = b->parentSlice(); auto label_a = get_label(parent_a.lock()); auto label_b = get_label(parent_b.lock()); return label_a < label_b; }); std::sort(slices_b.begin(), slices_b.end(), [&](std::shared_ptra, std::shared_ptrb) { auto parent_a = a->parentSlice(); auto parent_b = b->parentSlice(); auto label_a = get_label(parent_a.lock()); auto label_b = get_label(parent_b.lock()); return label_a < label_b; }); for (auto idx = 0; idx < slices_a.size(); ++idx) { auto refer_a = std::dynamic_pointer_cast(slices_a.at(idx)); auto refer_b = std::dynamic_pointer_cast(slices_b.at(idx)); auto desc_a = refer_a->getTextNode()->getLines(); auto desc_b = refer_b->getTextNode()->getLines(); if (desc_a != desc_b) return true; } return false; } bool Compare::upstream_check(std::shared_ptr a, std::shared_ptr b) const { auto prev_slice_a = a->prevSlice().lock(); auto prev_slice_b = b->prevSlice().lock(); if (!prev_slice_a && prev_slice_b) return true; if (prev_slice_a && !prev_slice_b) return true; if (prev_slice_a && prev_slice_b) { if (prev_slice_a->type() != prev_slice_b->type()) return true; QString desc_a, desc_b; switch (prev_slice_a->type()) { case SliceType::TextPragraph: { desc_a = std::dynamic_pointer_cast(prev_slice_a)->getLines(); desc_b = std::dynamic_pointer_cast(prev_slice_b)->getLines(); }break; case SliceType::PointRefers: { desc_a = std::dynamic_pointer_cast(prev_slice_a)->getTextNode()->getLines(); desc_b = std::dynamic_pointer_cast(prev_slice_b)->getTextNode()->getLines(); }break; default: { desc_a = std::dynamic_pointer_cast(prev_slice_a)->getTextNode()->getLines(); desc_b = std::dynamic_pointer_cast(prev_slice_b)->getTextNode()->getLines(); } break; } if (desc_a != desc_b) return true; } if (a->type() == SliceType::FragmentDefines) { auto slices_a = std::dynamic_pointer_cast(a)->referSlices(); auto slices_b = std::dynamic_pointer_cast(b)->referSlices(); if(slices_a.size() != slices_b.size()) return true; auto get_label = [](std::shared_ptr v) -> QString { switch (v->type()) { case SliceType::StoryDefines: { auto cast_it = std::dynamic_pointer_cast(v); return "s:" + cast_it->name(); }break; default: { auto cast_it = std::dynamic_pointer_cast(v); return "a:" + cast_it->name(); }break; } }; std::sort(slices_a.begin(), slices_a.end(), [&](std::shared_ptra, std::shared_ptrb) { auto parent_a = a->parentSlice(); auto parent_b = b->parentSlice(); auto label_a = get_label(parent_a.lock()); auto label_b = get_label(parent_b.lock()); return label_a < label_b; }); std::sort(slices_b.begin(), slices_b.end(), [&](std::shared_ptra, std::shared_ptrb) { auto parent_a = a->parentSlice(); auto parent_b = b->parentSlice(); auto label_a = get_label(parent_a.lock()); auto label_b = get_label(parent_b.lock()); return label_a < label_b; }); for (auto idx = 0; idx < slices_a.size(); ++idx) { auto refer_a = std::dynamic_pointer_cast(slices_a.at(idx)); auto refer_b = std::dynamic_pointer_cast(slices_b.at(idx)); if(upstream_check(refer_a, refer_b)) return true; } } return false; }