From 27bb000f2b1910484db77571a3728a870c3fe871 Mon Sep 17 00:00:00 2001 From: Littlegnal <8847263+littleGnAl@users.noreply.github.com> Date: Mon, 11 Sep 2023 12:49:07 +0800 Subject: [PATCH] fix: Align web implementation to native implementation (#84) --- lib/src/iris_method_channel.dart | 8 ++- .../io/iris_method_channel_internal_io.dart | 2 +- .../iris_method_channel_interface.dart | 2 +- .../bindings/iris_api_common_bindings_js.dart | 45 +++++-------- lib/src/platform/web/iris_event_web.dart | 44 ------------ .../web/iris_method_channel_internal_web.dart | 67 +++++++++++++++---- test/iris_method_channel_test.dart | 38 ++--------- .../fake_platform_binding_delegate_web.dart | 12 +--- 8 files changed, 84 insertions(+), 134 deletions(-) delete mode 100644 lib/src/platform/web/iris_event_web.dart diff --git a/lib/src/iris_method_channel.dart b/lib/src/iris_method_channel.dart index c2fabd0..4a51b75 100644 --- a/lib/src/iris_method_channel.dart +++ b/lib/src/iris_method_channel.dart @@ -148,7 +148,7 @@ class IrisMethodChannel { IrisMethodCall(eventKey.registerName, params))); final nativeEventHandlerIntPtr = result.data['observerIntPtr']; - holder.nativeEventHandlerIntPtr = nativeEventHandlerIntPtr; + holder.eventHandlerHandle = nativeEventHandlerIntPtr; } else { result = CallApiResult(irisReturnCode: 0, data: {'result': 0}); } @@ -176,13 +176,15 @@ class IrisMethodChannel { if (holder != null) { holder.removeEventHandler(scopedEvent.handler); if (holder.getEventHandlers().isEmpty) { + final eventHandlerHandle = holder.eventHandlerHandle; + assert(eventHandlerHandle != null); return _irisMethodChannelInternal .execute(DestroyNativeEventHandlerRequest( IrisMethodCall( scopedEvent.unregisterName, params, rawBufferParams: [ - BufferParam(BufferParamHandle(holder.nativeEventHandlerIntPtr), 1) + BufferParam(BufferParamHandle(eventHandlerHandle!()), 1) ], ), )); @@ -210,7 +212,7 @@ class IrisMethodChannel { '', rawBufferParams: [ BufferParam( - BufferParamHandle(holder.nativeEventHandlerIntPtr), 1) + BufferParamHandle(holder.eventHandlerHandle!()), 1) ], )) .toList(); diff --git a/lib/src/platform/io/iris_method_channel_internal_io.dart b/lib/src/platform/io/iris_method_channel_internal_io.dart index 380bfb5..bf7fa3b 100644 --- a/lib/src/platform/io/iris_method_channel_internal_io.dart +++ b/lib/src/platform/io/iris_method_channel_internal_io.dart @@ -367,7 +367,7 @@ class _IrisMethodChannelNative { methodCall.params, rawBufferParams: [BufferParam(BufferParamHandle(eventHandlerIntPtr), 1)], )); - result.data['observerIntPtr'] = eventHandlerIntPtr; + result.data['observerIntPtr'] = IrisEventHandlerHandle(eventHandlerIntPtr); return result; } diff --git a/lib/src/platform/iris_method_channel_interface.dart b/lib/src/platform/iris_method_channel_interface.dart index 92f18b8..e9cd945 100644 --- a/lib/src/platform/iris_method_channel_interface.dart +++ b/lib/src/platform/iris_method_channel_interface.dart @@ -160,7 +160,7 @@ class EventHandlerHolder final EventHandlerHolderKey key; final Set _eventHandlers = {}; - int nativeEventHandlerIntPtr = 0; + IrisEventHandlerHandle? eventHandlerHandle; void addEventHandler(EventLoopEventHandler eventHandler) { _eventHandlers.add(eventHandler); diff --git a/lib/src/platform/web/bindings/iris_api_common_bindings_js.dart b/lib/src/platform/web/bindings/iris_api_common_bindings_js.dart index 2d9424e..914137c 100644 --- a/lib/src/platform/web/bindings/iris_api_common_bindings_js.dart +++ b/lib/src/platform/web/bindings/iris_api_common_bindings_js.dart @@ -10,10 +10,10 @@ import 'package:js/js.dart'; // ignore_for_file: public_member_api_docs, non_constant_identifier_names // NOTE: -// For compatibility to dart sdk >= 2.12, we only use the feature that are +// For compatibility to dart sdk >= 2.12, we only use the feature that are // supported in `js: 0.6.3` at this time -@JS('AgoraWrapper.EventParam') +@JS('IrisCore.EventParam') @anonymous class EventParam { // Must have an unnamed factory constructor with named arguments. @@ -42,7 +42,7 @@ IrisEventMessage toIrisEventMessage(EventParam param) { typedef ApiParam = EventParam; -@JS('AgoraWrapper.CallIrisApiResult') +@JS('IrisCore.CallIrisApiResult') @anonymous class CallIrisApiResult { external factory CallIrisApiResult({ @@ -61,39 +61,26 @@ extension CallIrisApiResultExt on CallIrisApiResult { } } -typedef IrisCEventHandler = void Function(EventParam param); - -@JS('AgoraWrapper.IrisEventHandlerHandle') +@JS('IrisCore.IrisEventHandler') @anonymous -class IrisEventHandlerHandle {} +class IrisEventHandler {} -@JS('AgoraWrapper.IrisApiEngine') +@JS('IrisCore.IrisApiEngine') @anonymous class IrisApiEngine {} -@JS('AgoraWrapper.CreateIrisApiEngine') -external IrisApiEngine CreateIrisApiEngine(); - -@JS('AgoraWrapper.DestroyIrisApiEngine') -external int DestroyIrisApiEngine(IrisApiEngine engine_ptr); +@JS('IrisCore.createIrisApiEngine') +external IrisApiEngine createIrisApiEngine(); -@JS('AgoraWrapper.CallIrisApi') -external int CallIrisApi(IrisApiEngine engine_ptr, ApiParam apiParam); +@JS('IrisCore.disposeIrisApiEngine') +external int disposeIrisApiEngine(IrisApiEngine engine_ptr); -@JS('AgoraWrapper.CallIrisApiAsync') -external Future CallIrisApiAsync( - IrisApiEngine engine_ptr, ApiParam apiParam); +@JS('IrisCore.callIrisApi') +external int callIrisApi(IrisApiEngine engine_ptr, ApiParam apiParam); -typedef IrisCEventHandlerDartCallback = void Function(EventParam param); +typedef IrisEventHandlerFuncJS = void Function(EventParam param); +typedef IrisCEventHandler = IrisEventHandlerFuncJS; -@JS('AgoraWrapper.CreateIrisEventHandler') -external IrisEventHandlerHandle CreateIrisEventHandler( +@JS('IrisCore.createIrisEventHandler') +external IrisEventHandler createIrisEventHandler( IrisCEventHandler event_handler); - -@JS('AgoraWrapper.SetIrisRtcEngineEventHandler') -external IrisEventHandlerHandle SetIrisRtcEngineEventHandler( - IrisApiEngine engine_ptr, IrisEventHandlerHandle event_handler); - -@JS('AgoraWrapper.UnsetIrisRtcEngineEventHandler') -external IrisEventHandlerHandle UnsetIrisRtcEngineEventHandler( - IrisApiEngine engine_ptr, IrisEventHandlerHandle event_handler); diff --git a/lib/src/platform/web/iris_event_web.dart b/lib/src/platform/web/iris_event_web.dart deleted file mode 100644 index 62f9644..0000000 --- a/lib/src/platform/web/iris_event_web.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:iris_method_channel/src/iris_handles.dart'; -import 'package:iris_method_channel/src/platform/iris_event_interface.dart'; -import 'package:iris_method_channel/src/platform/web/bindings/iris_api_common_bindings_js.dart' - as js; -import 'package:js/js.dart' show allowInterop; - -// ignore_for_file: public_member_api_docs - -class IrisEventWeb implements IrisEvent { - IrisEventWeb(this._irisApiEngine); - - final IrisApiEngineHandle _irisApiEngine; - - IrisEventMessageListener? _irisEventMessageListener; - - js.IrisEventHandlerHandle? _irisEventHandlerJS; - - void initialize() { - final irisCEventHandlerJS = allowInterop(_onEventFromJS); - - _irisEventHandlerJS = js.CreateIrisEventHandler(irisCEventHandlerJS); - js.SetIrisRtcEngineEventHandler( - _irisApiEngine() as js.IrisApiEngine, _irisEventHandlerJS!); - } - - void setIrisEventMessageListener(IrisEventMessageListener? listener) { - _irisEventMessageListener = listener; - } - - void _onEventFromJS(js.EventParam param) { - if (_irisEventMessageListener != null) { - _irisEventMessageListener?.call(js.toIrisEventMessage(param)); - } - } - - /// Clean up native resources - void dispose() { - js.UnsetIrisRtcEngineEventHandler( - _irisApiEngine() as js.IrisApiEngine, _irisEventHandlerJS!); - _irisEventHandlerJS = null; - - _irisEventMessageListener = null; - } -} diff --git a/lib/src/platform/web/iris_method_channel_internal_web.dart b/lib/src/platform/web/iris_method_channel_internal_web.dart index f18cbb7..f88d88b 100644 --- a/lib/src/platform/web/iris_method_channel_internal_web.dart +++ b/lib/src/platform/web/iris_method_channel_internal_web.dart @@ -1,7 +1,10 @@ import 'dart:async'; -import 'package:flutter/foundation.dart' show VoidCallback, debugPrint; +import 'dart:js'; +import 'package:flutter/foundation.dart' show VoidCallback; import 'package:iris_method_channel/iris_method_channel.dart'; -import 'package:iris_method_channel/src/platform/web/iris_event_web.dart'; + +import 'package:iris_method_channel/src/platform/web/bindings/iris_api_common_bindings_js.dart' + as js_binding; // ignore_for_file: public_member_api_docs @@ -13,10 +16,15 @@ class IrisMethodChannelInternalWeb implements IrisMethodChannelInternal { IrisMethodChannelInternalWeb(this._nativeBindingsProvider); final PlatformBindingsProvider _nativeBindingsProvider; - IrisEventWeb? _irisEventWeb; IrisApiEngineHandle? _irisApiEngine; PlatformBindingsDelegateInterface? _platformBindingsDelegate; + IrisEventMessageListener? _irisEventMessageListener; + + js_binding.IrisCEventHandler? _irisEventHandlerFuncJS; + + IrisEventHandlerHandle? _irisEventHandlerHandle; + @override VoidCallback addHotRestartListener(HotRestartListener listener) { return () {}; @@ -26,18 +34,42 @@ class IrisMethodChannelInternalWeb implements IrisMethodChannelInternal { Future dispose() async { assert(_irisApiEngine != null); - _irisEventWeb?.dispose(); - _irisEventWeb = null; - _platformBindingsDelegate?.destroyNativeApiEngine(_irisApiEngine!); + + _platformBindingsDelegate + ?.destroyIrisEventHandler(_irisEventHandlerHandle!); + _platformBindingsDelegate = null; _irisApiEngine = null; + _irisEventHandlerFuncJS = null; + _irisEventHandlerHandle = null; + _irisEventMessageListener = null; } @override Future execute(Request request) async { if (request is CreateNativeEventHandlerRequest) { - return CallApiResult(irisReturnCode: 0, data: {'observerIntPtr': 0}); + final methodCall = request.methodCall; + + await _executeMethodCall(IrisMethodCall( + methodCall.funcName, + methodCall.params, + rawBufferParams: [ + BufferParam(BufferParamHandle(_irisEventHandlerHandle!()), 1) + ], + )); + + return CallApiResult( + irisReturnCode: 0, + data: {'observerIntPtr': _irisEventHandlerHandle}, + ); + } else if (request is DestroyNativeEventHandlerRequest) { + final methodCall = request.methodCall; + if (methodCall.funcName.isEmpty) { + return CallApiResult(irisReturnCode: 0, data: {'result': 0}); + } + + return _executeMethodCall(methodCall); } else if (request is ApiCallRequest) { final IrisMethodCall methodCall = request.methodCall; return _executeMethodCall(methodCall); @@ -61,6 +93,12 @@ class IrisMethodChannelInternalWeb implements IrisMethodChannelInternal { return 0; } + void _onEventFromJS(js_binding.EventParam param) { + if (_irisEventMessageListener != null) { + _irisEventMessageListener?.call(js_binding.toIrisEventMessage(param)); + } + } + @override Future initilize(List args) async { _platformBindingsDelegate = @@ -69,10 +107,9 @@ class IrisMethodChannelInternalWeb implements IrisMethodChannelInternal { _platformBindingsDelegate!.createApiEngine(args); _irisApiEngine = createApiEngineResult.apiEnginePtr; - final irisEvent = _nativeBindingsProvider.provideIrisEvent() ?? - IrisEventWeb(_irisApiEngine!); - _irisEventWeb = irisEvent as IrisEventWeb; - _irisEventWeb!.initialize(); + _irisEventHandlerFuncJS = allowInterop(_onEventFromJS); + _irisEventHandlerHandle = _platformBindingsDelegate!.createIrisEventHandler( + IrisCEventHandlerHandle(_irisEventHandlerFuncJS!)); return InitilizationResultWeb(); } @@ -87,7 +124,11 @@ class IrisMethodChannelInternalWeb implements IrisMethodChannelInternal { results.add(result); } } else if (request is DestroyNativeEventHandlerListRequest) { - debugPrint('[listExecute] Not implemented request: $request'); + final methodCalls = request.methodCalls; + for (final methodCall in methodCalls) { + final result = await _executeMethodCall(methodCall); + results.add(result); + } } return results; @@ -98,6 +139,6 @@ class IrisMethodChannelInternalWeb implements IrisMethodChannelInternal { @override void setIrisEventMessageListener(IrisEventMessageListener listener) { - _irisEventWeb!.setIrisEventMessageListener(listener); + _irisEventMessageListener = listener; } } diff --git a/test/iris_method_channel_test.dart b/test/iris_method_channel_test.dart index a8bf004..643aa8c 100644 --- a/test/iris_method_channel_test.dart +++ b/test/iris_method_channel_test.dart @@ -118,7 +118,7 @@ void main() { final holder = subScopedObjects.values.elementAt(0) as EventHandlerHolder; - expect(holder.nativeEventHandlerIntPtr, 123456); + expect(holder.eventHandlerHandle!(), 123456); expect(holder.getEventHandlers().length, 1); expect(holder.getEventHandlers().elementAt(0), eventHandler); @@ -129,8 +129,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -169,8 +167,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -199,8 +195,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test('disposed', () async { @@ -329,8 +323,6 @@ void main() { .where((e) => e.methodCall.funcName == 'registerEventHandler'); expect(registerEventHandlerCallRecord.length, 0); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test('unregisterEventHandler after disposed', () async { @@ -416,7 +408,7 @@ void main() { final holder = subScopedObjects.values.elementAt(0) as EventHandlerHolder; - expect(holder.nativeEventHandlerIntPtr, 123456); + expect(holder.eventHandlerHandle!(), 123456); expect(holder.getEventHandlers().length, 2); expect(holder.getEventHandlers().elementAt(0), eventHandler1); @@ -428,8 +420,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -460,14 +450,14 @@ void main() { expect(subScopedObjects.keys.length, 2); final holder = subScopedObjects.values.elementAt(0) as EventHandlerHolder; - expect(holder.nativeEventHandlerIntPtr, 123456); + expect(holder.eventHandlerHandle!(), 123456); expect(holder.getEventHandlers().length, 1); expect(holder.getEventHandlers().elementAt(0), eventHandler1); final holder2 = subScopedObjects.values.elementAt(1) as EventHandlerHolder; - expect(holder2.nativeEventHandlerIntPtr, 123456); + expect(holder2.eventHandlerHandle!(), 123456); expect(holder2.getEventHandlers().length, 1); expect(holder2.getEventHandlers().elementAt(0), eventHandler2); @@ -482,8 +472,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -523,7 +511,7 @@ void main() { final holder = subScopedObjects.values.elementAt(0) as EventHandlerHolder; - expect(holder.nativeEventHandlerIntPtr, 123456); + expect(holder.eventHandlerHandle!(), 123456); expect(holder.getEventHandlers().length, 1); expect(holder.getEventHandlers().elementAt(0), eventHandler1); @@ -534,8 +522,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -575,7 +561,7 @@ void main() { final holder = subScopedObjects.values.elementAt(0) as EventHandlerHolder; - expect(holder.nativeEventHandlerIntPtr, 123456); + expect(holder.eventHandlerHandle!(), 123456); expect(holder.getEventHandlers().length, 1); expect(holder.getEventHandlers().elementAt(0), eventHandler1); @@ -591,8 +577,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -642,8 +626,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -693,8 +675,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -743,8 +723,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -782,8 +760,6 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); test( @@ -825,7 +801,5 @@ void main() { await irisMethodChannel.dispose(); }, - // On web, the `PlatformBindingsDelegateInterface`'s APIs not be called at all - skip: kIsWeb, ); } diff --git a/test/platform/fake/fake_platform_binding_delegate_web.dart b/test/platform/fake/fake_platform_binding_delegate_web.dart index bd44c95..76701dc 100644 --- a/test/platform/fake/fake_platform_binding_delegate_web.dart +++ b/test/platform/fake/fake_platform_binding_delegate_web.dart @@ -1,7 +1,6 @@ import 'dart:js' as js; import 'package:iris_method_channel/iris_method_channel.dart'; -import 'package:iris_method_channel/src/platform/web/iris_event_web.dart'; import 'platform_tester_interface.dart'; @@ -113,17 +112,8 @@ class FakeNativeBindingDelegate extends PlatformBindingsDelegateInterface { } } -class _FakeIrisEvent implements IrisEventWeb { +class _FakeIrisEvent implements IrisEvent { _FakeIrisEvent(); - - @override - void dispose() {} - - @override - void initialize() {} - - @override - void setIrisEventMessageListener(IrisEventMessageListener? listener) {} } class FakeNativeBindingDelegateProvider extends PlatformBindingsProvider {