!370 解决if指令变更早于lazy watcher加载时所产生的lazy watcher概率性UI错乱问题

Merge pull request !370 from piggyguy_jdx/fix_lazy_watcher_dirty_issue_release
This commit is contained in:
openharmony_ci
2021-09-24 03:02:10 +00:00
committed by Gitee
5 changed files with 79 additions and 57 deletions
+65 -38
View File
@@ -21,7 +21,7 @@
namespace OHOS {
namespace ACELite {
LazyLoadManager::LazyLoadManager() : firstWatcher_(nullptr), lastWatcher_(nullptr), state_(LazyLoadState::INIT)
LazyLoadManager::LazyLoadManager() : state_(LazyLoadState::INIT)
{
}
@@ -32,47 +32,57 @@ LazyLoadManager::~LazyLoadManager()
void LazyLoadManager::ResetWatchers()
{
LazyLoadWatcher *next = nullptr;
while (firstWatcher_ != nullptr) {
next = const_cast<LazyLoadWatcher *>(firstWatcher_->GetNext());
delete firstWatcher_;
firstWatcher_ = next;
ListNode<LazyLoadWatcher *> *node = lazyWatchersList_.Begin();
while (node != lazyWatchersList_.End()) {
if (node->data_ != nullptr) {
delete node->data_;
node->data_ = nullptr;
}
node = node->next_;
}
lastWatcher_ = nullptr;
lazyWatchersList_.Clear();
state_ = LazyLoadState::INIT;
}
void LazyLoadManager::RenderLazyLoadWatcher()
{
LazyLoadWatcher *next = nullptr;
while (firstWatcher_ != nullptr) {
jerry_value_t attrName = firstWatcher_->GetAttrName();
jerry_value_t attrGetter = firstWatcher_->GetAttrGetter();
uint16_t attrKeyID = firstWatcher_->GetKeyId();
Component *component = ComponentUtils::GetComponentFromBindingObject(firstWatcher_->GetNativeElement());
jerry_value_t latestValue =
(component == nullptr) ? UNDEFINED : component->AddWatcherItem(attrName, attrGetter, true);
if (attrKeyID == K_UNKNOWN) {
// try to parse from attr name directly
attrKeyID = ParseKeyIdFromJSString(attrName);
ListNode<LazyLoadWatcher *> *node = lazyWatchersList_.Begin();
while (node != lazyWatchersList_.End()) {
if (node->data_ != nullptr) {
// handle it
RenderSingleLazyWatcher(*(node->data_));
delete node->data_;
node->data_ = nullptr;
}
if ((!IS_UNDEFINED(latestValue)) && (attrKeyID != K_UNKNOWN)) {
// need to update the view with the latest value, in case the value is already changed
if (component->UpdateView(attrKeyID, latestValue)) {
component->Invalidate();
}
// the new value has been calculated out by ParseExpression, need to be released
jerry_release_value(latestValue);
}
next = const_cast<LazyLoadWatcher *>(firstWatcher_->GetNext());
delete firstWatcher_;
firstWatcher_ = next;
node = node->next_;
}
lastWatcher_ = nullptr;
lazyWatchersList_.Clear();
state_ = LazyLoadState::DONE;
}
void LazyLoadManager::RenderSingleLazyWatcher(const LazyLoadWatcher &watcher) const
{
jerry_value_t attrName = watcher.GetAttrName();
jerry_value_t attrGetter = watcher.GetAttrGetter();
uint16_t attrKeyID = watcher.GetKeyId();
Component *component = ComponentUtils::GetComponentFromBindingObject(watcher.GetNativeElement());
jerry_value_t latestValue =
(component == nullptr) ? UNDEFINED : component->AddWatcherItem(attrName, attrGetter, true);
if (attrKeyID == K_UNKNOWN) {
// try to parse from attr name directly
attrKeyID = ParseKeyIdFromJSString(attrName);
}
if ((!IS_UNDEFINED(latestValue)) && (attrKeyID != K_UNKNOWN)) {
// need to update the view with the latest value, in case the value is already changed
if (component->UpdateView(attrKeyID, latestValue)) {
component->Invalidate();
}
}
// the new value has been calculated out by ParseExpression, need to be released
jerry_release_value(latestValue);
}
void LazyLoadManager::AddLazyLoadWatcher(jerry_value_t nativeElement,
jerry_value_t attrName,
jerry_value_t getter)
@@ -95,16 +105,33 @@ void LazyLoadManager::AddLazyLoadWatcher(jerry_value_t nativeElement,
HILOG_ERROR(HILOG_MODULE_ACE, "create watcher errpr");
return;
}
if (firstWatcher_ == nullptr) {
firstWatcher_ = watcher;
lastWatcher_ = watcher;
} else {
lastWatcher_->SetNext(*watcher);
lastWatcher_ = watcher;
}
lazyWatchersList_.PushBack(watcher);
// The state must be ready if any watcher lazy loading request was added, otherwise, in some cases,
// the js_ability may not be able to know there are watchers need to be loaded.
state_ = LazyLoadState::READY;
}
void LazyLoadManager::RemoveLazyWatcher(jerry_value_t nativeElement)
{
if (lazyWatchersList_.IsEmpty()) {
return;
}
ListNode<LazyLoadWatcher *> *node = lazyWatchersList_.Begin();
while (node != lazyWatchersList_.End()) {
if (node->data_ == nullptr) {
node = node->next_;
continue;
}
if (node->data_->GetNativeElement() == nativeElement) {
// found, remove the node
delete node->data_;
node->data_ = nullptr;
node = lazyWatchersList_.Remove(node);
continue;
}
node = node->next_;
}
}
} // namespace ACELite
} // namespace OHOS
+8 -7
View File
@@ -16,6 +16,7 @@
#ifndef OHOS_ACELITE_LAZY_LOAD_MANAGER_H
#define OHOS_ACELITE_LAZY_LOAD_MANAGER_H
#include "gfx_utils/list.h"
#include "lazy_load_watcher.h"
#include "non_copyable.h"
@@ -50,16 +51,16 @@ public:
*/
void AddLazyLoadWatcher(jerry_value_t nativeElement, jerry_value_t attrName, jerry_value_t getter, uint16_t keyId);
/**
* @brief Remove one lazy watcher from pending list by native element value
*/
void RemoveLazyWatcher(jerry_value_t nativeElement);
/**
* @brief Render watcher at next TE task
*/
void RenderLazyLoadWatcher();
const LazyLoadWatcher *GetLazyWatcher() const
{
return firstWatcher_;
}
void SetState(LazyLoadState state)
{
state_ = state;
@@ -70,8 +71,8 @@ public:
return state_;
}
private:
LazyLoadWatcher *firstWatcher_;
LazyLoadWatcher *lastWatcher_;
void RenderSingleLazyWatcher(const LazyLoadWatcher &watcher) const;
List<LazyLoadWatcher *> lazyWatchersList_;
LazyLoadState state_;
};
} // namespace ACELite
@@ -23,7 +23,6 @@ LazyLoadWatcher::LazyLoadWatcher(jerry_value_t nativeElement,
: nativeElement_(nativeElement),
attrName_(jerry_acquire_value(attrName)),
getter_(jerry_acquire_value(getter)),
next_(nullptr),
keyId_(keyId)
{
}
@@ -30,16 +30,6 @@ public:
~LazyLoadWatcher();
void SetNext(LazyLoadWatcher &next)
{
next_ = &next;
}
const LazyLoadWatcher *GetNext() const
{
return next_;
}
jerry_value_t GetNativeElement() const
{
return nativeElement_;
@@ -63,7 +53,6 @@ private:
jerry_value_t nativeElement_;
jerry_value_t attrName_;
jerry_value_t getter_;
LazyLoadWatcher *next_;
uint16_t keyId_;
};
} // namespace ACELite
@@ -183,6 +183,12 @@ void Component::Release()
{
// detach self from fatal handler monitoring
FatalHandler::GetInstance().DetachComponentNode(this);
#ifdef FEATURE_LAZY_LOADING_MODULE
// detach from lazy pending list
JsAppContext *context = JsAppContext::GetInstance();
LazyLoadManager *lazyLoadManager = const_cast<LazyLoadManager *>(context->GetLazyLoadManager());
lazyLoadManager->RemoveLazyWatcher(nativeElement_);
#endif // FEATURE_LAZY_LOADING_MODULE
if (parent_ != nullptr) {
parent_->RemoveChild(this);
}