| 1 |  |  | import 'package:meta/meta.dart'; | 
                
                
                    | 2 |  |  |  | 
                
                
                    | 3 |  |  | import '../_impl/xplat/_internal_logger.dart'; | 
                
                
                    | 4 |  |  | import '../_impl/xplat/_time_stamp.dart'; | 
                
                
                    | 5 |  |  | import '../exceptions/squadron_error.dart'; | 
                
                
                    | 6 |  |  | import '../tokens/_squadron_cancelation_token.dart'; | 
                
                
                    | 7 |  |  | import '../typedefs.dart'; | 
                
                
                    | 8 |  |  | import 'worker.dart'; | 
                
                
                    | 9 |  |  | import 'worker_channel.dart'; | 
                
                
                    | 10 |  |  | import 'worker_message.dart'; | 
                
                
                    | 11 |  |  |  | 
                
                
                    | 12 |  |  | /// [WorkerRequest]s are used to communicate from a client to a [Worker]. | 
                
                
                    | 13 |  |  | /// Typically a [WorkerRequest] consists of a command ID and a list of | 
                
                
                    | 14 |  |  | /// arguments. The [command] ID is used by the [Worker] to dispatch the | 
                
                
                    | 15 |  |  | /// [WorkerRequest] to the method responsible for handling it. | 
                
                
                    | 16 |  |  | /// The command's arguments are passed as a list and should only contain | 
                
                
                    | 17 |  |  | /// primitive values or objects that can be transfered across workers. For | 
                
                
                    | 18 |  |  | /// applications running on a VM platform, Dart objects should be safe | 
                
                
                    | 19 |  |  | /// according to Dart's documentation of [SendPort.send]. [WorkerRequestImpl] | 
                
                
                    | 20 |  |  | /// also implements specific requests used for worker startup, stream/token | 
                
                
                    | 21 |  |  | /// cancelation, worker termination... | 
                
                
                    | 22 |  |  | extension type WorkerRequest._(List data) implements WorkerMessage { | 
                
                
                    | 23 |  |  |   /// Creates a new request with the specified [command] ID and optional arguments. | 
                
                
                    | 24 |  | 10 |   static WorkerRequest userCommand(PlatformChannel channelInfo, int command, | 
                
                
                    | 25 |  |  |           List args, SquadronCancelationToken? token, bool inspectResponse) => | 
                
                
                    | 26 |  | 20 |       WorkerRequest._([ | 
                
                
                    | 27 |  | 10 |         microsecTimeStamp(), // 0 - travel time | 
                
                
                    | 28 |  |  |         channelInfo, // 1 - channel | 
                
                
                    | 29 |  |  |         command, // 2 - command | 
                
                
                    | 30 |  |  |         args, // 3 - args | 
                
                
                    | 31 |  |  |         token, // 4 - cancelation token | 
                
                
                    | 32 |  |  |         null, // 5 - stream id | 
                
                
                    | 33 |  |  |         inspectResponse, // 6 - inspect response | 
                
                
                    | 34 |  |  |       ]); | 
                
                
                    | 35 |  |  |  | 
                
                
                    | 36 |  |  |   /// Creates a new start request. | 
                
                
                    | 37 |  | 11 |   static WorkerRequest start(PlatformChannel channelInfo, List args) => | 
                
                
                    | 38 |  | 22 |       WorkerRequest._([ | 
                
                
                    | 39 |  | 11 |         microsecTimeStamp(), // 0 - travel time | 
                
                
                    | 40 |  |  |         channelInfo, // 1 - channel | 
                
                
                    | 41 |  |  |         _connectCommand, // 2 - command | 
                
                
                    | 42 |  |  |         args, // 3 - args | 
                
                
                    | 43 |  |  |         null, // 4 - cancelation token | 
                
                
                    | 44 |  |  |         null, // 5 - stream id | 
                
                
                    | 45 |  |  |         true, // 6 - inspect response | 
                
                
                    | 46 |  |  |       ]); | 
                
                
                    | 47 |  |  |  | 
                
                
                    | 48 |  |  |   /// Creates a new stream cancelation request. | 
                
                
                    | 49 |  | 12 |   static WorkerRequest cancelStream(int streamId) => WorkerRequest._([ | 
                
                
                    | 50 |  | 4 |         microsecTimeStamp(), // 0 - travel time | 
                
                
                    | 51 |  |  |         null, // 1 - channel | 
                
                
                    | 52 |  |  |         _cancelStreamCommand, // 2 - command | 
                
                
                    | 53 |  |  |         null, // 3 - args | 
                
                
                    | 54 |  |  |         null, // 4 - cancelation token | 
                
                
                    | 55 |  |  |         streamId, // 5 - stream id | 
                
                
                    | 56 |  |  |         null, // 6 - inspect response | 
                
                
                    | 57 |  |  |       ]); | 
                
                
                    | 58 |  |  |  | 
                
                
                    | 59 |  |  |   /// Creates a new cancelation request. | 
                
                
                    | 60 |  | 2 |   static WorkerRequest cancel(SquadronCancelationToken token) => | 
                
                
                    | 61 |  | 4 |       WorkerRequest._([ | 
                
                
                    | 62 |  | 2 |         microsecTimeStamp(), // 0 - travel time | 
                
                
                    | 63 |  |  |         null, // 1 - channel | 
                
                
                    | 64 |  |  |         _cancelTokenCommand, // 2 - command | 
                
                
                    | 65 |  |  |         null, // 3 - args | 
                
                
                    | 66 |  |  |         token, // 4 - cancelation token | 
                
                
                    | 67 |  |  |         null, // 5 - stream id | 
                
                
                    | 68 |  |  |         null, // 6 - inspect response | 
                
                
                    | 69 |  |  |       ]); | 
                
                
                    | 70 |  |  |  | 
                
                
                    | 71 |  |  |   /// Creates a new termination request. | 
                
                
                    | 72 |  | 30 |   static WorkerRequest stop() => WorkerRequest._([ | 
                
                
                    | 73 |  | 10 |         microsecTimeStamp(), // 0 - travel time | 
                
                
                    | 74 |  |  |         null, // 1 - channel | 
                
                
                    | 75 |  |  |         _terminateCommand, // 2 - command | 
                
                
                    | 76 |  |  |         null, // 3 - args | 
                
                
                    | 77 |  |  |         null, // 4 - cancelation token | 
                
                
                    | 78 |  |  |         null, // 5 - stream id | 
                
                
                    | 79 |  |  |         null, // 6 - inspect response | 
                
                
                    | 80 |  |  |       ]); | 
                
                
                    | 81 |  |  |  | 
                
                
                    | 82 |  |  |   /// The client's [WorkerChannel]. Only valid on the receiving end. | 
                
                
                    | 83 |  | 20 |   WorkerChannel? get channel => data[_$channel]; | 
                
                
                    | 84 |  |  |  | 
                
                
                    | 85 |  |  |   /// The channel method to be used for sending data back. | 
                
                
                    | 86 |  | 10 |   void Function(dynamic)? get reply => | 
                
                
                    | 87 |  | 34 |       inspectResponse ? channel?.inspectAndReply : channel?.reply; | 
                
                
                    | 88 |  |  |  | 
                
                
                    | 89 |  |  |   /// The client's channel info. | 
                
                
                    | 90 |  | 0 |   PlatformChannel? get channelInfo => data[_$channel]; | 
                
                
                    | 91 |  |  |  | 
                
                
                    | 92 |  |  |   /// Cancelation token. | 
                
                
                    | 93 |  | 20 |   SquadronCancelationToken? get cancelToken => data[_$token]; | 
                
                
                    | 94 |  |  |  | 
                
                
                    | 95 |  |  |   /// Stream id. | 
                
                
                    | 96 |  | 8 |   int? get streamId => data[_$streamId]; | 
                
                
                    | 97 |  |  |  | 
                
                
                    | 98 |  |  |   /// The [command]'s ID. | 
                
                
                    | 99 |  | 20 |   int get command => data[_$command]; | 
                
                
                    | 100 |  |  |  | 
                
                
                    | 101 |  |  |   /// The command's arguments, if any. | 
                
                
                    | 102 |  | 20 |   List get args => data[_$args]; | 
                
                
                    | 103 |  |  |  | 
                
                
                    | 104 |  |  |   /// Flag indicating whether the Channel should inspect the payload to identify non-base type objects. In | 
                
                
                    | 105 |  |  |   /// Web Workers, ownership of these objects must be transfered across threads. | 
                
                
                    | 106 |  | 20 |   bool get inspectResponse => data[_$inspectResponse]; | 
                
                
                    | 107 |  |  |  | 
                
                
                    | 108 |  |  |   /// flag for start requests. | 
                
                
                    | 109 |  | 30 |   bool get isConnection => (command == _connectCommand); | 
                
                
                    | 110 |  |  |  | 
                
                
                    | 111 |  |  |   /// flag for stream cancelation requests. | 
                
                
                    | 112 |  | 30 |   bool get isStreamCancelation => (command == _cancelStreamCommand); | 
                
                
                    | 113 |  |  |  | 
                
                
                    | 114 |  |  |   /// flag for cancelation requests. | 
                
                
                    | 115 |  | 30 |   bool get isTokenCancelation => (command == _cancelTokenCommand); | 
                
                
                    | 116 |  |  |  | 
                
                
                    | 117 |  |  |   /// flag for termination requests. | 
                
                
                    | 118 |  | 30 |   bool get isTermination => (command == _terminateCommand); | 
                
                
                    | 119 |  |  |  | 
                
                
                    | 120 |  |  |   static const int _connectCommand = -1; | 
                
                
                    | 121 |  |  |   static const int _cancelStreamCommand = -2; | 
                
                
                    | 122 |  |  |   static const int _cancelTokenCommand = -3; | 
                
                
                    | 123 |  |  |   static const int _terminateCommand = -4; | 
                
                
                    | 124 |  |  | } | 
                
                
                    | 125 |  |  |  | 
                
                
                    | 126 |  |  | // 0 is reserved for travel time | 
                
                
                    | 127 |  |  | const _$channel = 1; | 
                
                
                    | 128 |  |  | const _$command = 2; | 
                
                
                    | 129 |  |  | const _$args = 3; | 
                
                
                    | 130 |  |  | const _$token = 4; | 
                
                
                    | 131 |  |  | const _$streamId = 5; | 
                
                
                    | 132 |  |  | const _$inspectResponse = 6; | 
                
                
                    | 133 |  |  |  | 
                
                
                    | 134 |  |  | @internal | 
                
                
                    | 135 |  |  | extension WorkerRequestExt on WorkerRequest { | 
                
                
                    | 136 |  |  |   /// In-place deserialization of a [WorkerRequest] received by the worker. | 
                
                
                    | 137 |  | 10 |   void unwrapInPlace(InternalLogger? logger) { | 
                
                
                    | 138 |  | 10 |     unwrapTravelTime(); | 
                
                
                    | 139 |  | 30 |     data[_$command] = (data[_$command] as num).toInt(); | 
                
                
                    | 140 |  | 24 |     data[_$streamId] = (data[_$streamId] as num?)?.toInt(); | 
                
                
                    | 141 |  | 30 |     data[_$channel] = WorkerChannel.deserialize(data[_$channel], logger); | 
                
                
                    | 142 |  | 30 |     data[_$token] = SquadronCancelationToken.deserialize(data[_$token]); | 
                
                
                    | 143 |  | 10 |     data[_$inspectResponse] ??= false; | 
                
                
                    | 144 |  | 10 |     data[_$args] ??= const []; | 
                
                
                    | 145 |  |  |   } | 
                
                
                    | 146 |  |  |  | 
                
                
                    | 147 |  |  |   /// In-place serialization of a [WorkerRequest]. | 
                
                
                    | 148 |  | 11 |   List wrapInPlace() { | 
                
                
                    | 149 |  | 11 |     final token = data[_$token]; | 
                
                
                    | 150 |  | 11 |     if (token is SquadronCancelationToken) { | 
                
                
                    | 151 |  | 4 |       data[_$token] = token.serialize(); | 
                
                
                    | 152 |  |  |     } | 
                
                
                    | 153 |  |  |     return data; | 
                
                
                    | 154 |  |  |   } | 
                
                
                    | 155 |  |  |  | 
                
                
                    | 156 |  | 10 |   static WorkerRequest from(List data) { | 
                
                
                    | 157 |  | 20 |     if (data.length != 7) { | 
                
                
                    | 158 |  | 0 |       throw SquadronErrorImpl.create('Invalid worker request'); | 
                
                
                    | 159 |  |  |     } | 
                
                
                    | 160 |  | 10 |     return WorkerRequest._(data); | 
                
                
                    | 161 |  |  |   } | 
                
                
                    | 162 |  |  | } | 
                
                
                    | 163 |  |  |  | 
                
                
                    | 164 |  |  | @internal | 
                
                
                    | 165 |  |  | extension CancelationTokenExt on WorkerRequest { | 
                
                
                    | 166 |  | 2 |   void overrideCancelToken(SquadronCancelationToken token) { | 
                
                
                    | 167 |  | 10 |     if (cancelToken == null || cancelToken!.id != token.id) { | 
                
                
                    | 168 |  | 0 |       throw SquadronErrorImpl.create('Cancelation token mismatch'); | 
                
                
                    | 169 |  |  |     } | 
                
                
                    | 170 |  | 2 |     data[_$token] = token; | 
                
                
                    | 171 |  |  |   } | 
                
                
                    | 172 |  |  | } |