WsParser_VS/StoryPresent/storyline_compare.cpp

201 lines
5.9 KiB
C++

#include "storyline_compare.h"
using namespace compare;
using namespace xast_parse;
using namespace std;
Compare::Compare(const QHash<QString, shared_ptr<StoryDefine>>& graph)
: _graph_base(graph) {}
const QHash<QString, std::shared_ptr<xast_parse::StoryDefine>>& compare::Compare::graphBind() const
{
return _graph_base;
}
QList<shared_ptr<FragmentDefine>>
Compare::changeCompare(Type _type, const QHash<QString, shared_ptr<StoryDefine>>& g_old) const {
QList<shared_ptr<FragmentDefine>> 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<QString> fragmets_define;
while (story_new_temp) {
if (story_new_temp->type() == SliceType::FragmentDefines) {
auto fragm = std::dynamic_pointer_cast<FragmentDefine>(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<FragmentDefine>(story_new->getFragment(fragm));
auto fragm_peer = std::dynamic_pointer_cast<FragmentDefine>(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<FragmentDefine> a, std::shared_ptr<FragmentDefine> 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<IElementSlice> v) -> QString {
switch (v->type()) {
case SliceType::StoryDefines:
{
auto cast_it = std::dynamic_pointer_cast<StoryDefine>(v);
return "s:" + cast_it->name();
}break;
default:
{
auto cast_it = std::dynamic_pointer_cast<ArticleDefine>(v);
return "a:" + cast_it->name();
}break;
}
};
std::sort(slices_a.begin(), slices_a.end(), [&](std::shared_ptr<IElementSlice>a, std::shared_ptr<IElementSlice>b) {
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_ptr<IElementSlice>a, std::shared_ptr<IElementSlice>b) {
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<FragmentRefer>(slices_a.at(idx));
auto refer_b = std::dynamic_pointer_cast<FragmentRefer>(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<IElementSlice> a, std::shared_ptr<IElementSlice> 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<TextParagraph>(prev_slice_a)->getLines();
desc_b = std::dynamic_pointer_cast<TextParagraph>(prev_slice_b)->getLines();
}break;
case SliceType::PointRefers:
{
desc_a = std::dynamic_pointer_cast<FragmentRefer>(prev_slice_a)->getTextNode()->getLines();
desc_b = std::dynamic_pointer_cast<FragmentRefer>(prev_slice_b)->getTextNode()->getLines();
}break;
default:
{
desc_a = std::dynamic_pointer_cast<FragmentDefine>(prev_slice_a)->getTextNode()->getLines();
desc_b = std::dynamic_pointer_cast<FragmentDefine>(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<FragmentDefine>(a)->referSlices();
auto slices_b = std::dynamic_pointer_cast<FragmentDefine>(b)->referSlices();
if(slices_a.size() != slices_b.size())
return true;
auto get_label = [](std::shared_ptr<IElementSlice> v) -> QString {
switch (v->type()) {
case SliceType::StoryDefines:
{
auto cast_it = std::dynamic_pointer_cast<StoryDefine>(v);
return "s:" + cast_it->name();
}break;
default:
{
auto cast_it = std::dynamic_pointer_cast<ArticleDefine>(v);
return "a:" + cast_it->name();
}break;
}
};
std::sort(slices_a.begin(), slices_a.end(), [&](std::shared_ptr<IElementSlice>a, std::shared_ptr<IElementSlice>b) {
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_ptr<IElementSlice>a, std::shared_ptr<IElementSlice>b) {
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<FragmentRefer>(slices_a.at(idx));
auto refer_b = std::dynamic_pointer_cast<FragmentRefer>(slices_b.at(idx));
if(upstream_check(refer_a, refer_b))
return true;
}
}
return false;
}