Description: lazy watcher update issue

IssueNo:I40ZTY
Feature or Bugfix: Feature
Binary Source:No

Signed-off-by: jiadexiang <jiadexiang@huawei.com>
This commit is contained in:
jiadexiang
2021-07-14 21:39:37 +08:00
parent da2ed36edb
commit aadb32ba65
7 changed files with 83 additions and 33 deletions
@@ -1277,5 +1277,21 @@ bool CopyFontFamily(char *&destination, const char * const fontFamily, uint32_t
}
return true;
}
uint16_t ParseKeyIdFromJSString(const jerry_value_t str)
{
// calculate key ID
uint16_t keyId = K_UNKNOWN;
uint16_t strLength = 0;
char *keyStr = MallocStringOf(str, &strLength);
if (keyStr != nullptr) {
if (strLength != 0) {
keyId = KeyParser::ParseKeyId(keyStr, strLength);
}
ace_free(keyStr);
keyStr = nullptr;
}
return keyId;
}
} // namespace ACELite
} // namespace OHOS
+7
View File
@@ -284,6 +284,13 @@ void CureImagePath(char *&imagePath);
#endif // OHOS_ACELITE_PRODUCT_WATCH
const char *ParseImageSrc(jerry_value_t source);
/**
* @brief ParseKeyIdFromJSString parse key ID from JS value
* @param str the input JS string value
* @return the key ID
*/
uint16_t ParseKeyIdFromJSString(const jerry_value_t str);
constexpr char PATH_PREFIX[] = ".";
constexpr char PATH_DEFAULT[] = "/";
+29 -5
View File
@@ -47,9 +47,23 @@ 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());
if (component != nullptr) {
component->AddWatcherItem(firstWatcher_->GetAttrName(), firstWatcher_->GetAttrGetter(), true);
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);
}
next = const_cast<LazyLoadWatcher *>(firstWatcher_->GetNext());
delete firstWatcher_;
@@ -59,14 +73,24 @@ void LazyLoadManager::RenderLazyLoadWatcher()
state_ = LazyLoadState::DONE;
}
void LazyLoadManager::AddLazyLoadWatcher(jerry_value_t nativeElement, jerry_value_t attrName, jerry_value_t getter)
void LazyLoadManager::AddLazyLoadWatcher(jerry_value_t nativeElement,
jerry_value_t attrName,
jerry_value_t getter)
{
// pass key ID as UNKNOWN, and will be calculated out from attrName when using
AddLazyLoadWatcher(nativeElement, attrName, getter, K_UNKNOWN);
}
void LazyLoadManager::AddLazyLoadWatcher(jerry_value_t nativeElement,
jerry_value_t attrName,
jerry_value_t getter,
uint16_t keyId)
{
if (nativeElement == UNDEFINED || attrName == UNDEFINED || getter == UNDEFINED) {
return;
}
LazyLoadWatcher *watcher =
new LazyLoadWatcher(nativeElement, jerry_acquire_value(attrName), jerry_acquire_value(getter));
LazyLoadWatcher *watcher = new LazyLoadWatcher(nativeElement, attrName, getter, keyId);
if (watcher == nullptr) {
HILOG_ERROR(HILOG_MODULE_ACE, "create watcher errpr");
return;
+6 -1
View File
@@ -41,10 +41,15 @@ public:
void ResetWatchers();
/**
* @brief Cache watcher
* @brief Cache watcher, need to calculate the name key by self
*/
void AddLazyLoadWatcher(jerry_value_t nativeElement, jerry_value_t attrName, jerry_value_t getter);
/**
* @brief Cache watcher
*/
void AddLazyLoadWatcher(jerry_value_t nativeElement, jerry_value_t attrName, jerry_value_t getter, uint16_t keyId);
/**
* @brief Render watcher at next TE task
*/
@@ -16,11 +16,15 @@
#include "lazy_load_watcher.h"
namespace OHOS {
namespace ACELite {
LazyLoadWatcher::LazyLoadWatcher(jerry_value_t nativeElement, jerry_value_t attrName, jerry_value_t getter)
LazyLoadWatcher::LazyLoadWatcher(jerry_value_t nativeElement,
jerry_value_t attrName,
jerry_value_t getter,
uint16_t keyId)
: nativeElement_(nativeElement),
attrName_(attrName),
getter_(getter),
next_(nullptr)
attrName_(jerry_acquire_value(attrName)),
getter_(jerry_acquire_value(getter)),
next_(nullptr),
keyId_(keyId)
{
}
+7 -1
View File
@@ -26,7 +26,7 @@ class LazyLoadWatcher final : public MemoryHeap {
public:
ACE_DISALLOW_COPY_AND_MOVE(LazyLoadWatcher);
LazyLoadWatcher(jerry_value_t nativeElement, jerry_value_t attrName, jerry_value_t getter);
LazyLoadWatcher(jerry_value_t nativeElement, jerry_value_t attrName, jerry_value_t getter, uint16_t keyId);
~LazyLoadWatcher();
@@ -54,11 +54,17 @@ public:
{
return getter_;
}
uint16_t GetKeyId() const
{
return keyId_;
}
private:
jerry_value_t nativeElement_;
jerry_value_t attrName_;
jerry_value_t getter_;
LazyLoadWatcher *next_;
uint16_t keyId_;
};
} // namespace ACELite
} // namespace OHOS
+10 -22
View File
@@ -1020,6 +1020,7 @@ int32_t Component::GetAnimatorValue(char *animatorValue, const int8_t index, boo
jerry_value_t Component::AddWatcherItem(const jerry_value_t attrKey, const jerry_value_t attrValue, bool isLazyLoading)
{
(void)(isLazyLoading); // for lazy cases, the process is same currently
jerry_value_t options = jerry_create_object();
JerrySetNamedProperty(options, ARG_WATCH_EL, nativeElement_);
JerrySetNamedProperty(options, ARG_WATCH_ATTR, attrKey);
@@ -1032,14 +1033,8 @@ jerry_value_t Component::AddWatcherItem(const jerry_value_t attrKey, const jerry
}
// watcher is valide, insert it to the list
InsertWatcherCommon(watchersHead_, watcher);
if (isLazyLoading) {
// If the watcher creating is lazy loading, need to call watcher's update function to make sure the view
// is updated with latest value properly, because it's the lazy case, the value might be changed already.
JSRelease(JSObject::Call(watcher, "update", nullptr, 0));
return UNDEFINED;
}
// is the direct watcher creating, return the lastValue and need to be released out of this function
// return the lastValue and need to be released out of this function
return jerryx_get_property_str(watcher, "_lastValue");
}
@@ -1058,39 +1053,32 @@ void Component::ParseAttrs()
}
uint16_t length = jerry_get_array_length(attrKeys);
uint16_t attrKeyStrLength = 0;
for (uint32_t index = 0; index < length; ++index) {
jerry_value_t attrKey = jerry_get_property_by_index(attrKeys, index);
jerry_value_t attrValue = jerry_get_property(attrs, attrKey);
jerry_value_t newAttrValue = attrValue;
// calculate key ID
uint16_t attrKeyId = ParseKeyIdFromJSString(attrKey);
if (jerry_value_is_function(attrValue)) {
START_TRACING_WITH_COMPONENT_NAME(SET_ATTR_PARSE_EXPRESSION, componentName_);
#ifdef FEATURE_LAZY_LOADING_MODULE
newAttrValue = CallJSFunction(attrValue, viewModel_, nullptr, 0);
JsAppContext *context = JsAppContext::GetInstance();
LazyLoadManager *lazyLoadManager = const_cast<LazyLoadManager *>(context->GetLazyLoadManager());
lazyLoadManager->AddLazyLoadWatcher(nativeElement_, attrKey, attrValue);
lazyLoadManager->AddLazyLoadWatcher(nativeElement_, attrKey, attrValue, attrKeyId);
#else
newAttrValue = AddWatcherItem(attrKey, attrValue);
#endif
STOP_TRACING();
}
char *attrKeyStr = MallocStringOf(attrKey, &attrKeyStrLength);
if (attrKeyStr != nullptr) {
if (attrKeyStrLength != 0) {
uint16_t attrKeyId = KeyParser::ParseKeyId(attrKeyStr, attrKeyStrLength);
// ignore the return result for no need to invalided views here
START_TRACING_WITH_EXTRA_INFO(SET_ATTR_SET_TO_NATIVE, componentName_, attrKeyId);
SetAttribute(attrKeyId, newAttrValue);
STOP_TRACING();
}
ace_free(attrKeyStr);
attrKeyStr = nullptr;
if (attrKeyId != K_UNKNOWN) {
START_TRACING_WITH_EXTRA_INFO(SET_ATTR_SET_TO_NATIVE, componentName_, attrKeyId);
SetAttribute(attrKeyId, newAttrValue);
STOP_TRACING();
}
if (newAttrValue != attrValue) {
// the new value has been calculated out by ParseExpression, need to be released
// for watcher case, the attrValue is getter, and the newAttrValue is the real value
jerry_release_value(newAttrValue);
}
ReleaseJerryValue(attrKey, attrValue, VA_ARG_END_FLAG);