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;
import 'package:mojo/mojo/service_provider.mojom.dart' as mojom;
import 'package:mojo/mojo/shell.mojom.dart' as mojom;
/// A replacement for shell.connectToService. Implementations should return true
/// if they handled the request, or false if the request should fall through
/// to the default requestService.
/// Signature for replacements for [shell.connectToService]. Implementations
/// should return true if they handled the request, or false if the request
/// should fall through to the default requestService.
typedef bool OverrideConnectToService(String url, Object proxy);
/// Manages connections with embedder-provided services.
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() {
assert(_instance == null);
_instance = this;
......@@ -52,6 +56,8 @@ class MojoShell {
bool get canConnectToOtherApplications => _shell != null;
/// Attempts to connect to an application via the Mojo shell.
///
/// Returns null if [canConnectToOtherApplications] is false.
ApplicationConnection connectToApplication(String url) {
if (_shell == null)
return null;
......@@ -61,13 +67,33 @@ class MojoShell {
return new ApplicationConnection(exposedServices, services);
}
/// Set this to intercept calls to [connectToService()] and supply an
/// alternative implementation of a service (for example, a mock for testing).
/// Interceptor for calls to [connectToService] and
/// [connectToViewAssociatedService] so that tests can supply alternative
/// implementations of services (for example, a mock for testing).
OverrideConnectToService overrideConnectToService;
/// Attempts to connect to a service implementing the interface for the given proxy.
/// If an application URL is specified, the service will be requested from that application.
/// Otherwise, it will be requested from the embedder (the Flutter engine).
/// Attempts to connect to a service implementing the interface for the given
/// proxy. If an application URL is specified and
/// [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) {
if (overrideConnectToService != null && overrideConnectToService(url, proxy))
return;
......@@ -100,6 +126,27 @@ class MojoShell {
}
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) {
if (overrideConnectToService != null && overrideConnectToService(null, proxy))
return;
......@@ -111,6 +158,21 @@ class MojoShell {
}
/// 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) {
_embedderConnection?.provideService(interfaceName, factory);
}
......
......@@ -19,6 +19,7 @@ enum AnimationStatus {
completed,
}
/// Signature for listeners attached using [Animation.addStatusListener].
typedef void AnimationStatusListener(AnimationStatus status);
/// An animation with a value of type T
......@@ -36,8 +37,12 @@ typedef void AnimationStatusListener(AnimationStatus status);
/// To create a new animation that you can run forward and backward, consider
/// using [AnimationController].
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();
// keep these next five dartdocs in sync with the dartdocs in AnimationWithParentMixin<T>
/// Calls the listener every time the value of the animation changes.
void addListener(VoidCallback listener);
......@@ -66,6 +71,21 @@ abstract class Animation<T> {
String toString() {
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() {
assert(status != null);
String icon;
......
......@@ -109,6 +109,13 @@ class AnimationController extends Animation<double>
@override
double get value => _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) {
assert(newValue != null);
stop();
......
......@@ -67,7 +67,16 @@ class _AlwaysDismissedAnimation extends Animation<double> {
const Animation<double> kAlwaysDismissedAnimation = const _AlwaysDismissedAnimation();
/// An animation that is always stopped at a given value.
///
/// The [status] is always [AnimationStatus.forward].
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);
@override
......@@ -96,15 +105,25 @@ abstract class AnimationWithParentMixin<T> {
/// The animation whose value this animation will proxy.
///
/// 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].
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);
/// Stop calling the listener every time the value of the animation changes.
void removeListener(VoidCallback listener) => parent.removeListener(listener);
/// Calls listener every time the status of the animation changes.
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);
/// The current status of this animation.
AnimationStatus get status => parent.status;
}
......
......@@ -16,6 +16,8 @@ const double _kCubicErrorBound = 0.001;
///
/// See [Curves] for a collection of common animation curves.
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();
/// Returns the value of the curve at point [t].
......
......@@ -8,6 +8,8 @@ export 'package:newton/newton.dart' show SpringDescription;
/// A factory for simulations.
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();
/// Creates a new physics simulation with the given initial conditions.
......
......@@ -10,6 +10,8 @@ import 'curves.dart';
/// An object that can produce a value of type T given an [Animation] as input.
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();
/// The current value of this object for the given animation.
......
......@@ -148,8 +148,7 @@ class MojoClient {
mojo.UrlResponse response = (await loader.ptr.start(request)).response;
ByteData data = await mojo.DataPipeDrainer.drainHandle(response.body);
Uint8List bodyBytes = new Uint8List.view(data.buffer);
String bodyString = new String.fromCharCodes(bodyBytes);
return new Response(body: bodyString, bodyBytes: bodyBytes, statusCode: response.statusCode);
return new Response(bodyBytes: bodyBytes, statusCode: response.statusCode);
} catch (e) {
print("NetworkService unavailable $e");
return new Response(statusCode: 500);
......@@ -170,5 +169,6 @@ class MojoClient {
return proxy;
}
/// A handle to the [NetworkService] object used by [MojoClient].
static final mojo.NetworkServiceProxy networkService = _initNetworkService();
}
......@@ -6,8 +6,25 @@ import 'dart:typed_data';
/// An HTTP response where the entire response body is known in advance.
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;
/// The raw byte stream.
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;
}
......@@ -246,6 +246,8 @@ class BoxShadow {
/// A 2D 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();
Shader createShader(Rect rect);
}
......
......@@ -19,7 +19,8 @@ export 'edge_insets.dart' show EdgeInsets;
/// shared between boxes; [BoxPainter] objects can cache resources to
/// make painting on a particular surface faster.
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();
/// In checked mode, throws an exception if the object is not in a
......
......@@ -114,6 +114,8 @@ class AutoLayoutParentData extends ContainerBoxParentDataMixin<RenderBox> {
}
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();
List<al.Constraint> getConstraints(AutoLayoutRect parent);
......
......@@ -356,6 +356,8 @@ abstract class RenderObjectPainter {
/// Concrete layout models (such as box) will create concrete subclasses to
/// communicate layout constraints between parents and children.
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();
/// Whether there is exactly one size possible given these constraints
......
......@@ -1300,6 +1300,8 @@ class RenderFractionalTranslation extends RenderProxyBox {
}
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();
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