diff --git a/libParse/parse_novel.cpp b/libParse/parse_novel.cpp index 5b2b402..398fa59 100644 --- a/libParse/parse_novel.cpp +++ b/libParse/parse_novel.cpp @@ -31,7 +31,7 @@ std::shared_ptr ElementsCache::getNamedNodeBy(int paramType return node_cache[mixed_key]; } -void example_novel::FragmentExistsCheck::nodes_regist(std::shared_ptr cache, std::shared_ptr target) { +void FragmentExistsCheck::nodes_regist(std::shared_ptr cache, std::shared_ptr target) { if (!target->element()->isAnonymous()) cache->appendToCache(target->element()); @@ -53,7 +53,7 @@ void FragmentExistsCheck::exists_check(std::shared_ptr root, std: } } -example_novel::FragmentExistsCheck::FragmentExistsCheck() +FragmentExistsCheck::FragmentExistsCheck() :_nodes_cache(std::make_shared()) { } void FragmentExistsCheck::validCheck(std::shared_ptr root) const { @@ -200,11 +200,13 @@ void PointGraphCheck::validCheck(std::shared_ptr root) cons // 获取绑定节点名称 auto get_name = [](std::shared_ptr node)->QString { switch (node->element()->typeMark()) { - case (int) NovelNode::FragmentSlice: { + case (int) NovelNode::FragmentSlice: + { auto def_node = std::dynamic_pointer_cast(node->element()); return def_node->signature(); }break; - case (int) NovelNode::FragmentRefers: { + case (int) NovelNode::FragmentRefers: + { auto ref_node = std::dynamic_pointer_cast(node->element()); return ref_node->referSignature(); }break; @@ -227,7 +229,7 @@ void PointGraphCheck::validCheck(std::shared_ptr root) cons } // 构建完整图结构:串联引用节点的顺序 - for(auto point : point_items){ + for (auto point : point_items) { auto first_name = get_name(point); auto first_helper = getElement(first_name); @@ -272,7 +274,7 @@ void PointGraphCheck::validCheck(std::shared_ptr root) cons } QString PointGraphCheck::name() const { - return "情节网络有效性检查器"; + return "情节网络引用检查器"; } PointGraphHelper::PointGraphHelper(std::shared_ptr node) : node_peer(node) { } @@ -298,14 +300,16 @@ QList> StoryOrderCheck::valid_docs_peak(std auto type_code = pnode->element()->typeMark(); switch ((NovelNode) type_code) { - case NovelNode::GlobalElement: { + case NovelNode::GlobalElement: + { auto children = pnode->children(); for (auto& cinst : children) { values.append(valid_docs_peak(cinst)); } }break; - case NovelNode::Document: { + case NovelNode::Document: + { auto elms_set = pnode->children(); decltype(elms_set) story_set; @@ -371,3 +375,99 @@ void StoryOrderCheck::validCheck(std::shared_ptr root) cons for (auto& story : story_docs) ranks_number = story_node_sort(story, ranks_number); } + +std::shared_ptr FragmentLayerCheck::_sets_fill(std::shared_ptr node) { + switch ((NovelNode) node->element()->typeMark()) { + case NovelNode::FragmentSlice: + { + auto wins = std::make_shared(node); + this->_node_set[node->element()->signature()] = wins; + return wins; + }break; + case NovelNode::StoryDefine: + { + QList> list; + for (auto nis : node->children()) { + auto ptr = _sets_fill(nis); + if (ptr) list << ptr; + } + for (auto node = ++list.begin(); node != list.end(); ++node) { + auto prev = *(node - 1); + auto curr = *node; + prev->appendNext(curr); + } + if (list.size()) + this->_story_start << list.first(); + } + break; + default: + for (auto nis : node->children()) + _sets_fill(nis); + break; + } + return nullptr; +} + +void FragmentLayerCheck::_refers_rebuild(std::shared_ptr node) { + auto fragm = std::static_pointer_cast(node->bind()->element()); + for (auto node_t : fragm->children()) { + auto refn = std::static_pointer_cast(node_t); + auto target_node = _node_set[refn->referSignature()]; + std::const_pointer_cast(node)->appendNext(target_node); + } + +} + +void FragmentLayerCheck::node_relayer(std::shared_ptr node, int curr_num) { + if (node->layerNumber() < curr_num) { + node->setLayer(curr_num); + + for (auto nis : node->referNodes()) + node_relayer(nis, curr_num + 1); + } +} + +QString FragmentLayerCheck::name() const { + return "情节时间层级校验器"; +} + +void FragmentLayerCheck::validCheck(std::shared_ptr root) const { + auto chk = const_cast(this); + chk->_sets_fill(root); + + for (auto node : chk->_node_set) + chk->_refers_rebuild(node); + + for (auto node : chk->_story_start) + chk->node_relayer(node); +} + +FragmentNode::FragmentNode(std::shared_ptr bind) :_src_fragm(bind) { } + +std::shared_ptr FragmentNode::bind() const { + return this->_src_fragm; +} + +void FragmentNode::setLayer(int number) { + this->_layer_number = number; +} + +void FragmentNode::setLayer(int number) { + this->_layer_number = number; +} + +int FragmentNode::layerNumber() const { + return this->_layer_number; +} + +int FragmentNode::layerNumber() const { + return this->_layer_number; +} + +QList> FragmentNode::referNodes() const { + return _next_fragms; +} + +void FragmentNode::appendNext(std::shared_ptr ins) { + this->_next_fragms << ins; +} diff --git a/libParse/parse_novel.h b/libParse/parse_novel.h index a2c3c71..cb18fb3 100644 --- a/libParse/parse_novel.h +++ b/libParse/parse_novel.h @@ -108,4 +108,51 @@ namespace example_novel { QString name() const override; void validCheck(std::shared_ptr root) const override; }; + + class FragmentNode : public std::enable_shared_from_this { + private: + std::shared_ptr _src_fragm = nullptr; + QList> _next_fragms; + int _layer_number = -1; + + public: + FragmentNode(std::shared_ptr bind); + std::shared_ptr bind() const; + + void setLayer(int number); + int layerNumber() const; + + QList> referNodes() const; + void appendNext(std::shared_ptr ins); + }; + + /** + * @brief 情节时间顺序校验 + */ + class LIBPARSE_EXPORT FragmentLayerCheck : public lib_parse::CheckProvider { + private: + QHash> _node_set; + QList> _story_start; + + /** + * @brief 故事线转换 + */ + std::shared_ptr _sets_fill(std::shared_ptr node); + /** + * @brief 引用网络重构 + */ + void _refers_rebuild(std::shared_ptr node); + + /** + * @brief 节点层级重排 + */ + void node_relayer(std::shared_ptr node, int curr = 0); + + void layer_check(std::shared_ptr node){ } + + public: + // 通过 CheckProvider 继承 + QString name() const override; + void validCheck(std::shared_ptr root) const override; + }; } // namespace example_novel