Skip to content

Commit

Permalink
feat(dom): change some functions to excute under dom thread
Browse files Browse the repository at this point in the history
  • Loading branch information
ilikethese committed Apr 28, 2022
1 parent 2ac54c8 commit 31fffc4
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 115 deletions.
16 changes: 13 additions & 3 deletions dom/include/dom/dom_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
#include <vector>

#include "base/logging.h"
#include "core/base/task_runner.h"
#include "base/macros.h"
#include "core/base/common.h"
#include "core/base/task_runner.h"
#include "core/task/common_task.h"
#include "dom/dom_action_interceptor.h"
#include "dom/dom_argument.h"
#include "dom/dom_event.h"
#include "dom/dom_listener.h"
#include "dom/dom_value.h"
#include "dom/layout_node.h"
#include "dom/dom_action_interceptor.h"
#include "dom/scene.h"
#include "base/macros.h"

namespace hippy {
inline namespace dom {
Expand All @@ -27,6 +27,16 @@ class RenderManager;
class RootNode;
class LayerOptimizedRenderManager;

// This class is used to mainpulate dom. Please note that the member
// function of this class must be run in dom thread. If you want to call
// in other thread please use PostTask.
// Example:
// std::vector<std::function<void()>> ops;
// ops.emplace_back([]() {
// some_ops();
// });
// dom_manager->PostTask(Scene(std::move(ops)));

class DomManager : public std::enable_shared_from_this<DomManager> {
public:
using DomValue = tdf::base::DomValue;
Expand Down
10 changes: 3 additions & 7 deletions dom/src/dom/dom_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,9 @@ void DomManager::HandleEvent(const std::shared_ptr<DomEvent>& event) {
}

void DomManager::PostTask(const Scene&& scene) {
if (dom_task_runner_->Id() == hippy::base::ThreadId::GetCurrent()) {
scene.Build();
} else {
std::shared_ptr<CommonTask> task = std::make_shared<CommonTask>();
task->func_ = [scene = std::move(scene)] { scene.Build(); };
dom_task_runner_->PostTask(std::move(task));
}
std::shared_ptr<CommonTask> task = std::make_shared<CommonTask>();
task->func_ = [scene = std::move(scene)] { scene.Build(); };
dom_task_runner_->PostTask(std::move(task));
}

void DomManager::UpdateRenderNode(const std::shared_ptr<DomNode>& node) {
Expand Down
154 changes: 58 additions & 96 deletions dom/src/dom/dom_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,7 @@ void DomNode::HandleEvent(const std::shared_ptr<DomEvent>& event) {
auto dom_manager = dom_manager_.lock();
TDF_BASE_DCHECK(dom_manager);
if (dom_manager) {
std::vector<std::function<void()>> ops = {[WEAK_THIS, event] {
DEFINE_AND_CHECK_SELF(DomNode);
auto manager = self->dom_manager_.lock();
TDF_BASE_DCHECK(manager);
if (manager) {
manager->HandleEvent(std::move(event));
}
}};
dom_manager->PostTask(Scene(std::move(ops)));
dom_manager->HandleEvent(std::move(event));
}
}

Expand All @@ -138,85 +130,66 @@ void DomNode::AddEventListener(const std::string& name, bool use_capture, const
auto dom_manager = dom_manager_.lock();
TDF_BASE_DCHECK(dom_manager);
if (dom_manager) {
std::vector<std::function<void()>> ops_ = {[WEAK_THIS, name, use_capture, cb, callback]() {
DEFINE_AND_CHECK_SELF(DomNode)
// taskRunner内置执行确保current_callback_id_无多线程问题
self->current_callback_id_ += 1;
TDF_BASE_DCHECK(self->current_callback_id_ <= std::numeric_limits<uint32_t>::max());
if (!self->event_listener_map_) {
self->event_listener_map_ = std::make_shared<
std::unordered_map<std::string, std::array<std::vector<std::shared_ptr<EventListenerInfo>>, 2>>>();
}
auto it = self->event_listener_map_->find(name);
if (it == self->event_listener_map_->end()) {
(*self->event_listener_map_)[name] = {};
auto dom_manager = self->dom_manager_.lock();
TDF_BASE_DCHECK(dom_manager);
if (dom_manager) {
dom_manager->AddEventListenerOperation(self, name);
}
}
if (use_capture) {
(*self->event_listener_map_)[name][kCapture].push_back(
std::make_shared<EventListenerInfo>(self->current_callback_id_, cb));
} else {
(*self->event_listener_map_)[name][kBubble].push_back(
std::make_shared<EventListenerInfo>(self->current_callback_id_, cb));
}
if (callback) {
auto arg = std::make_shared<DomArgument>(DomValue(self->current_callback_id_));
callback(arg);
}
}};
dom_manager->PostTask(Scene(std::move(ops_)));
current_callback_id_ += 1;
TDF_BASE_DCHECK(current_callback_id_ <= std::numeric_limits<uint32_t>::max());
if (!event_listener_map_) {
event_listener_map_ = std::make_shared<
std::unordered_map<std::string, std::array<std::vector<std::shared_ptr<EventListenerInfo>>, 2>>>();
}
auto it = event_listener_map_->find(name);
if (it == event_listener_map_->end()) {
(*event_listener_map_)[name] = {};
dom_manager->AddEventListenerOperation(shared_from_this(), name);
}
if (use_capture) {
(*event_listener_map_)[name][kCapture].push_back(std::make_shared<EventListenerInfo>(current_callback_id_, cb));
} else {
(*event_listener_map_)[name][kBubble].push_back(std::make_shared<EventListenerInfo>(current_callback_id_, cb));
}
if (callback) {
auto arg = std::make_shared<DomArgument>(DomValue(current_callback_id_));
callback(arg);
}
}
}

void DomNode::RemoveEventListener(const std::string& name, uint32_t id) {
auto dom_manager = dom_manager_.lock();
TDF_BASE_DCHECK(dom_manager);
if (dom_manager) {
std::vector<std::function<void()>> ops_ = {[WEAK_THIS, name, id]() {
DEFINE_AND_CHECK_SELF(DomNode)
if (!self->event_listener_map_) {
return;
}
auto it = self->event_listener_map_->find(name);
if (it == self->event_listener_map_->end()) {
return;
}
auto capture_listeners = it->second[kCapture];
auto capture_it = std::find_if(capture_listeners.begin(), capture_listeners.end(),
[id](const std::shared_ptr<EventListenerInfo>& item) {
if (item->id == id) {
return true;
}
return false;
});
if (capture_it != capture_listeners.end()) {
capture_listeners.erase(capture_it);
}
auto bubble_listeners = it->second[kBubble];
auto bubble_it = std::find_if(bubble_listeners.begin(), bubble_listeners.end(),
[id](const std::shared_ptr<EventListenerInfo>& item) {
if (item->id == id) {
return true;
}
return false;
});
if (bubble_it != bubble_listeners.end()) {
bubble_listeners.erase(bubble_it);
}
if (capture_listeners.empty() && bubble_listeners.empty()) {
auto dom_manager = self->dom_manager_.lock();
TDF_BASE_DCHECK(dom_manager);
if (dom_manager) {
dom_manager->RemoveEventListenerOperation(self, name);
self->event_listener_map_->erase(it);
}
}
}};
dom_manager->PostTask(Scene(std::move(ops_)));
if (!event_listener_map_) {
return;
}
auto it = event_listener_map_->find(name);
if (it == event_listener_map_->end()) {
return;
}
auto capture_listeners = it->second[kCapture];
auto capture_it = std::find_if(capture_listeners.begin(), capture_listeners.end(),
[id](const std::shared_ptr<EventListenerInfo>& item) {
if (item->id == id) {
return true;
}
return false;
});
if (capture_it != capture_listeners.end()) {
capture_listeners.erase(capture_it);
}
auto bubble_listeners = it->second[kBubble];
auto bubble_it = std::find_if(bubble_listeners.begin(), bubble_listeners.end(),
[id](const std::shared_ptr<EventListenerInfo>& item) {
if (item->id == id) {
return true;
}
return false;
});
if (bubble_it != bubble_listeners.end()) {
bubble_listeners.erase(bubble_it);
}
if (capture_listeners.empty() && bubble_listeners.empty()) {
dom_manager->RemoveEventListenerOperation(shared_from_this(), name);
event_listener_map_->erase(it);
}
}
}

Expand Down Expand Up @@ -352,21 +325,10 @@ void DomNode::UpdateProperties(const std::unordered_map<std::string, std::shared
auto dom_manager = dom_manager_.lock();
TDF_BASE_DCHECK(dom_manager);
if (dom_manager) {
std::vector<std::function<void()>> ops_ = {[WEAK_THIS, update_style, update_dom_ext]() {
DEFINE_AND_CHECK_SELF(DomNode)

self->UpdateDiff(update_style, update_dom_ext);
self->UpdateStyle(update_style);
self->UpdateDomExt(update_dom_ext);

// update Render Node
auto dom_manager = self->dom_manager_.lock();
TDF_BASE_DCHECK(dom_manager);
if (dom_manager) {
dom_manager->UpdateRenderNode(self->shared_from_this());
}
}};
dom_manager->PostTask(Scene(std::move(ops_)));
this->UpdateDiff(update_style, update_dom_ext);
this->UpdateStyle(update_style);
this->UpdateDomExt(update_dom_ext);
dom_manager->UpdateRenderNode(shared_from_this());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,9 @@ void DoCallBack(JNIEnv *j_env, jobject j_object,
callback(std::make_shared<DomArgument>(*params));
}

void OnReceivedEvent(JNIEnv *j_env, jobject j_object,
jint j_instance_id, jint j_dom_id, jstring j_event_name,
jbyteArray j_buffer, jint j_offset, jint j_length,
jboolean j_use_capture, jboolean j_use_bubble) {
std::shared_ptr<HippyRenderManager> render_manager = HippyRenderManager::Find(
static_cast<int32_t>(j_instance_id));
void OnReceivedEvent(JNIEnv* j_env, jobject j_object, jint j_instance_id, jint j_dom_id, jstring j_event_name,
jbyteArray j_buffer, jint j_offset, jint j_length, jboolean j_use_capture, jboolean j_use_bubble) {
std::shared_ptr<HippyRenderManager> render_manager = HippyRenderManager::Find(static_cast<int32_t>(j_instance_id));
if (!render_manager) {
TDF_BASE_DLOG(WARNING) << "OnReceivedEvent j_instance_id invalid";
return;
Expand Down Expand Up @@ -224,7 +221,15 @@ void OnReceivedEvent(JNIEnv *j_env, jobject j_object,
}

jboolean is_copy = JNI_TRUE;
const char* event_name = j_env->GetStringUTFChars(j_event_name, &is_copy);
auto event = std::make_shared<DomEvent>(event_name, node,(bool) j_use_capture, (bool) j_use_bubble, params);
node->HandleEvent(event);
const char* c = j_env->GetStringUTFChars(j_event_name, &is_copy);
std::string event_name(c);

std::vector<std::function<void()>> ops = {[node = std::move(node), params = std::move(params),
use_capture = static_cast<bool>(j_use_capture),
use_bubble = static_cast<bool>(j_use_bubble),
event_name = std::move(event_name)] {
auto event = std::make_shared<DomEvent>(event_name, node, use_capture, use_bubble, params);
node->HandleEvent(event);
}};
dom_manager->PostTask(Scene(std::move(ops)));
}

0 comments on commit 31fffc4

Please sign in to comment.