201 lines
5.9 KiB
C++
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<PointDefines>>
|
|
Compare::changeCompare(Type _type, const QHash<QString, shared_ptr<StoryDefine>>& g_old) const {
|
|
QList<shared_ptr<PointDefines>> 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<PointDefines>(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<PointDefines>(story_new->getFragment(fragm));
|
|
auto fragm_peer = std::dynamic_pointer_cast<PointDefines>(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<PointDefines> a, std::shared_ptr<PointDefines> 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<PointDefines>(prev_slice_a)->getTextNode()->getLines();
|
|
desc_b = std::dynamic_pointer_cast<PointDefines>(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<PointDefines>(a)->referSlices();
|
|
auto slices_b = std::dynamic_pointer_cast<PointDefines>(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;
|
|
}
|