Skip to content

Commit

Permalink
fix: fix native intersection observer entry.
Browse files Browse the repository at this point in the history
  • Loading branch information
andycall committed Oct 16, 2024
1 parent 9b9a702 commit 96870df
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 64 deletions.
38 changes: 24 additions & 14 deletions bridge/core/dom/intersection_observer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,22 @@
#include <algorithm>
#include <limits>

#include "core/dom/element.h"
#include <native_value_converter.h>
#include "bindings/qjs/converter_impl.h"
#include "core/dom/element.h"
#include "core/dom/intersection_observer_entry.h"
#include "core/dom/node.h"
#include "core/executing_context.h"
#include "qjs_intersection_observer_init.h"
#include "foundation/logging.h"
#include "foundation/native_value_converter.h"
#include "qjs_intersection_observer_init.h"

namespace webf {

struct NativeIntersectionObserverEntry : public DartReadable {
int8_t is_intersecting;
NativeBindingObject* target;
};

IntersectionObserver* IntersectionObserver::Create(ExecutingContext* context,
const std::shared_ptr<QJSFunction>& function,
ExceptionState& exception_state) {
Expand Down Expand Up @@ -105,28 +110,33 @@ NativeValue IntersectionObserver::HandleCallFromDartSide(const AtomicString& met
int32_t argc,
const NativeValue* argv,
Dart_Handle dart_object) {
if (!GetExecutingContext() || !GetExecutingContext()->IsContextValid()) {
if (!GetExecutingContext() || !GetExecutingContext()->IsContextValid()) {
WEBF_LOG(ERROR) << "[IntersectionObserver]: HandleCallFromDartSide Context Valid" << std::endl;
return Native_NewNull();
}

MemberMutationScope scope{GetExecutingContext()};
WEBF_LOG(DEBUG) << "[IntersectionObserver]: HandleCallFromDartSide NativeValueConverter" << std::endl;
NativeValue native_entry_list = argv[0];
std::vector<IntersectionObserverEntry*> entries =
NativeValueConverter<NativeTypeArray<NativeTypePointer<IntersectionObserverEntry>>>::FromNativeValue(
ctx(), native_entry_list);
NativeIntersectionObserverEntry* native_entry =
NativeValueConverter<NativeTypePointer<NativeIntersectionObserverEntry>>::FromNativeValue(argv[0]);
size_t length = NativeValueConverter<NativeTypeInt64>::FromNativeValue(argv[1]);

if (!entries.empty()) {
if (length > 0) {
assert(function_ != nullptr);

WEBF_LOG(DEBUG) << "[IntersectionObserver]: HandleCallFromDartSide To JSValue" << std::endl;
JSValue v = Converter<IDLSequence<IntersectionObserverEntry>>::ToValue(ctx(), entries);
ScriptValue arguments[] = {ScriptValue(ctx(), v), ToValue()};

JS_FreeValue(ctx(), v);
JSValue js_array = JS_NewArray(ctx());
for (int i = 0; i < length; i++) {
auto* entry = MakeGarbageCollected<IntersectionObserverEntry>(
GetExecutingContext(), native_entry[i].is_intersecting,
DynamicTo<Element>(BindingObject::From(native_entry[i].target)));
JS_SetPropertyUint32(ctx(), js_array, i, entry->ToQuickJS());
}
ScriptValue arguments[] = {ScriptValue(ctx(), js_array), ToValue()};

WEBF_LOG(DEBUG) << "[IntersectionObserver]: HandleCallFromDartSide function_ Invoke" << std::endl;
function_->Invoke(ctx(), ToValue(), 2, arguments);

JS_FreeValue(ctx(), js_array);
} else {
WEBF_LOG(ERROR) << "[IntersectionObserver]: HandleCallFromDartSide entries is empty";
}
Expand Down
51 changes: 23 additions & 28 deletions webf/lib/src/dom/intersection_observer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class _IntersectionObserverDeliverContext {

// Pointer<NativeValue> method;
Pointer<NativeValue> allocatedNativeArguments;

//Pointer<NativeValue> rawNativeEntries;
WebFController controller;
EvaluateOpItem? profileOp;
Expand All @@ -33,7 +34,8 @@ class _IntersectionObserverDeliverContext {
);
}

void _handleDeliverResult(_IntersectionObserverDeliverContext context, Pointer<NativeValue> returnValue) {
void _handleDeliverResult(Object handle, Pointer<NativeValue> returnValue) {
_IntersectionObserverDeliverContext context = handle as _IntersectionObserverDeliverContext;
Pointer<EventDispatchResult> dispatchResult =
fromNativeValue(context.controller.view, returnValue).cast<EventDispatchResult>();

Expand Down Expand Up @@ -99,35 +101,17 @@ class IntersectionObserver extends DynamicBindingObject {
_entries.add(entry);
}

List<NativeIntersectionObserverEntry> takeRecords() {
List<DartIntersectionObserverEntry> takeRecords() {
List<DartIntersectionObserverEntry> entries = _entries.map((entry) => entry.copy()).toList();
_entries.clear();
return toNativeEntries(entries);
}

List<NativeIntersectionObserverEntry> toNativeEntries(List<DartIntersectionObserverEntry> entries) {
if (entries.isEmpty) {
return [];
}

return List.generate(entries.length, (i) {
return NativeIntersectionObserverEntry(
BindingContext(
entries[i].element.ownerView,
entries[i].element.ownerView.contextId,
allocateNewBindingObject(),
),
entries[i].isIntersecting,
entries[i].element,
);
});
return entries;
}

Future<void> deliver(WebFController controller) async {
if (pointer == null) return;
debugPrint('Dom.IntersectionObserver.deliver pointer:$pointer');
List<NativeIntersectionObserverEntry> nativeEntries = takeRecords();
if (nativeEntries.isNotEmpty) {
List<DartIntersectionObserverEntry> entries = takeRecords();
if (entries.isNotEmpty) {
Completer completer = Completer();

EvaluateOpItem? currentProfileOp;
Expand All @@ -139,16 +123,26 @@ class IntersectionObserver extends DynamicBindingObject {
// Call methods implements at C++ side.
DartInvokeBindingMethodsFromDart? f = pointer!.ref.invokeBindingMethodFromDart.asFunction();

// Pointer<NativeValue> method = malloc.allocate(sizeOf<NativeValue>());
// toNativeValue(method, 'deliver');

List<dynamic> dispatchEntryArguments = [nativeEntries];

Stopwatch? stopwatch;
if (enableWebFCommandLog) {
stopwatch = Stopwatch()..start();
}

// Allocate an chunk of memory for an list of NativeIntersectionObserverEntry
Pointer<NativeIntersectionObserverEntry> head =
malloc.allocate(sizeOf<NativeIntersectionObserverEntry>() * entries.length);

// Write the native memory from dart objects.
for(int i = 0; i < entries.length; i ++) {
(head + i).ref.isIntersecting = entries[i].isIntersecting ? 1 : 0;
(head + i).ref.target = entries[i].element.pointer!;
}

List<dynamic> dispatchEntryArguments = [
head,
entries.length
];

Pointer<NativeValue> allocatedNativeArguments = makeNativeValueArguments(bindingObject, dispatchEntryArguments);

_IntersectionObserverDeliverContext context = _IntersectionObserverDeliverContext(
Expand All @@ -167,6 +161,7 @@ class IntersectionObserver extends DynamicBindingObject {
// Pointer<NativeFunction<NativeInvokeResultCallback>> result_callback);
f(pointer!, currentProfileOp?.hashCode ?? 0, nullptr, dispatchEntryArguments.length, allocatedNativeArguments,
context, resultCallback);
malloc.free(head);
});

return completer.future;
Expand Down
28 changes: 6 additions & 22 deletions webf/lib/src/dom/intersection_observer_entry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* Copyright (C) 2022-present The WebF authors. All rights reserved.
*/

import 'package:webf/foundation.dart';
import 'dart:ffi';
import 'package:webf/bridge.dart';
import 'element.dart';

class DartIntersectionObserverEntry {
Expand All @@ -24,26 +25,9 @@ class DartIntersectionObserverEntry {
}
}

class NativeIntersectionObserverEntry extends DynamicBindingObject {
//final DOMHighResTimeStamp time;
//final DOMRectReadOnly? rootBounds;
//final DOMRectReadOnly boundingClientRect;
//final DOMRectReadOnly intersectionRect;
final bool isIntersecting;

//final bool isVisible;
//final double intersectionRatio;
final Element target;

NativeIntersectionObserverEntry(BindingContext context, this.isIntersecting, this.target) : super(context);
class NativeIntersectionObserverEntry extends Struct {
@Int8()
external int isIntersecting;

@override
void initializeMethods(Map<String, BindingObjectMethod> methods) {
// TODO: implement initializeMethods
}

@override
void initializeProperties(Map<String, BindingObjectProperty> properties) {
// TODO: implement initializeProperties
}
external Pointer<NativeBindingObject> target;
}

0 comments on commit 96870df

Please sign in to comment.