mirror of
https://github.com/openharmony/ace_engine_lite.git
synced 2026-07-21 00:35:30 -04:00
Description: fix lazy watcher loading issue
IssueNo:I4B9VR Feature or Bugfix: Feature Binary Source:No Signed-off-by: jiadexiang <jiadexiang@huawei.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user