LCOV - code coverage report
Current view: top level - infrastructure/services - callback_controller.service.dart (source / functions) Hit Total Coverage
Test: new_lcov.info Lines: 39 51 76.5 %
Date: 2022-02-05 16:49:32 Functions: 0 0 -

          Line data    Source code
       1             : part of './services.nativechannels.dart';
       2             : 
       3             : /// Manage our channels instances and listeners by [actionMethod]
       4             : /// callback registered.
       5             : class CallBacksController implements ICallBacksController {
       6             :   static const String _tag = 'CallBacksController';
       7             : 
       8             :   /// CallBackMethod<T>
       9             :   /// here we can't use this.
      10             :   final _callbacks = <CallBackMethod<MirrorMethodCall, Error>>{};
      11             : 
      12           6 :   static final CallBacksController _singleton = CallBacksController._internal();
      13             : 
      14           2 :   factory CallBacksController() {
      15           2 :     return _singleton;
      16             :   }
      17             : 
      18           2 :   CallBacksController._internal();
      19             : 
      20             :   int _nextCallbackId = 0;
      21             : 
      22           2 :   int get lastAddedCallbackId => _nextCallbackId;
      23             : 
      24           1 :   @override
      25           2 :   int get registeredCallbacksCount => _callbacks.length;
      26             : 
      27             :   @override
      28           1 :   Future<dynamic> callBackMethodHandlerSetup(MethodCall call) async {
      29             :     try {
      30           2 :       if (_callbacks.isEmpty) {
      31             :         // throw Exception('No callback registered.');
      32             :         // TODO(v): maybe there is a delay between hosts callbacks invoke
      33           0 :         log('SUPOSE TO: \nthrow Exception(\'No callback registered.\');',
      34             :             level: 2000);
      35           0 :         return Future.value('[Platform info]: No callback registered.');
      36             :       }
      37             : 
      38           1 :       switch (call.method) {
      39           1 :         case PlatformEntrypoint.setupMethodHandler:
      40           1 :         case PlatformEntrypoint.callBackMethodHandler:
      41           2 :           Message message = Message.fromBuffer(call.arguments);
      42             : 
      43           3 :           if (message.header.communicationType ==
      44             :               Header_CommunicationType.CANCELATION) {
      45           3 :             disposeCallBack(message.header.callBackId);
      46             :             break;
      47             :           }
      48             : 
      49           2 :           int id = message.header.callBackId;
      50             : 
      51           1 :           if (id == 0) {
      52           0 :             throw Exception('Invalid [callback id] value.');
      53             :           }
      54             : 
      55             :           /// On this case we can call a global dispose on host.
      56             :           /// Means that there are more instances inside our native channel.
      57           5 :           if (!_callbacks.any((e) => e.id == id)) {
      58             :             // TODO(v): maybe there is a delay between hosts callbacks invoke
      59           0 :             log('SUPOSE TO: \nthrow Exception(\'Invalid [callback id]. Is this callback disposed?\');',
      60             :                 level: 2000);
      61           0 :             return Future.value('[Platform info]: callback id not found');
      62             :             // throw Exception(
      63             :             //     'Invalid [callback id]. Is this callback disposed?');
      64             :           }
      65             : 
      66             :           final dynamicMethod =
      67           5 :               _callbacks.firstWhere((element) => element.id == id);
      68             : 
      69             :           // TODO(v): function references doesn't throw explicit runtime exceptions on message.apply
      70             :           // final arguments = await message.apply();
      71             : 
      72           2 :           dynamicMethod.call(
      73           1 :             message.methodCall,
      74           2 :             message.payload.error,
      75             :           );
      76             : 
      77             :           break;
      78             :         default:
      79           0 :           log('CallBacksController, callBackMethodHandlerSetup -> IGNORING: ${call.method}');
      80             :           break;
      81             :       }
      82             :     } catch (e, s) {
      83           0 :       log('CallBacksController, callBackMethodHandlerSetup\n$call',
      84             :           name: _tag, stackTrace: s, error: e);
      85             :       rethrow;
      86             :     }
      87             :   }
      88             : 
      89           1 :   @override
      90             :   bool isAlreadyRegistered({required String actionMethod}) =>
      91           2 :       _callbacks.any((e) => e.message.header.actionMethod == actionMethod);
      92             : 
      93             :   /// If [listenerCancelation] method is provided
      94             :   /// It will dispose the current [actionMethod] listener.
      95             :   /// Can be used like a [restart] on our actual callback listener,
      96             :   /// and avoid duplicated listeners.
      97           1 :   Future<void> disposeActiveCallbackListener({
      98             :     required String actionMethod,
      99             :     required CancelListening Function(Message msg) listenerCancelation,
     100             :   }) async {
     101             :     CallBackMethod<dynamic, dynamic> callBack;
     102             : 
     103             :     try {
     104           1 :       callBack = _callbacks
     105           6 :           .firstWhere((e) => e.message.header.actionMethod == actionMethod);
     106           1 :     } on StateError catch (_) {
     107             :       return;
     108           0 :     } on Exception catch (e, s) {
     109           0 :       log('disposeActiveCallbackListener:',
     110             :           name: _tag, stackTrace: s, error: e);
     111             :       rethrow;
     112             :     }
     113             : 
     114             :     try {
     115           6 :       await listenerCancelation.call(callBack.message).call().then((_) {
     116           2 :         disposeCallBack(callBack.id);
     117             :       });
     118             :     } catch (e, s) {
     119           0 :       log('CancelListening, listenerCancelation\n',
     120             :           name: _tag, stackTrace: s, error: e);
     121           0 :       throw Exception('CancelListening listenerCancelation() fail.');
     122             :     }
     123             :   }
     124             : 
     125             :   /// If call [setCallBack] to a [actionMethod] already registered,
     126             :   /// then will dispose the actual callback listener before continue.
     127           1 :   @override
     128             :   void setCallBack({
     129             :     required CallBackMethod<MirrorMethodCall, Error> call,
     130             :   }) {
     131           4 :     if (isAlreadyRegistered(actionMethod: call.message.header.actionMethod)) {
     132           0 :       throw Exception(
     133             :           'actionMethod: [call.message.header.actionMethod] already registered.');
     134             :     }
     135             : 
     136           2 :     _nextCallbackId++;
     137             : 
     138           4 :     call.message.header.callBackId = _nextCallbackId;
     139             : 
     140           2 :     _callbacks.add(call);
     141             : 
     142           6 :     log('CallBacksController, setCallBack -> $_nextCallbackId : ${call.message.header.actionMethod}');
     143             :   }
     144             : 
     145           1 :   @override
     146             :   void disposeCallBack(int callBackId) {
     147           2 :     log('CallBacksController, disposeCallBack -> $callBackId');
     148           7 :     _callbacks.removeWhere((e) => e.message.header.callBackId == callBackId);
     149             :   }
     150             : }

Generated by: LCOV version 1.15