feat(dom): lazy layout

This commit is contained in:
charleeshen
2021-12-29 10:26:42 +08:00
committed by ilikethese
parent e960c50560
commit d9dc87f45c
8 changed files with 78 additions and 15 deletions
+1
View File
@@ -83,6 +83,7 @@ class DomManager: public std::enable_shared_from_this<DomManager> {
using DomOperation = std::function<void(void)>;
std::vector<DomOperation> batched_operations_;
std::vector<DomOperation> listener_operations_;
std::vector<DomOperation> layout_operations_;
std::vector<std::shared_ptr<DomNode>> layout_changed_nodes_;
void HandleEvent(const std::shared_ptr<DomEvent>& event);
void AddLayoutChangedNode(const std::shared_ptr<DomNode>& node);
@@ -14,8 +14,11 @@ class LayerOptimizedRenderManager : public RenderManager {
void DeleteRenderNode(std::vector<std::shared_ptr<DomNode>>&& nodes) override;
void UpdateLayout(const std::vector<std::shared_ptr<DomNode>>& nodes) override;
void MoveRenderNode(std::vector<int32_t>&& moved_ids, int32_t from_pid, int32_t to_pid) override;
void Batch() override;
void BeforeLayout() override;
void AfterLayout() override;
void AddEventListener(std::weak_ptr<DomNode> dom_node, const std::string& name) override;
void RemoveEventListener(std::weak_ptr<DomNode> dom_node, const std::string& name) override;
+7 -5
View File
@@ -4,10 +4,10 @@
#include <cstdint>
#include <memory>
#include "dom/dom_listener.h"
#include "dom/dom_value.h"
#include "dom/dom_argument.h"
#include "dom/dom_listener.h"
#include "dom/dom_node.h"
#include "dom/dom_value.h"
namespace hippy {
inline namespace dom {
@@ -25,14 +25,16 @@ class RenderManager {
virtual void MoveRenderNode(std::vector<int32_t>&& moved_ids, int32_t from_pid, int32_t to_pid) = 0;
virtual void Batch() = 0;
virtual void BeforeLayout() = 0;
virtual void AfterLayout() = 0;
using DomArgument = hippy::dom::DomArgument;
virtual void AddEventListener(std::weak_ptr<DomNode> dom_node, const std::string& name) = 0;
virtual void RemoveEventListener(std::weak_ptr<DomNode> dom_node, const std::string& name) = 0;
virtual void AddRenderListener(std::weak_ptr<DomNode> dom_node, const std::string& name) = 0;
virtual void RemoveRenderListener(std::weak_ptr<DomNode> dom_node, const std::string& name) = 0;
virtual void CallFunction(std::weak_ptr<DomNode> dom_node, const std::string& name,
const DomArgument& param,
CallFunctionCallback cb) = 0;
virtual void CallFunction(std::weak_ptr<DomNode> dom_node, const std::string& name, const DomArgument& param,
CallFunctionCallback cb) = 0;
};
} // namespace dom
+48 -7
View File
@@ -42,6 +42,14 @@ void DomManager::CreateDomNodes(std::vector<std::shared_ptr<DomNode>>&& nodes) {
node->ParseLayoutStyleInfo();
parent_node->AddChildAt(node, node->GetIndex());
// 延迟构造layout tree
auto layout_node = node->GetLayoutNode();
auto parent_layout_node = parent_node->GetLayoutNode();
uint32_t index = node->GetIndex();
self->layout_operations_.emplace_back([layout_node, parent_layout_node, index]() {
parent_layout_node->InsertChild(layout_node, index);
});
self->dom_node_registry_.AddNode(node);
self->HandleListener(node, kOnDomCreated, nullptr);
}
@@ -74,9 +82,16 @@ void DomManager::UpdateDomNodes(std::vector<std::shared_ptr<DomNode>>&& nodes) {
node->SetStyleMap(it->get()->GetStyleMap());
node->SetExtStyleMap(it->get()->GetExtStyle());
node->SetDiffStyle(std::move(style_diff));
node->ParseLayoutStyleInfo();
// node->ParseLayoutStyleInfo();
update_nodes.push_back(node);
self->HandleListener(node, kOnDomUpdated, nullptr);
// 延迟更新 layout tree
int32_t id = node->GetId();
self->layout_operations_.emplace_back([self, id]() {
auto node = self->dom_node_registry_.GetNode(id);
node->ParseLayoutStyleInfo();
});
}
if (!update_nodes.empty()) {
@@ -107,6 +122,13 @@ void DomManager::DeleteDomNodes(std::vector<std::shared_ptr<DomNode>>&& nodes) {
self->dom_node_registry_.RemoveNode(node->GetId());
delete_nodes.push_back(node);
self->HandleListener(node, kOnDomDeleted, nullptr);
// 延迟删除 layout tree
auto layout_node = node->GetLayoutNode();
auto parent_layout_node = parent_node->GetLayoutNode();
self->layout_operations_.emplace_back([layout_node, parent_layout_node]() {
parent_layout_node->RemoveChild(layout_node);
});
}
if (!delete_nodes.empty()) {
@@ -135,15 +157,24 @@ void DomManager::EndBatch() {
listener_operation();
}
self->listener_operations_.clear();
// 触发布局计算
self->layout_changed_nodes_.clear();
// 触发布局计算
self->root_node_->DoLayout();
auto render_manager = self->render_manager_.lock();
TDF_BASE_DCHECK(render_manager);
if (!render_manager) {
return;
}
// Before Layout
render_manager->BeforeLayout();
// build layout tree
for (auto& layout_operation : self->layout_operations_) {
layout_operation();
}
self->layout_operations_.clear();
// 清理布局计算
self->layout_changed_nodes_.clear();
// 触发布局计算
self->root_node_->DoLayout();
// After Layout
render_manager->AfterLayout();
if (!self->layout_changed_nodes_.empty()) {
render_manager->UpdateLayout(self->layout_changed_nodes_);
}
@@ -254,13 +285,23 @@ void DomManager::DoLayout() {
PostTask([WEAK_THIS]() {
DEFINE_AND_CHECK_SELF(DomManager)
self->layout_changed_nodes_.clear();
// 触发布局计算
self->root_node_->DoLayout();
auto render_manager = self->render_manager_.lock();
TDF_BASE_DCHECK(render_manager);
if (!render_manager) {
return;
}
// Before Layout
render_manager->BeforeLayout();
// build layout tree
for (auto& layout_operation : self->layout_operations_) {
layout_operation();
}
self->layout_operations_.clear();
// 触发布局计算
self->root_node_->DoLayout();
// After Layout
render_manager->AfterLayout();
if (!self->layout_changed_nodes_.empty()) {
render_manager->UpdateLayout(self->layout_changed_nodes_);
}
+2 -2
View File
@@ -90,14 +90,14 @@ void DomNode::AddChildAt(const std::shared_ptr<DomNode>& dom_node, int32_t index
children_.insert(it, dom_node);
}
dom_node->SetParent(shared_from_this());
layout_node_->InsertChild(dom_node->layout_node_, insert_index);
// layout_node_->InsertChild(dom_node->layout_node_, insert_index);
}
std::shared_ptr<DomNode> DomNode::RemoveChildAt(int32_t index) {
auto child = children_[index];
child->SetParent(nullptr);
children_.erase(children_.begin() + index);
layout_node_->RemoveChild(child->layout_node_);
// layout_node_->RemoveChild(child->layout_node_);
return child;
}
@@ -89,6 +89,10 @@ void LayerOptimizedRenderManager::Batch() {
render_manager_->Batch();
}
void LayerOptimizedRenderManager::BeforeLayout() {}
void LayerOptimizedRenderManager::AfterLayout() {}
void LayerOptimizedRenderManager::AddEventListener(std::weak_ptr<DomNode> dom_node,
const std::string &name) {
render_manager_->AddEventListener(dom_node, name);
@@ -27,6 +27,9 @@ class HippyRenderManager : public RenderManager {
void MoveRenderNode(std::vector<int32_t>&& moved_ids, int32_t from_pid, int32_t to_pid) override;
void Batch() override;
void BeforeLayout() override;
void AfterLayout() override;
using DomValue = tdf::base::DomValue;
void AddEventListener(std::weak_ptr<DomNode> dom_node, const std::string& name) override;
@@ -160,6 +160,12 @@ void HippyRenderManager::UpdateLayout(const std::vector<std::shared_ptr<DomNode>
dom_node[kHeight] = tdf::base::DomValue(DpToPx(result.height));
dom_node[kLeft] = tdf::base::DomValue(DpToPx(result.left));
dom_node[kTop] = tdf::base::DomValue(DpToPx(result.top));
if(nodes[i]->GetViewName() == kView) {
dom_node["paddingLeft"] = tdf::base::DomValue(DpToPx(result.padding[0]));
dom_node["paddingTop"] = tdf::base::DomValue(DpToPx(result.padding[1]));
dom_node["paddingRight"] = tdf::base::DomValue(DpToPx(result.padding[2]));
dom_node["paddingBottom"] = tdf::base::DomValue(DpToPx(result.padding[3]));
}
dom_node_array[i] = dom_node;
}
serializer_->WriteDenseJSArray(dom_node_array);
@@ -201,6 +207,9 @@ void HippyRenderManager::Batch() {
return;
};
void BeforeLayout() {};
void AfterLayout() {};
void HippyRenderManager::AddEventListener(std::weak_ptr<DomNode> dom_node, const std::string& name) {
event_listener_ops_.emplace_back(EventListenerOp(true, dom_node, name));
}