1// Copyright 2013 The Flutter Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5part of dart.ui; 6 7/// A wrapper for a raw callback handle. 8/// 9/// This is the return type for [PluginUtilities.getCallbackHandle]. 10class CallbackHandle { 11 /// Create an instance using a raw callback handle. 12 /// 13 /// Only values produced by a call to [CallbackHandle.toRawHandle] should be 14 /// used, otherwise this object will be an invalid handle. 15 CallbackHandle.fromRawHandle(this._handle) 16 : assert(_handle != null, "'_handle' must not be null."); 17 18 final int _handle; 19 20 /// Get the raw callback handle to pass over a [MethodChannel] or [SendPort] 21 /// (to pass to another [Isolate]). 22 int toRawHandle() => _handle; 23 24 @override 25 bool operator ==(dynamic other) { 26 if (runtimeType != other.runtimeType) 27 return false; 28 final CallbackHandle typedOther = other; 29 return _handle == typedOther._handle; 30 } 31 32 @override 33 int get hashCode => _handle.hashCode; 34} 35 36/// Functionality for Flutter plugin authors. 37/// 38/// See also: 39/// 40/// * [IsolateNameServer], which provides utilities for dealing with 41/// [Isolate]s. 42class PluginUtilities { 43 // This class is only a namespace, and should not be instantiated or 44 // extended directly. 45 factory PluginUtilities._() => null; 46 47 static Map<Function, CallbackHandle> _forwardCache = 48 <Function, CallbackHandle>{}; 49 static Map<CallbackHandle, Function> _backwardCache = 50 <CallbackHandle, Function>{}; 51 52 /// Get a handle to a named top-level or static callback function which can 53 /// be easily passed between isolates. 54 /// 55 /// The `callback` argument must not be null. 56 /// 57 /// Returns a [CallbackHandle] that can be provided to 58 /// [PluginUtilities.getCallbackFromHandle] to retrieve a tear-off of the 59 /// original callback. If `callback` is not a top-level or static function, 60 /// null is returned. 61 static CallbackHandle getCallbackHandle(Function callback) { 62 assert(callback != null, "'callback' must not be null."); 63 return _forwardCache.putIfAbsent(callback, () { 64 final int handle = _getCallbackHandle(callback); 65 return handle != null ? CallbackHandle.fromRawHandle(handle) : null; 66 }); 67 } 68 69 /// Get a tear-off of a named top-level or static callback represented by a 70 /// handle. 71 /// 72 /// The `handle` argument must not be null. 73 /// 74 /// If `handle` is not a valid handle returned by 75 /// [PluginUtilities.getCallbackHandle], null is returned. Otherwise, a 76 /// tear-off of the callback associated with `handle` is returned. 77 static Function getCallbackFromHandle(CallbackHandle handle) { 78 assert(handle != null, "'handle' must not be null."); 79 return _backwardCache.putIfAbsent( 80 handle, () => _getCallbackFromHandle(handle.toRawHandle())); 81 } 82} 83