Commit bef6ff3b authored by Ian Hickson's avatar Ian Hickson

Provide more documentation for MojoShell

As usual, as I was doing this I ran into some stuff that seemed hard
to document as-is and so I changed it. In this case, in the "http"
library. The new code is more or less equivalent, I think, but the
resulting documentation makes it more obvious that it's wrong...
parent da885781
...@@ -13,13 +13,17 @@ import 'package:mojo/core.dart' as core; ...@@ -13,13 +13,17 @@ import 'package:mojo/core.dart' as core;
import 'package:mojo/mojo/service_provider.mojom.dart' as mojom; import 'package:mojo/mojo/service_provider.mojom.dart' as mojom;
import 'package:mojo/mojo/shell.mojom.dart' as mojom; import 'package:mojo/mojo/shell.mojom.dart' as mojom;
/// A replacement for shell.connectToService. Implementations should return true /// Signature for replacements for [shell.connectToService]. Implementations
/// if they handled the request, or false if the request should fall through /// should return true if they handled the request, or false if the request
/// to the default requestService. /// should fall through to the default requestService.
typedef bool OverrideConnectToService(String url, Object proxy); typedef bool OverrideConnectToService(String url, Object proxy);
/// Manages connections with embedder-provided services. /// Manages connections with embedder-provided services.
class MojoShell { class MojoShell {
/// Creates the MojoShell singleton. This constructor can only be called once.
/// If your application uses bindings, it is called by the [Services] binding.
/// (See [BindingBase] for more details on bindings. Any application using
/// the Flutter 'rendering' or 'widgets' libraries uses a binding.)
MojoShell() { MojoShell() {
assert(_instance == null); assert(_instance == null);
_instance = this; _instance = this;
...@@ -52,6 +56,8 @@ class MojoShell { ...@@ -52,6 +56,8 @@ class MojoShell {
bool get canConnectToOtherApplications => _shell != null; bool get canConnectToOtherApplications => _shell != null;
/// Attempts to connect to an application via the Mojo shell. /// Attempts to connect to an application via the Mojo shell.
///
/// Returns null if [canConnectToOtherApplications] is false.
ApplicationConnection connectToApplication(String url) { ApplicationConnection connectToApplication(String url) {
if (_shell == null) if (_shell == null)
return null; return null;
...@@ -61,13 +67,33 @@ class MojoShell { ...@@ -61,13 +67,33 @@ class MojoShell {
return new ApplicationConnection(exposedServices, services); return new ApplicationConnection(exposedServices, services);
} }
/// Set this to intercept calls to [connectToService()] and supply an /// Interceptor for calls to [connectToService] and
/// alternative implementation of a service (for example, a mock for testing). /// [connectToViewAssociatedService] so that tests can supply alternative
/// implementations of services (for example, a mock for testing).
OverrideConnectToService overrideConnectToService; OverrideConnectToService overrideConnectToService;
/// Attempts to connect to a service implementing the interface for the given proxy. /// Attempts to connect to a service implementing the interface for the given
/// If an application URL is specified, the service will be requested from that application. /// proxy. If an application URL is specified and
/// Otherwise, it will be requested from the embedder (the Flutter engine). /// [canConnectToOtherApplications] is true, the service will be requested
/// from that application. Otherwise, it will be requested from the embedder
/// (the Flutter engine).
///
/// For example, suppose there was a service of type `Foo` that was normally
/// hosted with the URL "mojo:foo" and that was also provided by the Flutter
/// embedder when there is no shell (i.e. when [canConnectToOtherApplications]
/// returns false). The following code (assuming the relevant mojom file
/// declaring `Foo` was imported with the prefix `mojom`) would connect to it,
/// and then invoke the method `bar()` on it:
///
/// ```dart
/// mojom.FooProxy foo = new mojom.FooProxy.unbound();
/// shell.connectToService("mojo:foo", foo);
/// foo.ptr.bar();
/// ```
///
/// For examples of mojom files, see the `sky_services` package.
///
/// See also [connectToViewAssociatedService].
void connectToService(String url, bindings.ProxyBase proxy) { void connectToService(String url, bindings.ProxyBase proxy) {
if (overrideConnectToService != null && overrideConnectToService(url, proxy)) if (overrideConnectToService != null && overrideConnectToService(url, proxy))
return; return;
...@@ -100,6 +126,27 @@ class MojoShell { ...@@ -100,6 +126,27 @@ class MojoShell {
} }
final mojom.ServiceProviderProxy _viewServices = _takeViewServices(); final mojom.ServiceProviderProxy _viewServices = _takeViewServices();
/// Attempts to connect to a service provided specifically for the current
/// view by the embedder or host platform.
///
/// For example, keyboard services are specific to a view; you can only
/// receive keyboard input when the application's view is the one with focus.
///
/// For example, suppose there was a service of type `Foo` that was provided
/// on a view-by-view basis by the embedder or host platform. The following
/// code (assuming the relevant mojom file declaring `Foo` was imported with
/// the prefix `mojom`) would connect to it, and then invoke the method
/// `bar()` on it:
///
/// ```dart
/// mojom.FooProxy foo = new mojom.FooProxy.unbound();
/// shell.connectToViewAssociatedService(foo);
/// foo.ptr.bar();
/// ```
///
/// For examples of mojom files, see the `sky_services` package.
///
/// See also [connectToService].
void connectToViewAssociatedService(bindings.ProxyBase proxy) { void connectToViewAssociatedService(bindings.ProxyBase proxy) {
if (overrideConnectToService != null && overrideConnectToService(null, proxy)) if (overrideConnectToService != null && overrideConnectToService(null, proxy))
return; return;
...@@ -111,6 +158,21 @@ class MojoShell { ...@@ -111,6 +158,21 @@ class MojoShell {
} }
/// Registers a service to expose to the embedder. /// Registers a service to expose to the embedder.
///
/// For example, suppose a Flutter application wanted to provide a service
/// `Foo` to the embedder, that a mojom file declaring `Foo` was imported with
/// the prefix `mojom`, that `package:mojo/core.dart` was imported with the
/// prefix `core`, and that an implementation of the `Foo` service existed in
/// the class `MyFooImplementation`. The following code, run during the
/// binding initialization (i.e. during the same call stack as the call to the
/// [new MojoShell] constructor) would achieve this:
///
/// ```dart
/// shell.provideService(mojom.Foo.serviceName, (core.MojoMessagePipeEndpoint endpoint) {
/// mojom.FooStub foo = new mojom.FooStub.fromEndpoint(endpoint);
/// foo.impl = new MyFooImplementation();
/// });
/// ```
void provideService(String interfaceName, ServiceFactory factory) { void provideService(String interfaceName, ServiceFactory factory) {
_embedderConnection?.provideService(interfaceName, factory); _embedderConnection?.provideService(interfaceName, factory);
} }
......
...@@ -19,6 +19,7 @@ enum AnimationStatus { ...@@ -19,6 +19,7 @@ enum AnimationStatus {
completed, completed,
} }
/// Signature for listeners attached using [Animation.addStatusListener].
typedef void AnimationStatusListener(AnimationStatus status); typedef void AnimationStatusListener(AnimationStatus status);
/// An animation with a value of type T /// An animation with a value of type T
...@@ -36,8 +37,12 @@ typedef void AnimationStatusListener(AnimationStatus status); ...@@ -36,8 +37,12 @@ typedef void AnimationStatusListener(AnimationStatus status);
/// To create a new animation that you can run forward and backward, consider /// To create a new animation that you can run forward and backward, consider
/// using [AnimationController]. /// using [AnimationController].
abstract class Animation<T> { abstract class Animation<T> {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Animation(); const Animation();
// keep these next five dartdocs in sync with the dartdocs in AnimationWithParentMixin<T>
/// Calls the listener every time the value of the animation changes. /// Calls the listener every time the value of the animation changes.
void addListener(VoidCallback listener); void addListener(VoidCallback listener);
...@@ -66,6 +71,21 @@ abstract class Animation<T> { ...@@ -66,6 +71,21 @@ abstract class Animation<T> {
String toString() { String toString() {
return '$runtimeType(${toStringDetails()})'; return '$runtimeType(${toStringDetails()})';
} }
/// Provides a string describing the status of this object, but not including
/// information about the object itself.
///
/// This function is used by [Animation.toString] so that [Animation]
/// subclasses can provide additional details while ensuring all [Animation]
/// subclasses have a consistent [toString] style.
///
/// The result of this function includes an icon describing the status of this
/// [Animation] object:
///
/// * "&#x25B6;": [AnimationStatus.forward] ([value] increasing)
/// * "&#x25C0;": [AnimationStatus.reverse] ([value] decreasing)
/// * "&#x23ED;": [AnimationStatus.completed] ([value] == 1.0)
/// * "&#x23EE;": [AnimationStatus.dismissed] ([value] == 0.0)
String toStringDetails() { String toStringDetails() {
assert(status != null); assert(status != null);
String icon; String icon;
......
...@@ -109,6 +109,13 @@ class AnimationController extends Animation<double> ...@@ -109,6 +109,13 @@ class AnimationController extends Animation<double>
@override @override
double get value => _value; double get value => _value;
double _value; double _value;
/// Stops the animation controller and sets the current value of the
/// animation.
///
/// The new value is clamped to the range set by [lowerBound] and [upperBound].
///
/// Value listeners are notified even if this does not change the value.
/// Status listeners are notified if the animation was previously playing.
void set value(double newValue) { void set value(double newValue) {
assert(newValue != null); assert(newValue != null);
stop(); stop();
......
...@@ -67,7 +67,16 @@ class _AlwaysDismissedAnimation extends Animation<double> { ...@@ -67,7 +67,16 @@ class _AlwaysDismissedAnimation extends Animation<double> {
const Animation<double> kAlwaysDismissedAnimation = const _AlwaysDismissedAnimation(); const Animation<double> kAlwaysDismissedAnimation = const _AlwaysDismissedAnimation();
/// An animation that is always stopped at a given value. /// An animation that is always stopped at a given value.
///
/// The [status] is always [AnimationStatus.forward].
class AlwaysStoppedAnimation<T> extends Animation<T> { class AlwaysStoppedAnimation<T> extends Animation<T> {
/// Creates an [AlwaysStoppedAnimation] with the given value.
///
/// Since the [value] and [status] of an [AlwaysStoppedAnimation] can never
/// change, the listeners can never be invoked. It is therefore safe to reuse
/// an [AlwaysStoppedAnimation] instance in multiple places. If the [value] to
/// be used is known at compile time, the constructor should be invoked as a
/// `const` constructor.
const AlwaysStoppedAnimation(this.value); const AlwaysStoppedAnimation(this.value);
@override @override
...@@ -96,15 +105,25 @@ abstract class AnimationWithParentMixin<T> { ...@@ -96,15 +105,25 @@ abstract class AnimationWithParentMixin<T> {
/// The animation whose value this animation will proxy. /// The animation whose value this animation will proxy.
/// ///
/// This animation must remain the same for the lifetime of this object. If /// This animation must remain the same for the lifetime of this object. If
/// you wish to proxy a different animation at different times, conside using /// you wish to proxy a different animation at different times, consider using
/// [ProxyAnimation]. /// [ProxyAnimation].
Animation<T> get parent; Animation<T> get parent;
// keep these next five dartdocs in sync with the dartdocs in Animation<T>
/// Calls the listener every time the value of the animation changes.
void addListener(VoidCallback listener) => parent.addListener(listener); void addListener(VoidCallback listener) => parent.addListener(listener);
/// Stop calling the listener every time the value of the animation changes.
void removeListener(VoidCallback listener) => parent.removeListener(listener); void removeListener(VoidCallback listener) => parent.removeListener(listener);
/// Calls listener every time the status of the animation changes.
void addStatusListener(AnimationStatusListener listener) => parent.addStatusListener(listener); void addStatusListener(AnimationStatusListener listener) => parent.addStatusListener(listener);
/// Stops calling the listener every time the status of the animation changes.
void removeStatusListener(AnimationStatusListener listener) => parent.removeStatusListener(listener); void removeStatusListener(AnimationStatusListener listener) => parent.removeStatusListener(listener);
/// The current status of this animation.
AnimationStatus get status => parent.status; AnimationStatus get status => parent.status;
} }
......
...@@ -16,6 +16,8 @@ const double _kCubicErrorBound = 0.001; ...@@ -16,6 +16,8 @@ const double _kCubicErrorBound = 0.001;
/// ///
/// See [Curves] for a collection of common animation curves. /// See [Curves] for a collection of common animation curves.
abstract class Curve { abstract class Curve {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Curve(); const Curve();
/// Returns the value of the curve at point [t]. /// Returns the value of the curve at point [t].
......
...@@ -8,6 +8,8 @@ export 'package:newton/newton.dart' show SpringDescription; ...@@ -8,6 +8,8 @@ export 'package:newton/newton.dart' show SpringDescription;
/// A factory for simulations. /// A factory for simulations.
abstract class Force { abstract class Force {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Force(); const Force();
/// Creates a new physics simulation with the given initial conditions. /// Creates a new physics simulation with the given initial conditions.
......
...@@ -10,6 +10,8 @@ import 'curves.dart'; ...@@ -10,6 +10,8 @@ import 'curves.dart';
/// An object that can produce a value of type T given an [Animation] as input. /// An object that can produce a value of type T given an [Animation] as input.
abstract class Animatable<T> { abstract class Animatable<T> {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Animatable(); const Animatable();
/// The current value of this object for the given animation. /// The current value of this object for the given animation.
......
...@@ -148,8 +148,7 @@ class MojoClient { ...@@ -148,8 +148,7 @@ class MojoClient {
mojo.UrlResponse response = (await loader.ptr.start(request)).response; mojo.UrlResponse response = (await loader.ptr.start(request)).response;
ByteData data = await mojo.DataPipeDrainer.drainHandle(response.body); ByteData data = await mojo.DataPipeDrainer.drainHandle(response.body);
Uint8List bodyBytes = new Uint8List.view(data.buffer); Uint8List bodyBytes = new Uint8List.view(data.buffer);
String bodyString = new String.fromCharCodes(bodyBytes); return new Response(bodyBytes: bodyBytes, statusCode: response.statusCode);
return new Response(body: bodyString, bodyBytes: bodyBytes, statusCode: response.statusCode);
} catch (e) { } catch (e) {
print("NetworkService unavailable $e"); print("NetworkService unavailable $e");
return new Response(statusCode: 500); return new Response(statusCode: 500);
...@@ -170,5 +169,6 @@ class MojoClient { ...@@ -170,5 +169,6 @@ class MojoClient {
return proxy; return proxy;
} }
/// A handle to the [NetworkService] object used by [MojoClient].
static final mojo.NetworkServiceProxy networkService = _initNetworkService(); static final mojo.NetworkServiceProxy networkService = _initNetworkService();
} }
...@@ -6,8 +6,25 @@ import 'dart:typed_data'; ...@@ -6,8 +6,25 @@ import 'dart:typed_data';
/// An HTTP response where the entire response body is known in advance. /// An HTTP response where the entire response body is known in advance.
class Response { class Response {
const Response({ this.body, this.bodyBytes, this.statusCode }); /// Creates a [Response] object with the given fields.
///
/// If [bodyBytes] is non-null, it is used to populate [body].
Response({
Uint8List bodyBytes,
this.statusCode
}) : body = bodyBytes != null ? new String.fromCharCodes(bodyBytes) : null,
bodyBytes = bodyBytes;
/// The result of decoding [bodyBytes] using ISO-8859-1.
///
/// If [bodyBytes] is null, this will also be null.
final String body; final String body;
/// The raw byte stream.
final Uint8List bodyBytes; final Uint8List bodyBytes;
/// The HTTP result code.
///
/// The code 500 is used when no status code could be obtained from the host.
final int statusCode; final int statusCode;
} }
...@@ -246,6 +246,8 @@ class BoxShadow { ...@@ -246,6 +246,8 @@ class BoxShadow {
/// A 2D gradient. /// A 2D gradient.
abstract class Gradient { abstract class Gradient {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Gradient(); const Gradient();
Shader createShader(Rect rect); Shader createShader(Rect rect);
} }
......
...@@ -19,7 +19,8 @@ export 'edge_insets.dart' show EdgeInsets; ...@@ -19,7 +19,8 @@ export 'edge_insets.dart' show EdgeInsets;
/// shared between boxes; [BoxPainter] objects can cache resources to /// shared between boxes; [BoxPainter] objects can cache resources to
/// make painting on a particular surface faster. /// make painting on a particular surface faster.
abstract class Decoration { abstract class Decoration {
/// Abstract const constructor. /// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Decoration(); const Decoration();
/// In checked mode, throws an exception if the object is not in a /// In checked mode, throws an exception if the object is not in a
......
...@@ -114,6 +114,8 @@ class AutoLayoutParentData extends ContainerBoxParentDataMixin<RenderBox> { ...@@ -114,6 +114,8 @@ class AutoLayoutParentData extends ContainerBoxParentDataMixin<RenderBox> {
} }
abstract class AutoLayoutDelegate { abstract class AutoLayoutDelegate {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const AutoLayoutDelegate(); const AutoLayoutDelegate();
List<al.Constraint> getConstraints(AutoLayoutRect parent); List<al.Constraint> getConstraints(AutoLayoutRect parent);
......
...@@ -356,6 +356,8 @@ abstract class RenderObjectPainter { ...@@ -356,6 +356,8 @@ abstract class RenderObjectPainter {
/// Concrete layout models (such as box) will create concrete subclasses to /// Concrete layout models (such as box) will create concrete subclasses to
/// communicate layout constraints between parents and children. /// communicate layout constraints between parents and children.
abstract class Constraints { abstract class Constraints {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Constraints(); const Constraints();
/// Whether there is exactly one size possible given these constraints /// Whether there is exactly one size possible given these constraints
......
...@@ -1300,6 +1300,8 @@ class RenderFractionalTranslation extends RenderProxyBox { ...@@ -1300,6 +1300,8 @@ class RenderFractionalTranslation extends RenderProxyBox {
} }
abstract class CustomPainter { abstract class CustomPainter {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const CustomPainter(); const CustomPainter();
void paint(Canvas canvas, Size size); void paint(Canvas canvas, Size size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment