mirror of
https://github.com/openharmony/ace_engine_lite.git
synced 2026-07-21 00:35:30 -04:00
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:
@@ -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
|
||||
|
||||
@@ -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[] = "/";
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user