From b357aa32ecada885b27f18ce3763934282d62e81 Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 5 May 2016 12:09:23 -0700 Subject: [PATCH 1/7] More docs for PerformanceOverlay (#3749) Fixes #3747 --- .../flutter/lib/src/widgets/performance_overlay.dart | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/flutter/lib/src/widgets/performance_overlay.dart b/packages/flutter/lib/src/widgets/performance_overlay.dart index 0205071471f..d4cdb215403 100644 --- a/packages/flutter/lib/src/widgets/performance_overlay.dart +++ b/packages/flutter/lib/src/widgets/performance_overlay.dart @@ -7,6 +7,18 @@ import 'package:flutter/rendering.dart'; import 'framework.dart'; /// Displays performance statistics. +/// +/// The overlay show two time series. The first shows how much time was required +/// on this thread to produce each frame. The second shows how much time was +/// required on the GPU thread to produce each frame. Ideally, both these values +/// would be less than the total frame budget for the hardware on which the app +/// is running. For example, if the hardware has a screen that updates at 60 Hz, +/// each thread should ideally spend less than 16 ms producing each frame. This +/// ideal condition is indicated by a green vertical line for each thread. +/// +/// The simplest way to show the performance overlay is to set +/// [MaterialApp.showPerformanceOverlay] or [WidgetsApp.showPerformanceOverlay] +/// to `true`. class PerformanceOverlay extends LeafRenderObjectWidget { // TODO(abarth): We should have a page on the web site with a screenshot and // an explanation of all the various readouts. From 2592f8f4b6fdf6b2062d918a142c2e87a75a14bf Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 5 May 2016 12:09:29 -0700 Subject: [PATCH 2/7] DropDownMenu should use ScrollableList (#3745) Previously it used Block, which is less efficient for large numbers of items. Also move the top margin out of the menu item to fix the baseline alignment of the text. Fixes #1615 --- .../flutter/lib/src/material/drop_down.dart | 55 +++++++++---------- .../flutter/test/material/drop_down_test.dart | 8 +++ 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/packages/flutter/lib/src/material/drop_down.dart b/packages/flutter/lib/src/material/drop_down.dart index a727b97aacf..376eb34f66a 100644 --- a/packages/flutter/lib/src/material/drop_down.dart +++ b/packages/flutter/lib/src/material/drop_down.dart @@ -28,7 +28,6 @@ class _DropDownMenuPainter extends CustomPainter { _DropDownMenuPainter({ Color color, int elevation, - this.buttonRect, this.selectedIndex, Animation resize }) : color = color, @@ -43,7 +42,6 @@ class _DropDownMenuPainter extends CustomPainter { final Color color; final int elevation; - final Rect buttonRect; final int selectedIndex; final Animation resize; @@ -52,12 +50,12 @@ class _DropDownMenuPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final Tween top = new Tween( - begin: (selectedIndex * buttonRect.height + _kMenuVerticalPadding.top).clamp(0.0, size.height - buttonRect.height), + begin: (selectedIndex * _kMenuItemHeight + _kMenuVerticalPadding.top).clamp(0.0, size.height - _kMenuItemHeight), end: 0.0 ); final Tween bottom = new Tween( - begin: (top.begin + buttonRect.height).clamp(buttonRect.height, size.height), + begin: (top.begin + _kMenuItemHeight).clamp(_kMenuItemHeight, size.height), end: size.height ); @@ -68,7 +66,6 @@ class _DropDownMenuPainter extends CustomPainter { bool shouldRepaint(_DropDownMenuPainter oldPainter) { return oldPainter.color != color || oldPainter.elevation != elevation - || oldPainter.buttonRect != buttonRect || oldPainter.selectedIndex != selectedIndex || oldPainter.resize != resize; } @@ -130,7 +127,6 @@ class _DropDownMenu extends StatusTransitionWidget { painter: new _DropDownMenuPainter( color: Theme.of(context).canvasColor, elevation: route.elevation, - buttonRect: route.buttonRect, selectedIndex: route.selectedIndex, resize: new CurvedAnimation( parent: route.animation, @@ -140,8 +136,9 @@ class _DropDownMenu extends StatusTransitionWidget { ), child: new Material( type: MaterialType.transparency, - child: new Block( + child: new ScrollableList( padding: _kMenuVerticalPadding, + itemExtent: _kMenuItemHeight, children: children ) ) @@ -162,10 +159,11 @@ class _DropDownMenuRouteLayout extends SingleChildLayoutDelegate { // the view height. This ensures a tappable area outside of the simple menu // with which to dismiss the menu. // -- https://www.google.com/design/spec/components/menus.html#menus-simple-menus - final double maxHeight = math.max(0.0, constraints.maxHeight - 2 * buttonRect.height); + final double maxHeight = math.max(0.0, constraints.maxHeight - 2 * _kMenuItemHeight); + final double width = buttonRect.width; return new BoxConstraints( - minWidth: buttonRect.width, - maxWidth: buttonRect.width, + minWidth: width, + maxWidth: width, minHeight: 0.0, maxHeight: maxHeight ); @@ -173,14 +171,15 @@ class _DropDownMenuRouteLayout extends SingleChildLayoutDelegate { @override Offset getPositionForChild(Size size, Size childSize) { - double top = buttonRect.top - selectedIndex * buttonRect.height - _kMenuVerticalPadding.top; - double topPreferredLimit = buttonRect.height; + final double buttonTop = buttonRect.top; + double top = buttonTop - selectedIndex * _kMenuItemHeight - _kMenuVerticalPadding.top; + double topPreferredLimit = _kMenuItemHeight; if (top < topPreferredLimit) - top = math.min(buttonRect.top, topPreferredLimit); + top = math.min(buttonTop, topPreferredLimit); double bottom = top + childSize.height; - double bottomPreferredLimit = size.height - buttonRect.height; + double bottomPreferredLimit = size.height - _kMenuItemHeight; if (bottom > bottomPreferredLimit) { - bottom = math.max(buttonRect.bottom, bottomPreferredLimit); + bottom = math.max(buttonTop + _kMenuItemHeight, bottomPreferredLimit); top = bottom - childSize.height; } assert(top >= 0.0); @@ -277,7 +276,7 @@ class DropDownMenuItem extends StatelessWidget { Widget build(BuildContext context) { return new Container( height: _kMenuItemHeight, - padding: const EdgeInsets.only(left: 8.0, right: 8.0, top: _kTopMargin), + padding: const EdgeInsets.symmetric(horizontal: 8.0), child: new DefaultTextStyle( style: Theme.of(context).textTheme.subhead, child: new Baseline( @@ -363,7 +362,7 @@ class DropDownButton extends StatefulWidget { } class _DropDownButtonState extends State> { - final GlobalKey indexedStackKey = new GlobalKey(debugLabel: 'DropDownButton.IndexedStack'); + final GlobalKey _itemKey = new GlobalKey(debugLabel: 'DropDownButton item key'); @override void initState() { @@ -390,13 +389,13 @@ class _DropDownButtonState extends State> { } void _handleTap() { - final RenderBox renderBox = indexedStackKey.currentContext.findRenderObject(); - final Rect buttonRect = renderBox.localToGlobal(Point.origin) & renderBox.size; + final RenderBox itemBox = _itemKey.currentContext.findRenderObject(); + final Rect itemRect = itemBox.localToGlobal(Point.origin) & itemBox.size; final Completer<_DropDownRouteResult> completer = new Completer<_DropDownRouteResult>(); Navigator.push(context, new _DropDownRoute( completer: completer, items: config.items, - buttonRect: _kMenuHorizontalPadding.inflateRect(buttonRect), + buttonRect: _kMenuHorizontalPadding.inflateRect(itemRect), selectedIndex: _selectedIndex, elevation: config.elevation )); @@ -412,27 +411,27 @@ class _DropDownButtonState extends State> { Widget build(BuildContext context) { assert(debugCheckHasMaterial(context)); Widget result = new Row( + mainAxisAlignment: MainAxisAlignment.collapse, children: [ + // We use an IndexedStack to make sure we have enough width to show any + // possible item as the selected item without changing size. new IndexedStack( children: config.items, - key: indexedStackKey, + key: _itemKey, index: _selectedIndex, alignment: FractionalOffset.topCenter ), - new Container( - child: new Icon(icon: Icons.arrow_drop_down, size: 36.0), - padding: const EdgeInsets.only(top: _kTopMargin) - ) - ], - mainAxisAlignment: MainAxisAlignment.collapse + new Icon(icon: Icons.arrow_drop_down, size: 36.0) + ] ); if (DropDownButtonHideUnderline.at(context)) { result = new Padding( - padding: const EdgeInsets.only(bottom: _kBottomBorderHeight), + padding: const EdgeInsets.only(top: _kTopMargin, bottom: _kBottomBorderHeight), child: result ); } else { result = new Container( + padding: const EdgeInsets.only(top: _kTopMargin), decoration: const BoxDecoration(border: _kDropDownUnderline), child: result ); diff --git a/packages/flutter/test/material/drop_down_test.dart b/packages/flutter/test/material/drop_down_test.dart index 3555940c379..f48d6a7ce63 100644 --- a/packages/flutter/test/material/drop_down_test.dart +++ b/packages/flutter/test/material/drop_down_test.dart @@ -38,6 +38,14 @@ void main() { tester.pump(); tester.pump(const Duration(seconds: 1)); // finish the menu animation + // We should have two copies of item 5, one in the menu and one in the + // button itself. + expect(find.text('5').evaluate().length, 2); + + // We should only have one copy of item 19, which is in the button itself. + // The copy in the menu shouldn't be in the tree because it's off-screen. + expect(find.text('19').evaluate().length, 1); + tester.tap(find.byConfig(button)); // Ideally this would be 4 because the menu would be overscrolled to the From a9993664823dc18693f15fd89d9fc0411ec5fbe4 Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Thu, 5 May 2016 14:26:21 -0700 Subject: [PATCH 3/7] remove the analyze --benhcmark-expected option (#3755) --- .../lib/src/commands/analyze.dart | 18 ++---------------- packages/flutter_tools/lib/src/device.dart | 2 +- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/packages/flutter_tools/lib/src/commands/analyze.dart b/packages/flutter_tools/lib/src/commands/analyze.dart index ef1fc65aa30..be5078a4e86 100644 --- a/packages/flutter_tools/lib/src/commands/analyze.dart +++ b/packages/flutter_tools/lib/src/commands/analyze.dart @@ -118,15 +118,8 @@ class AnalyzeCommand extends FlutterCommand { argParser.addFlag('watch', help: 'Run analysis continuously, watching the filesystem for changes.', negatable: false); argParser.addOption('dart-sdk', help: 'The path to the Dart SDK.', hide: true); - // Options to enable a benchmarking mode. - argParser.addFlag('benchmark', - negatable: false, - hide: true - ); - argParser.addOption('benchmark-expected', - hide: true, - help: 'The time (in seconds) that the benchmark is expected to run.' - ); + // Hidden option to enable a benchmarking mode. + argParser.addFlag('benchmark', negatable: false, hide: true); usesPubOption(); } @@ -577,19 +570,12 @@ class AnalyzeCommand extends FlutterCommand { void _writeBenchmark(Stopwatch stopwatch, int errorCount) { final String benchmarkOut = 'analysis_benchmark.json'; - String expectedTime = argResults['benchmark-expected']; - Map data = { 'time': (stopwatch.elapsedMilliseconds / 1000.0), 'issues': errorCount }; - - if (expectedTime != null) - data['expected'] = expectedTime; - JsonEncoder encoder = new JsonEncoder.withIndent(' '); new File(benchmarkOut).writeAsStringSync(encoder.convert(data) + '\n'); - printStatus('Analysis benchmark written to $benchmarkOut.'); } } diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 2d9d5f77723..9dbebed3ee9 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart @@ -57,7 +57,7 @@ class DeviceManager { devices = devices.where((Device device) { return (device.id.toLowerCase().startsWith(deviceId) || device.name.toLowerCase().startsWith(deviceId)); - }); + }).toList(); return devices.length == 1 ? devices.first : null; } From 4d0e6984c204a27e2baa018b0debcfebd54242ba Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Thu, 5 May 2016 16:04:22 -0700 Subject: [PATCH 4/7] Build tool support for Android x86 targets in 32- or 64-bit modes (#3761) --- bin/cache/engine.version | 2 +- .../lib/src/android/android_device.dart | 49 +++++++++++++------ .../lib/src/application_package.dart | 2 + .../lib/src/build_configuration.dart | 1 + packages/flutter_tools/lib/src/cache.dart | 3 +- .../lib/src/commands/build_apk.dart | 19 ++++++- packages/flutter_tools/lib/src/toolchain.dart | 17 +++++-- 7 files changed, 72 insertions(+), 21 deletions(-) diff --git a/bin/cache/engine.version b/bin/cache/engine.version index bf129913617..662dd630b6c 100644 --- a/bin/cache/engine.version +++ b/bin/cache/engine.version @@ -1 +1 @@ -d85ead8ec2556739924282e2b3f77ff077a45820 +86837edd4ecbe5d28f16a770dff40a239f5b40b7 diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index b5e37ebde13..0712fdec431 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart @@ -49,23 +49,49 @@ class AndroidDevice extends Device { final String modelID; final String deviceCodeName; + Map _properties; bool _isLocalEmulator; + TargetPlatform _platform; + + String _getProperty(String name) { + if (_properties == null) { + String getpropOutput = runCheckedSync(adbCommandForDevice(['shell', 'getprop'])); + RegExp propertyExp = new RegExp(r'\[(.*?)\]: \[(.*?)\]'); + _properties = {}; + for (Match m in propertyExp.allMatches(getpropOutput)) { + _properties[m.group(1)] = m.group(2); + } + } + return _properties[name]; + } @override bool get isLocalEmulator { if (_isLocalEmulator == null) { + String characteristics = _getProperty('ro.build.characteristics'); + _isLocalEmulator = characteristics != null && characteristics.contains('emulator'); + } + return _isLocalEmulator; + } + + @override + TargetPlatform get platform { + if (_platform == null) { // http://developer.android.com/ndk/guides/abis.html (x86, armeabi-v7a, ...) - try { - String value = runCheckedSync(adbCommandForDevice( - ['shell', 'getprop', 'ro.product.cpu.abi'] - )); - _isLocalEmulator = value.startsWith('x86'); - } catch (error) { - _isLocalEmulator = false; + switch (_getProperty('ro.product.cpu.abi')) { + case 'x86_64': + _platform = TargetPlatform.android_x64; + break; + case 'x86': + _platform = TargetPlatform.android_x86; + break; + default: + _platform = TargetPlatform.android_arm; + break; } } - return _isLocalEmulator; + return _platform; } _AdbLogReader _logReader; @@ -123,9 +149,7 @@ class AndroidDevice extends Device { runCheckedSync([androidSdk.adbPath, 'start-server']); // Sample output: '22' - String sdkVersion = runCheckedSync( - adbCommandForDevice(['shell', 'getprop', 'ro.build.version.sdk']) - ).trimRight(); + String sdkVersion = _getProperty('ro.build.version.sdk'); int sdkVersionParsed = int.parse(sdkVersion, onError: (String source) => null); if (sdkVersionParsed == null) { @@ -333,9 +357,6 @@ class AndroidDevice extends Device { return runCommandAndStreamOutput(command).then((int exitCode) => exitCode == 0); } - @override - TargetPlatform get platform => isLocalEmulator ? TargetPlatform.android_x64 : TargetPlatform.android_arm; - @override void clearLogs() { runSync(adbCommandForDevice(['logcat', '-c'])); diff --git a/packages/flutter_tools/lib/src/application_package.dart b/packages/flutter_tools/lib/src/application_package.dart index 07a9318a98c..f4154eb9700 100644 --- a/packages/flutter_tools/lib/src/application_package.dart +++ b/packages/flutter_tools/lib/src/application_package.dart @@ -103,6 +103,7 @@ ApplicationPackage getApplicationPackageForPlatform(TargetPlatform platform) { switch (platform) { case TargetPlatform.android_arm: case TargetPlatform.android_x64: + case TargetPlatform.android_x86: return new AndroidApk.fromCurrentDirectory(); case TargetPlatform.ios: return new IOSApp.fromCurrentDirectory(); @@ -122,6 +123,7 @@ class ApplicationPackageStore { switch (platform) { case TargetPlatform.android_arm: case TargetPlatform.android_x64: + case TargetPlatform.android_x86: android ??= new AndroidApk.fromCurrentDirectory(); return android; case TargetPlatform.ios: diff --git a/packages/flutter_tools/lib/src/build_configuration.dart b/packages/flutter_tools/lib/src/build_configuration.dart index a70e6916765..e4e992c4373 100644 --- a/packages/flutter_tools/lib/src/build_configuration.dart +++ b/packages/flutter_tools/lib/src/build_configuration.dart @@ -41,6 +41,7 @@ String getNameForHostPlatform(HostPlatform platform) { enum TargetPlatform { android_arm, android_x64, + android_x86, ios, darwin_x64, linux_x64 diff --git a/packages/flutter_tools/lib/src/cache.dart b/packages/flutter_tools/lib/src/cache.dart index 892657baa88..ebb7369051f 100644 --- a/packages/flutter_tools/lib/src/cache.dart +++ b/packages/flutter_tools/lib/src/cache.dart @@ -192,7 +192,8 @@ class FlutterEngine { 'android-arm', 'android-arm-profile', 'android-arm-release', - 'android-x64' + 'android-x64', + 'android-x86', ]; if (Platform.isMacOS) diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart index 6004bff412d..0029062785b 100644 --- a/packages/flutter_tools/lib/src/commands/build_apk.dart +++ b/packages/flutter_tools/lib/src/commands/build_apk.dart @@ -261,6 +261,21 @@ class BuildApkCommand extends FlutterCommand { } } +// Return the directory name within the APK that is used for native code libraries +// on the given platform. +String getAbiDirectory(TargetPlatform platform) { + switch (platform) { + case TargetPlatform.android_arm: + return 'armeabi-v7a'; + case TargetPlatform.android_x64: + return 'x86_64'; + case TargetPlatform.android_x86: + return 'x86'; + default: + throw new Exception('Unsupported platform.'); + } +} + Future<_ApkComponents> _findApkComponents( TargetPlatform platform, BuildMode buildMode, @@ -274,7 +289,7 @@ Future<_ApkComponents> _findApkComponents( components.extraFiles = extraFiles != null ? extraFiles : {}; if (tools.isLocalEngine) { - String abiDir = platform == TargetPlatform.android_arm ? 'armeabi-v7a' : 'x86_64'; + String abiDir = getAbiDirectory(platform); String enginePath = tools.engineSrcPath; String buildDir = tools.getEngineArtifactsDirectory(platform, buildMode).path; @@ -348,7 +363,7 @@ int _buildApk( _AssetBuilder artifactBuilder = new _AssetBuilder(tempDir, 'artifacts'); artifactBuilder.add(classesDex, 'classes.dex'); - String abiDir = platform == TargetPlatform.android_arm ? 'armeabi-v7a' : 'x86_64'; + String abiDir = getAbiDirectory(platform); artifactBuilder.add(components.libSkyShell, 'lib/$abiDir/libsky_shell.so'); for (String relativePath in components.extraFiles.keys) diff --git a/packages/flutter_tools/lib/src/toolchain.dart b/packages/flutter_tools/lib/src/toolchain.dart index 7c876560ba9..3c3dd9749b6 100644 --- a/packages/flutter_tools/lib/src/toolchain.dart +++ b/packages/flutter_tools/lib/src/toolchain.dart @@ -144,10 +144,9 @@ class ToolConfiguration { switch (platform) { case TargetPlatform.android_arm: - type = 'android'; - break; case TargetPlatform.android_x64: - type = 'android_sim'; + case TargetPlatform.android_x86: + type = 'android'; break; // TODO(devoncarew): We will need an ios vs ios_x86 target (for ios vs. ios_sim). @@ -166,6 +165,18 @@ class ToolConfiguration { if (isAotBuildMode(mode)) buildOutputPath += '_Deploy'; + // Add a suffix for the target architecture. + switch (platform) { + case TargetPlatform.android_x64: + buildOutputPath += '_x64'; + break; + case TargetPlatform.android_x86: + buildOutputPath += '_x86'; + break; + default: + break; + } + return new Directory(path.join(engineSrcPath, buildOutputPath)); } else { String suffix = mode != BuildMode.debug ? '-${getModeName(mode)}' : ''; From 01978d98a8f687826e375e1e58af8431cab04757 Mon Sep 17 00:00:00 2001 From: krisgiesing Date: Thu, 5 May 2016 16:30:38 -0700 Subject: [PATCH 5/7] Move global analysis options file to the repo root (#3750) * Move global analysis options file to the repo root Also restore the analysis options file for stocks example, since the global options trigger warnings on generated intl files. * Remove obsolete analysis options file for Material Gallery example --- packages/.analysis_options => .analysis_options | 0 examples/material_gallery/.analysis_options | 3 --- examples/stocks/.analysis_options | 3 +++ 3 files changed, 3 insertions(+), 3 deletions(-) rename packages/.analysis_options => .analysis_options (100%) delete mode 100644 examples/material_gallery/.analysis_options create mode 100644 examples/stocks/.analysis_options diff --git a/packages/.analysis_options b/.analysis_options similarity index 100% rename from packages/.analysis_options rename to .analysis_options diff --git a/examples/material_gallery/.analysis_options b/examples/material_gallery/.analysis_options deleted file mode 100644 index a9b94d74906..00000000000 --- a/examples/material_gallery/.analysis_options +++ /dev/null @@ -1,3 +0,0 @@ -analyzer: - exclude: - - 'ios/.generated/**' diff --git a/examples/stocks/.analysis_options b/examples/stocks/.analysis_options new file mode 100644 index 00000000000..f9e8f30d8fe --- /dev/null +++ b/examples/stocks/.analysis_options @@ -0,0 +1,3 @@ +analyzer: + exclude: + - 'lib/i18n/stock_messages_*.dart' From 153e1bb918648f7c32fb8eb1664cd848ccf87a29 Mon Sep 17 00:00:00 2001 From: Viktor Lidholt Date: Thu, 5 May 2016 17:31:16 -0700 Subject: [PATCH 6/7] Fixes to particle system API (#3762) --- .../lib/demo/fitness_demo.dart | 3 +- .../lib/src/particle_system.dart | 107 +++++++++++------- 2 files changed, 64 insertions(+), 46 deletions(-) diff --git a/examples/material_gallery/lib/demo/fitness_demo.dart b/examples/material_gallery/lib/demo/fitness_demo.dart index 01707985c23..45cc3bac1fb 100644 --- a/examples/material_gallery/lib/demo/fitness_demo.dart +++ b/examples/material_gallery/lib/demo/fitness_demo.dart @@ -7,7 +7,6 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_sprites/flutter_sprites.dart'; -import 'package:vector_math/vector_math_64.dart' as vec; ImageMap _images; SpriteSheet _sprites; @@ -581,7 +580,7 @@ class _FireworksNode extends NodeWithSize { speedVar: 50.0, startSize: 1.0, startSizeVar: 0.5, - gravity: new vec.Vector2(0.0, 30.0), + gravity: const Offset(0.0, 30.0), colorSequence: new ColorSequence.fromStartAndEndColor(startColor, endColor) ); system.position = new Point(randomDouble() * 1024.0, randomDouble() * 1024.0); diff --git a/packages/flutter_sprites/lib/src/particle_system.dart b/packages/flutter_sprites/lib/src/particle_system.dart index 7f6c435d811..7f7609f9939 100644 --- a/packages/flutter_sprites/lib/src/particle_system.dart +++ b/packages/flutter_sprites/lib/src/particle_system.dart @@ -41,6 +41,49 @@ class _ParticleAccelerations { /// number of particles can never exceed the [maxParticles] limit. class ParticleSystem extends Node { + ParticleSystem(this.texture, + {this.life: 1.5, + this.lifeVar: 1.0, + this.posVar: Point.origin, + this.startSize: 2.5, + this.startSizeVar: 0.5, + this.endSize: 0.0, + this.endSizeVar: 0.0, + this.startRotation: 0.0, + this.startRotationVar: 0.0, + this.endRotation: 0.0, + this.endRotationVar: 0.0, + this.rotateToMovement : false, + this.direction: 0.0, + this.directionVar: 360.0, + this.speed: 100.0, + this.speedVar: 50.0, + this.radialAcceleration: 0.0, + this.radialAccelerationVar: 0.0, + this.tangentialAcceleration: 0.0, + this.tangentialAccelerationVar: 0.0, + this.maxParticles: 100, + this.emissionRate: 50.0, + this.colorSequence, + this.alphaVar: 0, + this.redVar: 0, + this.greenVar: 0, + this.blueVar: 0, + this.transferMode: TransferMode.plus, + this.numParticlesToEmit: 0, + this.autoRemoveOnFinish: true, + Offset gravity + }) { + this.gravity = gravity; + _particles = new List<_Particle>(); + _emitCounter = 0.0; + // _elapsedTime = 0.0; + if (_gravity == null) + _gravity = new Vector2.zero(); + if (colorSequence == null) + colorSequence = new ColorSequence.fromStartAndEndColor(new Color(0xffffffff), new Color(0x00ffffff)); + } + /// The texture used to draw each individual sprite. Texture texture; @@ -108,7 +151,21 @@ class ParticleSystem extends Node { double tangentialAccelerationVar; /// The gravity vector of the particle system. - Vector2 gravity; + Offset get gravity { + if (_gravity == null) + return null; + + return new Offset(_gravity.x, _gravity.y); + } + + Vector2 _gravity; + + void set gravity(Offset gravity) { + if (gravity == null) + _gravity = null; + else + _gravity = new Vector2(gravity.dx, gravity.dy); + } /// The maximum number of particles the system can display at a single time. int maxParticles; @@ -157,45 +214,6 @@ class ParticleSystem extends Node { ..filterQuality = FilterQuality.low ..isAntiAlias = false; - ParticleSystem(this.texture, - {this.life: 1.5, - this.lifeVar: 1.0, - this.posVar: Point.origin, - this.startSize: 2.5, - this.startSizeVar: 0.5, - this.endSize: 0.0, - this.endSizeVar: 0.0, - this.startRotation: 0.0, - this.startRotationVar: 0.0, - this.endRotation: 0.0, - this.endRotationVar: 0.0, - this.rotateToMovement : false, - this.direction: 0.0, - this.directionVar: 360.0, - this.speed: 100.0, - this.speedVar: 50.0, - this.radialAcceleration: 0.0, - this.radialAccelerationVar: 0.0, - this.tangentialAcceleration: 0.0, - this.tangentialAccelerationVar: 0.0, - this.gravity, - this.maxParticles: 100, - this.emissionRate: 50.0, - this.colorSequence, - this.alphaVar: 0, - this.redVar: 0, - this.greenVar: 0, - this.blueVar: 0, - this.transferMode: TransferMode.plus, - this.numParticlesToEmit: 0, - this.autoRemoveOnFinish: true}) { - _particles = new List<_Particle>(); - _emitCounter = 0.0; - // _elapsedTime = 0.0; - if (gravity == null) gravity = new Vector2.zero(); - if (colorSequence == null) colorSequence = new ColorSequence.fromStartAndEndColor(new Color(0xffffffff), new Color(0x00ffffff)); - } - @override void update(double dt) { // TODO: Fix this (it's a temp fix for low framerates) @@ -249,11 +267,11 @@ class ParticleSystem extends Node { tangential.scale(particle.accelerations.tangentialAccel); // (gravity + radial + tangential) * dt - Vector2 accel = (gravity + radial + tangential).scale(dt); + final Vector2 accel = (_gravity + radial + tangential).scale(dt); particle.dir += accel; - } else if (gravity[0] != 0.0 || gravity[1] != 0) { + } else if (_gravity[0] != 0.0 || _gravity[1] != 0) { // gravity - Vector2 accel = new Vector2.copy(gravity).scale(dt); + final Vector2 accel = new Vector2.copy(_gravity).scale(dt); particle.dir += accel; } @@ -362,7 +380,8 @@ class ParticleSystem extends Node { @override void paint(Canvas canvas) { - if (opacity == 0.0) return; + if (opacity == 0.0) + return; List transforms = []; List rects = []; From bd564a02af1a98167227b8e4dc11e41cd172ec2f Mon Sep 17 00:00:00 2001 From: Devon Carew Date: Thu, 5 May 2016 19:51:22 -0700 Subject: [PATCH 7/7] avoid sending analytics on ci systems (#3765) * avoid sending analytics on ci systems * review comments --- packages/flutter_tools/lib/executable.dart | 2 +- .../flutter_tools/lib/src/base/utils.dart | 7 ++++++ .../lib/src/commands/upgrade.dart | 2 +- packages/flutter_tools/lib/src/doctor.dart | 2 +- .../src/runner/flutter_command_runner.dart | 2 +- packages/flutter_tools/lib/src/usage.dart | 23 ++++++++++++++++--- .../lib/src/{runner => }/version.dart | 8 +++---- travis/setup.sh | 6 ++--- 8 files changed, 37 insertions(+), 15 deletions(-) rename packages/flutter_tools/lib/src/{runner => }/version.dart (95%) diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart index 98b6664d416..0d9cddfbe69 100644 --- a/packages/flutter_tools/lib/executable.dart +++ b/packages/flutter_tools/lib/executable.dart @@ -102,7 +102,7 @@ Future main(List args) async { flutterUsage.sendException(error, chain); - if (Platform.environment.containsKey('FLUTTER_DEV')) { + if (Platform.environment.containsKey('FLUTTER_DEV') || isRunningOnBot) { // If we're working on the tools themselves, just print the stack trace. stderr.writeln('$error'); stderr.writeln(chain.terse.toString()); diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart index 8b1ba05dcf0..a550f9cbbf4 100644 --- a/packages/flutter_tools/lib/src/base/utils.dart +++ b/packages/flutter_tools/lib/src/base/utils.dart @@ -8,6 +8,13 @@ import 'dart:io'; import 'package:crypto/crypto.dart'; import 'package:path/path.dart' as path; +bool get isRunningOnBot { + // https://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables + return + Platform.environment['TRAVIS'] == 'true' || + Platform.environment['CONTINUOUS_INTEGRATION'] == 'true'; +} + String hex(List bytes) { StringBuffer result = new StringBuffer(); for (int part in bytes) diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart index 562342c25c5..70c1b610594 100644 --- a/packages/flutter_tools/lib/src/commands/upgrade.dart +++ b/packages/flutter_tools/lib/src/commands/upgrade.dart @@ -10,7 +10,7 @@ import '../base/process.dart'; import '../dart/pub.dart'; import '../globals.dart'; import '../runner/flutter_command.dart'; -import '../runner/version.dart'; +import '../version.dart'; class UpgradeCommand extends FlutterCommand { @override diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index 7a718f0d129..86ac9411628 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -12,7 +12,7 @@ import 'base/context.dart'; import 'base/os.dart'; import 'globals.dart'; import 'ios/ios_workflow.dart'; -import 'runner/version.dart'; +import 'version.dart'; const Map _osNames = const { 'macos': 'Mac OS', diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart index 382cc4ef9c8..03a34f1ba03 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart @@ -18,7 +18,7 @@ import '../build_configuration.dart'; import '../globals.dart'; import '../package_map.dart'; import '../toolchain.dart'; -import 'version.dart'; +import '../version.dart'; const String kFlutterRootEnvironmentVariableName = 'FLUTTER_ROOT'; // should point to //flutter/ (root of flutter/flutter repo) const String kFlutterEngineEnvironmentVariableName = 'FLUTTER_ENGINE'; // should point to //engine/src/ (root of flutter/engine repo) diff --git a/packages/flutter_tools/lib/src/usage.dart b/packages/flutter_tools/lib/src/usage.dart index 388adb3027a..440ce5e1f78 100644 --- a/packages/flutter_tools/lib/src/usage.dart +++ b/packages/flutter_tools/lib/src/usage.dart @@ -8,8 +8,9 @@ import 'package:usage/src/usage_impl_io.dart'; import 'package:usage/usage.dart'; import 'base/context.dart'; +import 'base/utils.dart'; import 'globals.dart'; -import 'runner/version.dart'; +import 'version.dart'; // TODO(devoncarew): We'll need to do some work on the user agent in order to // correctly track usage by operating system (dart-lang/usage/issues/70). @@ -22,7 +23,19 @@ class Usage { Usage() { String version = FlutterVersion.getVersionString(whitelistBranchName: true); _analytics = new AnalyticsIO(_kFlutterUA, 'flutter', version); - _analytics.analyticsOpt = AnalyticsOpt.optOut; + + bool runningOnCI = false; + + // Many CI systems don't do a full git checkout. + if (version.startsWith('unknown/')) + runningOnCI = true; + + // Check for common CI systems. + if (isRunningOnBot) + runningOnCI = true; + + // If we think we're running on a CI system, default to not sending analytics. + _analytics.analyticsOpt = runningOnCI ? AnalyticsOpt.optIn : AnalyticsOpt.optOut; } /// Returns [Usage] active in the current app context. @@ -82,10 +95,14 @@ class Usage { final String versionString = FlutterVersion.getVersionString(whitelistBranchName: true); + String welcomeString = 'Welcome to Flutter! - Flutter version $versionString - https://flutter.io'; + welcomeString = welcomeString.padLeft((welcomeString.length + 100) ~/ 2); + welcomeString = welcomeString.padRight(100); + printStatus(''); printStatus(''' ╔════════════════════════════════════════════════════════════════════════════════════════════════════╗ - ║ Welcome to Flutter! - Flutter version $versionString - https://flutter.io ║ + ║$welcomeString║ ║ ║ ║ The Flutter tool anonymously reports feature usage statistics and basic crash reports to Google in ║ ║ order to help Google contribute improvements to Flutter over time. See Google's privacy policy: ║ diff --git a/packages/flutter_tools/lib/src/runner/version.dart b/packages/flutter_tools/lib/src/version.dart similarity index 95% rename from packages/flutter_tools/lib/src/runner/version.dart rename to packages/flutter_tools/lib/src/version.dart index 8e400c55272..5b402a4a66d 100644 --- a/packages/flutter_tools/lib/src/runner/version.dart +++ b/packages/flutter_tools/lib/src/version.dart @@ -4,8 +4,8 @@ import 'dart:io'; -import '../artifacts.dart'; -import '../base/process.dart'; +import 'artifacts.dart'; +import 'base/process.dart'; final Set kKnownBranchNames = new Set.from([ 'master', @@ -64,7 +64,7 @@ class FlutterVersion { return new FlutterVersion(flutterRoot != null ? flutterRoot : ArtifactStore.flutterRoot); } - /// Return a short string for the version (`a76bc8e22b/alpha`). + /// Return a short string for the version (`alpha/a76bc8e22b`). static String getVersionString({ bool whitelistBranchName: false }) { final String cwd = ArtifactStore.flutterRoot; @@ -80,7 +80,7 @@ class FlutterVersion { branch = 'dev'; } - return '$commit/$branch'; + return '$branch/$commit'; } } diff --git a/travis/setup.sh b/travis/setup.sh index 213102825dd..cad886fc872 100755 --- a/travis/setup.sh +++ b/travis/setup.sh @@ -1,10 +1,8 @@ #!/bin/bash set -ex -# Download dependencies flutter -./bin/flutter --version - -# Disable analytics on the bots (to avoid skewing analytics data). +# disable analytics on the bots and download Flutter dependencies ./bin/flutter config --no-analytics +# run pub get in all the repo packages ./bin/flutter update-packages