From aa93c41c9d3b8a81e09d80583d5d672c5fd547fe Mon Sep 17 00:00:00 2001 From: zealotchen Date: Wed, 18 Oct 2023 19:12:05 +0800 Subject: [PATCH] feat(dom): add dom style diff --- dom/include/dom/diff_utils.h | 2 +- dom/include/dom/dom_node.h | 11 +++++++++- dom/src/dom/diff_utils.cc | 6 +++++- dom/src/dom/dom_manager.cc | 2 +- dom/src/dom/dom_manager_unittests.cc | 3 ++- dom/src/dom/dom_node.cc | 4 ++-- dom/src/dom/root_node.cc | 10 +++++++--- driver/js/src/modules/scene_builder_module.cc | 20 +++++++++++++++---- 8 files changed, 44 insertions(+), 14 deletions(-) diff --git a/dom/include/dom/diff_utils.h b/dom/include/dom/diff_utils.h index 8f8ec570b0e..5b8c0b9f679 100644 --- a/dom/include/dom/diff_utils.h +++ b/dom/include/dom/diff_utils.h @@ -53,7 +53,7 @@ class DiffUtils { * k: 11, * } */ - static DiffValue DiffProps(const DomValueMap& old_props_map, const DomValueMap& new_props_map); + static DiffValue DiffProps(const DomValueMap& old_props_map, const DomValueMap& new_props_map, bool skip_style_diff); }; } // namespace dom } // namespace hippy diff --git a/dom/include/dom/dom_node.h b/dom/include/dom/dom_node.h index 8b957411a44..24519607de8 100644 --- a/dom/include/dom/dom_node.h +++ b/dom/include/dom/dom_node.h @@ -55,6 +55,14 @@ enum RelativeType { kBack = 1, }; +struct DiffInfo { + bool skip_style_diff; + DiffInfo(bool skip_style_diff) : skip_style_diff(skip_style_diff) {} + + private: + friend std::ostream& operator<<(std::ostream& os, const DiffInfo& diff_info); +}; + struct RefInfo { uint32_t ref_id; int32_t relative_to_ref = RelativeType::kDefault; @@ -67,7 +75,8 @@ struct RefInfo { struct DomInfo { std::shared_ptr dom_node; std::shared_ptr ref_info; - DomInfo(std::shared_ptr node, std::shared_ptr ref) : dom_node(node), ref_info(ref) {} + std::shared_ptr diff_info; + DomInfo(std::shared_ptr node, std::shared_ptr ref, std::shared_ptr diff) : dom_node(node), ref_info(ref), diff_info(diff) {} private: friend std::ostream& operator<<(std::ostream& os, const DomInfo& dom_info); diff --git a/dom/src/dom/diff_utils.cc b/dom/src/dom/diff_utils.cc index d101a840bc6..7b11fa274a2 100644 --- a/dom/src/dom/diff_utils.cc +++ b/dom/src/dom/diff_utils.cc @@ -69,9 +69,13 @@ static bool ShouldUpdateProperty(const std::string& key, const DomValueMap& old_ return false; } -DiffValue DiffUtils::DiffProps(const DomValueMap& old_props_map, const DomValueMap& new_props_map) { +DiffValue DiffUtils::DiffProps(const DomValueMap& old_props_map, const DomValueMap& new_props_map, bool skip_style_diff) { std::shared_ptr update_props = std::make_shared(); std::shared_ptr> delete_props = std::make_shared>(); + if (skip_style_diff) { + // 跳过 style diff 计算 + return std::make_tuple(update_props, delete_props); + } // delete props // Example: diff --git a/dom/src/dom/dom_manager.cc b/dom/src/dom/dom_manager.cc index 3a9e947dd26..533466a2d3c 100644 --- a/dom/src/dom/dom_manager.cc +++ b/dom/src/dom/dom_manager.cc @@ -262,7 +262,7 @@ bool DomManager::SetSnapShot(const std::shared_ptr& root_node, const b if (dom_node->GetPid() == orig_root_id) { dom_node->SetPid(root_node->GetId()); } - nodes.push_back(std::make_shared(dom_node, nullptr)); + nodes.push_back(std::make_shared(dom_node, nullptr, nullptr)); } CreateDomNodes(root_node, std::move(nodes)); diff --git a/dom/src/dom/dom_manager_unittests.cc b/dom/src/dom/dom_manager_unittests.cc index 4c76cf745fb..094566a0236 100644 --- a/dom/src/dom/dom_manager_unittests.cc +++ b/dom/src/dom/dom_manager_unittests.cc @@ -110,7 +110,8 @@ std::vector> ParserJson(const std::string& json_ ref = std::make_shared(id, ref_id); } - std::shared_ptr dom_info = std::make_shared(dom_node, ref); + auto diff_info = std::make_shared(false); + std::shared_ptr dom_info = std::make_shared(dom_node, ref, diff_info); nodes.push_back(dom_info); } return nodes; diff --git a/dom/src/dom/dom_node.cc b/dom/src/dom/dom_node.cc index 4e569582c28..701db433487 100644 --- a/dom/src/dom/dom_node.cc +++ b/dom/src/dom/dom_node.cc @@ -494,8 +494,8 @@ void DomNode::UpdateDiff(const std::unordered_map>& update_style, const std::unordered_map>& update_dom_ext) { - auto style_diff_value = DiffUtils::DiffProps(*this->GetStyleMap(), update_style); - auto ext_diff_value = DiffUtils::DiffProps(*this->GetExtStyle(), update_dom_ext); + auto style_diff_value = DiffUtils::DiffProps(*this->GetStyleMap(), update_style, false); + auto ext_diff_value = DiffUtils::DiffProps(*this->GetExtStyle(), update_dom_ext, false); auto style_update = std::get<0>(style_diff_value); auto ext_update = std::get<0>(ext_diff_value); std::shared_ptr diff_value = std::make_shared(); diff --git a/dom/src/dom/root_node.cc b/dom/src/dom/root_node.cc index 7310b5a087c..30db48f49e8 100644 --- a/dom/src/dom/root_node.cc +++ b/dom/src/dom/root_node.cc @@ -141,9 +141,13 @@ void RootNode::UpdateDomNodes(std::vector>&& nodes) { if (dom_node == nullptr) { continue; } + auto skip_style_diff = false; + if (node_info->diff_info != nullptr) { + skip_style_diff = node_info->diff_info->skip_style_diff; + } // diff props - auto style_diff_value = DiffUtils::DiffProps(*dom_node->GetStyleMap(), *node_info->dom_node->GetStyleMap()); - auto ext_diff_value = DiffUtils::DiffProps(*dom_node->GetExtStyle(), *node_info->dom_node->GetExtStyle()); + auto style_diff_value = DiffUtils::DiffProps(*dom_node->GetStyleMap(), *node_info->dom_node->GetStyleMap(), skip_style_diff); + auto ext_diff_value = DiffUtils::DiffProps(*dom_node->GetExtStyle(), *node_info->dom_node->GetExtStyle(), false); auto style_update = std::get<0>(style_diff_value); auto ext_update = std::get<0>(ext_diff_value); std::shared_ptr diff_value = std::make_shared(); @@ -205,7 +209,7 @@ void RootNode::MoveDomNodes(std::vector>&& nodes) { continue; } nodes_to_move.push_back(node); - parent_node->AddChildByRefInfo(std::make_shared(node, node_info->ref_info)); + parent_node->AddChildByRefInfo(std::make_shared(node, node_info->ref_info, nullptr)); } for (const auto& node : nodes_to_move) { node->SetRenderInfo({node->GetId(), node->GetPid(), node->GetSelfIndex()}); diff --git a/driver/js/src/modules/scene_builder_module.cc b/driver/js/src/modules/scene_builder_module.cc index 27a8f6bfb6f..9f76ec84ac5 100644 --- a/driver/js/src/modules/scene_builder_module.cc +++ b/driver/js/src/modules/scene_builder_module.cc @@ -59,6 +59,7 @@ constexpr char kNodePropertyProps[] = "props"; constexpr char kNodePropertyStyle[] = "style"; constexpr char kNodePropertyRefId[] = "refId"; constexpr char kNodePropertyRelativeToRef[] = "relativeToRef"; +constexpr char KNodePropertySkipStyleDiff[] = "skipStyleDiff"; constexpr char kEventCapture[] = "capture"; const int32_t kInvalidValue = -1; @@ -322,6 +323,7 @@ std::tuple> CreateDomInfo( std::shared_ptr dom_info = nullptr; std::shared_ptr dom_node = nullptr; std::shared_ptr ref_info = nullptr; + std::shared_ptr diff_info = nullptr; uint32_t len = context->GetArrayLength(node); if (len > 0) { auto dom_node_tuple = @@ -330,17 +332,26 @@ std::tuple> CreateDomInfo( return std::make_tuple(false, "get dom node info error.", dom_info); } dom_node = std::get<2>(dom_node_tuple); - if (len == 2) { + if (len > 1) { auto ref_info_tuple = CreateRefInfo(context, context->CopyArrayElement(node, 1), scope); if (std::get<0>(ref_info_tuple)) { ref_info = std::get<2>(ref_info_tuple); } } + if (len == 3) { + auto diff = context->CopyArrayElement(node, 2); + std::shared_ptr style_diff = context->GetProperty(diff, KNodePropertySkipStyleDiff); + if (style_diff) { + bool skip_style_diff; + context->GetValueBoolean(style_diff, &skip_style_diff); + diff_info = std::make_shared(skip_style_diff); + } + } } else { return std::make_tuple(false, "dom info length error.", dom_info); } - dom_info = std::make_shared(dom_node, ref_info); + dom_info = std::make_shared(dom_node, ref_info, diff_info); return std::make_tuple(true, "", dom_info); } @@ -484,7 +495,8 @@ std::shared_ptr> RegisterSceneBuilder(const std::wea std::get<2>(id_tuple), std::get<2>(pid_tuple), scope->GetRootNode()), - std::get<2>(ref_info_tuple))); + std::get<2>(ref_info_tuple), + nullptr)); } } } @@ -528,7 +540,7 @@ std::shared_ptr> RegisterSceneBuilder(const std::wea std::get<2>(id_tuple), std::get<2>(pid_tuple), scope->GetRootNode()), - nullptr)); + nullptr, nullptr)); } } SceneBuilder::Delete(scope->GetDomManager(), scope->GetRootNode(), std::move(dom_infos));