blob: 810d7c22222316db4d04c74f7fce186ca260d2f0 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:math' show Random;
import 'package:flutter/material.dart';
import 'package:lib.app_driver.dart/module_driver.dart';
import 'package:lib.logging/logging.dart';
import 'package:lib.widgets.dart/model.dart'
show ScopedModel, ScopedModelDescendant;
import 'package:lib.schemas.dart/com.fuchsia.color.dart';
import 'src/color_model.dart';
/// The amount of time between color updates.
const Duration _kUpdateDuration = const Duration(seconds: 5);
/// Used to translate raw Entity data into structured values.
final ColorEntityCodec _kColorCodec = new ColorEntityCodec();
/// Main entry point to the color module.
void main() {
setupLogger(
name: 'color',
);
/// The [ColorModel] holds UI state and automatically triggers a re-render of
/// Flutter's widget tree when attributes are updated.
ColorModel model = new ColorModel();
/// The [ModuleDriver] provides an idiomatic Dart API encapsulating
/// boilerplate and book keeping required for FIDL service interactions.
ModuleDriver module = new ModuleDriver();
/// Use [ColorEntity#watch] to access a stream of change events for the
/// 'color' Link's Entity updates. Since this module updates it's own Entity
/// value the `all` param is set to true.
module.watch('color', _kColorCodec, all: true).listen(
(ColorEntityData data) => model.color = new Color(data.value),
cancelOnError: true,
onError: handleError,
onDone: () => log.info('update stream closed'),
);
/// When the module is ready (listeners and async event listeners have been
/// added etc.) it is connected to the Fuchsia's application framework via
/// [module#start()]. When a module is "started" it is expressly stating it is
/// in a state to handle incoming requests from the framework to it's
/// underlying interfaces (Module, Lifecycle, etc.) and that it is in a
/// position to handling UI rendering and input.
module.start().then(handleStart, onError: handleError);
runApp(new ScopedModel<ColorModel>(
model: model,
child: new ScopedModelDescendant<ColorModel>(
builder: (BuildContext context, Widget child, ColorModel model) {
return new Container(color: model.color);
},
),
));
}
/// Generic error handler.
// TODO(SO-1123): hook up to a snackbar.
void handleError(Error error, StackTrace stackTrace) {
log.severe('An error ocurred', error, stackTrace);
}
///
void handleStart(ModuleDriver module) {
/// Once the module is ready to interact with the rest of the system,
/// periodically update the color value stored in the Link that the module was
/// started with.
log.info('module ready, link values will periodically update');
final Random rand = new Random();
/// Change the [entity]'s value to a random color periodically.
new Timer.periodic(_kUpdateDuration, (_) async {
ColorEntityData value = new ColorEntityData(
value: (new Color.fromRGBO(
rand.nextInt(255), // red
rand.nextInt(255), // green
rand.nextInt(255), // red
1.0)
.value));
return module.put('color', value, _kColorCodec).then(
(String ref) => log.fine('updated entity: $ref'),
onError: handleError);
});
}