├── .gitignore ├── .metadata ├── README.md ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── procedural_generation │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── assets ├── cloud.riv ├── fire.riv ├── grass.riv ├── marty_transparent.riv ├── marty_v6.riv ├── planet.riv ├── star.riv ├── star_close.riv ├── ufo.riv └── wave.riv ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib ├── cloud.dart ├── constants.dart ├── fire.dart ├── grass.dart ├── helpers.dart ├── iv_builder_page.dart ├── iv_builder_table_page.dart ├── iv_builderless_page.dart ├── iv_slow_page.dart ├── layer.dart ├── list_view_builder_page.dart ├── main.dart ├── map_data.dart ├── marty.dart ├── planet.dart ├── procedural_generation_page.dart ├── rive_asset.dart ├── single_child_scroll_view_page.dart ├── star.dart ├── star_close.dart ├── table_builder.dart ├── ufo.dart └── wave.dart ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── app_icon_1024.png │ │ ├── app_icon_128.png │ │ ├── app_icon_16.png │ │ ├── app_icon_256.png │ │ ├── app_icon_32.png │ │ ├── app_icon_512.png │ │ └── app_icon_64.png │ ├── Base.lproj │ └── MainMenu.xib │ ├── Configs │ ├── AppInfo.xcconfig │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements ├── pubspec.lock ├── pubspec.yaml ├── screenshots ├── 1d.png ├── 2d.png ├── menu.png └── proc_gen.png ├── test └── widget_test.dart └── web ├── favicon.png ├── icons ├── Icon-192.png └── Icon-512.png ├── index.html └── manifest.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 25134a16d128ed22dc0ad8d41d2b931fcad3b014 8 | channel: master 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flutter Lazy Performance 2 | 3 | Examples of widgets extending off-screen and various ways of handling this in a performant way. Demos with "naive" in the title optimize nothing at all, and they probably shouldn't be used except in trivial cases. Other examples attempt various performance improvements and trade offs. 4 | 5 | This repo comes from a [talk](https://www.youtube.com/watch?v=qax_nOpgz7E) at Google I/O 2021. 6 | 7 | Check out the live demo at: [https://justinmc.github.io/flutter-lazy-performance/](https://justinmc.github.io/flutter-lazy-performance/). 8 | 9 | Thanks to the Marty McFly asset from Rive: [https://rive.app/community/52-69-marty-animation/](https://rive.app/community/52-69-marty-animation/). 10 | 11 | ## Notes 12 | * `InteractiveViewer.builder`, used in several of the examples here, was not available in Flutter's stable channel at the time of I/O (May 2021), but was available in dev and stable. To check if your Flutter build has `InteractiveViewer.builder`, be sure you have commit https://github.com/flutter/flutter/commit/a8e41f8206133012056b02595111efe94537a816, which is from PR https://github.com/flutter/flutter/pull/80166. 13 | * When deploying the live demo on Github Pages, the index.html file must be updated to set a non-root path (see more in the [docs](https://flutter.dev/docs/development/ui/navigation/url-strategies)). 14 | 15 | ![Screenshot of menu](https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/main/screenshots/menu.png?raw=true) 16 | ![Screenshot of list](https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/main/screenshots/1d.png?raw=true) 17 | ![Screenshot of grid](https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/main/screenshots/2d.png?raw=true) 18 | ![Screenshot of procedural generation demo](https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/main/screenshots/proc_gen.png?raw=true) 19 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 30 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 37 | applicationId "com.example.procedural_generation" 38 | minSdkVersion 16 39 | targetSdkVersion 30 40 | versionCode flutterVersionCode.toInteger() 41 | versionName flutterVersionName 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 59 | } 60 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/procedural_generation/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.procedural_generation 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /assets/cloud.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/cloud.riv -------------------------------------------------------------------------------- /assets/fire.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/fire.riv -------------------------------------------------------------------------------- /assets/grass.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/grass.riv -------------------------------------------------------------------------------- /assets/marty_transparent.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/marty_transparent.riv -------------------------------------------------------------------------------- /assets/marty_v6.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/marty_v6.riv -------------------------------------------------------------------------------- /assets/planet.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/planet.riv -------------------------------------------------------------------------------- /assets/star.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/star.riv -------------------------------------------------------------------------------- /assets/star_close.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/star_close.riv -------------------------------------------------------------------------------- /assets/ufo.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/ufo.riv -------------------------------------------------------------------------------- /assets/wave.riv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/assets/wave.riv -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | INFOPLIST_FILE = Runner/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 294 | PRODUCT_BUNDLE_IDENTIFIER = com.example.proceduralGeneration; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 297 | SWIFT_VERSION = 5.0; 298 | VERSIONING_SYSTEM = "apple-generic"; 299 | }; 300 | name = Profile; 301 | }; 302 | 97C147031CF9000F007C117D /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = dwarf; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | ENABLE_TESTABILITY = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_DYNAMIC_NO_PIC = NO; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_PREPROCESSOR_DEFINITIONS = ( 340 | "DEBUG=1", 341 | "$(inherited)", 342 | ); 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 350 | MTL_ENABLE_DEBUG_INFO = YES; 351 | ONLY_ACTIVE_ARCH = YES; 352 | SDKROOT = iphoneos; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | }; 355 | name = Debug; 356 | }; 357 | 97C147041CF9000F007C117D /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_COMMA = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 381 | CLANG_WARN_STRICT_PROTOTYPES = YES; 382 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 386 | COPY_PHASE_STRIP = NO; 387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 388 | ENABLE_NS_ASSERTIONS = NO; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | GCC_C_LANGUAGE_STANDARD = gnu99; 391 | GCC_NO_COMMON_BLOCKS = YES; 392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 394 | GCC_WARN_UNDECLARED_SELECTOR = YES; 395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 396 | GCC_WARN_UNUSED_FUNCTION = YES; 397 | GCC_WARN_UNUSED_VARIABLE = YES; 398 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 399 | MTL_ENABLE_DEBUG_INFO = NO; 400 | SDKROOT = iphoneos; 401 | SUPPORTED_PLATFORMS = iphoneos; 402 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 403 | TARGETED_DEVICE_FAMILY = "1,2"; 404 | VALIDATE_PRODUCT = YES; 405 | }; 406 | name = Release; 407 | }; 408 | 97C147061CF9000F007C117D /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 411 | buildSettings = { 412 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 413 | CLANG_ENABLE_MODULES = YES; 414 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 415 | ENABLE_BITCODE = NO; 416 | INFOPLIST_FILE = Runner/Info.plist; 417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 418 | PRODUCT_BUNDLE_IDENTIFIER = com.example.proceduralGeneration; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 422 | SWIFT_VERSION = 5.0; 423 | VERSIONING_SYSTEM = "apple-generic"; 424 | }; 425 | name = Debug; 426 | }; 427 | 97C147071CF9000F007C117D /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 430 | buildSettings = { 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | CLANG_ENABLE_MODULES = YES; 433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 434 | ENABLE_BITCODE = NO; 435 | INFOPLIST_FILE = Runner/Info.plist; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 437 | PRODUCT_BUNDLE_IDENTIFIER = com.example.proceduralGeneration; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 440 | SWIFT_VERSION = 5.0; 441 | VERSIONING_SYSTEM = "apple-generic"; 442 | }; 443 | name = Release; 444 | }; 445 | /* End XCBuildConfiguration section */ 446 | 447 | /* Begin XCConfigurationList section */ 448 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 449 | isa = XCConfigurationList; 450 | buildConfigurations = ( 451 | 97C147031CF9000F007C117D /* Debug */, 452 | 97C147041CF9000F007C117D /* Release */, 453 | 249021D3217E4FDB00AE95B9 /* Profile */, 454 | ); 455 | defaultConfigurationIsVisible = 0; 456 | defaultConfigurationName = Release; 457 | }; 458 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 97C147061CF9000F007C117D /* Debug */, 462 | 97C147071CF9000F007C117D /* Release */, 463 | 249021D4217E4FDB00AE95B9 /* Profile */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 471 | } 472 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | procedural_generation 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/cloud.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'rive_asset.dart'; 5 | 6 | class Cloud extends RiveAsset { 7 | const Cloud({ 8 | Key? key, 9 | }) : super( 10 | key: key, 11 | asset: 'assets/cloud.riv', 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /lib/constants.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | const Size cellSize = Size(100.0, 100.0); 4 | -------------------------------------------------------------------------------- /lib/fire.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'rive_asset.dart'; 5 | 6 | class Fire extends RiveAsset { 7 | const Fire({ 8 | Key? key, 9 | }) : super( 10 | key: key, 11 | asset: 'assets/fire.riv', 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /lib/grass.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'rive_asset.dart'; 5 | 6 | class Grass extends RiveAsset { 7 | const Grass({ 8 | Key? key, 9 | }) : super( 10 | key: key, 11 | asset: 'assets/grass.riv', 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /lib/helpers.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui' show Rect; 2 | 3 | import 'package:vector_math/vector_math_64.dart' show Quad, Vector3; 4 | 5 | // Returns the axis aligned bounding box for the given Quad, which might not 6 | // be axis aligned. 7 | Rect axisAlignedBoundingBox(Quad quad) { 8 | double? xMin; 9 | double? xMax; 10 | double? yMin; 11 | double? yMax; 12 | for (final Vector3 point in [ 13 | quad.point0, 14 | quad.point1, 15 | quad.point2, 16 | quad.point3 17 | ]) { 18 | if (xMin == null || point.x < xMin) { 19 | xMin = point.x; 20 | } 21 | if (xMax == null || point.x > xMax) { 22 | xMax = point.x; 23 | } 24 | if (yMin == null || point.y < yMin) { 25 | yMin = point.y; 26 | } 27 | if (yMax == null || point.y > yMax) { 28 | yMax = point.y; 29 | } 30 | } 31 | return Rect.fromLTRB(xMin!, yMin!, xMax!, yMax!); 32 | } 33 | -------------------------------------------------------------------------------- /lib/iv_builder_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:vector_math/vector_math_64.dart' show Quad; 3 | 4 | import 'helpers.dart'; 5 | import 'marty.dart'; 6 | 7 | class IVBuilderPage extends StatefulWidget { 8 | const IVBuilderPage({Key? key}) : super(key: key); 9 | 10 | static const String routeName = '/iv-builder'; 11 | 12 | @override 13 | _IVBuilderPageState createState() => _IVBuilderPageState(); 14 | } 15 | 16 | class _IVBuilderPageState extends State { 17 | final TransformationController _transformationController = 18 | TransformationController(); 19 | 20 | static const double _cellWidth = 200.0; 21 | static const double _cellHeight = 200.0; 22 | static const int _rowCount = 10; 23 | static const int _columnCount = 10; 24 | 25 | // Returns true iff the given cell is currently visible. Caches viewport 26 | // calculations. 27 | Quad? _cachedViewport; 28 | late int _firstVisibleColumn; 29 | late int _firstVisibleRow; 30 | late int _lastVisibleColumn; 31 | late int _lastVisibleRow; 32 | bool _isCellVisible(int row, int column, Quad viewport) { 33 | if (viewport != _cachedViewport) { 34 | final Rect aabb = axisAlignedBoundingBox(viewport); 35 | _cachedViewport = viewport; 36 | _firstVisibleRow = (aabb.top / _cellHeight).floor(); 37 | _firstVisibleColumn = (aabb.left / _cellWidth).floor(); 38 | _lastVisibleRow = (aabb.bottom / _cellHeight).floor(); 39 | _lastVisibleColumn = (aabb.right / _cellWidth).floor(); 40 | } 41 | return row >= _firstVisibleRow && 42 | row <= _lastVisibleRow && 43 | column >= _firstVisibleColumn && 44 | column <= _lastVisibleColumn; 45 | } 46 | 47 | void _onChangeTransformation() { 48 | setState(() {}); 49 | } 50 | 51 | @override 52 | void initState() { 53 | super.initState(); 54 | _transformationController.addListener(_onChangeTransformation); 55 | } 56 | 57 | @override 58 | void dispose() { 59 | _transformationController.removeListener(_onChangeTransformation); 60 | super.dispose(); 61 | } 62 | 63 | @override 64 | Widget build(BuildContext context) { 65 | return Scaffold( 66 | appBar: AppBar( 67 | title: const Text('Two Dimensions'), 68 | actions: [ 69 | IconButton( 70 | icon: const Icon(Icons.add_alert), 71 | tooltip: 'Show Snackbar', 72 | onPressed: () { 73 | ScaffoldMessenger.of(context).showSnackBar( 74 | const SnackBar(content: Text('This is a snackbar'))); 75 | }, 76 | ), 77 | ], 78 | ), 79 | body: Center( 80 | child: LayoutBuilder( 81 | builder: (BuildContext context, BoxConstraints constraints) { 82 | return InteractiveViewer.builder( 83 | scaleEnabled: false, 84 | transformationController: _transformationController, 85 | builder: (BuildContext context, Quad viewport) { 86 | return Column( 87 | children: [ 88 | for (int row = 0; row < _rowCount; row++) 89 | Row( 90 | children: [ 91 | for (int column = 0; column < _columnCount; column++) 92 | _isCellVisible(row, column, viewport) 93 | ? Container( 94 | height: _cellHeight, 95 | width: _cellWidth, 96 | child: Marty( 97 | index: row * _columnCount + column), 98 | ) 99 | : Container( 100 | width: _cellWidth, height: _cellHeight), 101 | ], 102 | ), 103 | ], 104 | ); 105 | }, 106 | ); 107 | }, 108 | ), 109 | ), 110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /lib/iv_builder_table_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:vector_math/vector_math_64.dart' show Quad; 3 | 4 | import 'helpers.dart'; 5 | import 'table_builder.dart'; 6 | 7 | class IVBuilderTablePage extends StatefulWidget { 8 | const IVBuilderTablePage({Key? key}) : super(key: key); 9 | 10 | static const String routeName = '/iv-builder-table'; 11 | 12 | @override 13 | _IVBuilderTablePageState createState() => _IVBuilderTablePageState(); 14 | } 15 | 16 | class _IVBuilderTablePageState extends State { 17 | final TransformationController _transformationController = 18 | TransformationController(); 19 | 20 | static const double _cellWidth = 200.0; 21 | static const double _cellHeight = 26.0; 22 | 23 | // Returns true iff the given cell is currently visible. Caches viewport 24 | // calculations. 25 | Quad? _cachedViewport; 26 | late int _firstVisibleColumn; 27 | late int _firstVisibleRow; 28 | late int _lastVisibleColumn; 29 | late int _lastVisibleRow; 30 | bool _isCellVisible(int row, int column, Quad viewport) { 31 | if (viewport != _cachedViewport) { 32 | final Rect aabb = axisAlignedBoundingBox(viewport); 33 | _cachedViewport = viewport; 34 | _firstVisibleRow = (aabb.top / _cellHeight).floor(); 35 | _firstVisibleColumn = (aabb.left / _cellWidth).floor(); 36 | _lastVisibleRow = (aabb.bottom / _cellHeight).floor(); 37 | _lastVisibleColumn = (aabb.right / _cellWidth).floor(); 38 | } 39 | return row >= _firstVisibleRow && 40 | row <= _lastVisibleRow && 41 | column >= _firstVisibleColumn && 42 | column <= _lastVisibleColumn; 43 | } 44 | 45 | void _onChangeTransformation() { 46 | setState(() {}); 47 | } 48 | 49 | @override 50 | void initState() { 51 | super.initState(); 52 | _transformationController.addListener(_onChangeTransformation); 53 | } 54 | 55 | @override 56 | void dispose() { 57 | _transformationController.removeListener(_onChangeTransformation); 58 | super.dispose(); 59 | } 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | return Scaffold( 64 | appBar: AppBar( 65 | title: const Text('Two Dimensions'), 66 | actions: [], 67 | ), 68 | body: Center( 69 | child: LayoutBuilder( 70 | builder: (BuildContext context, BoxConstraints constraints) { 71 | return InteractiveViewer.builder( 72 | alignPanAxis: true, 73 | scaleEnabled: false, 74 | transformationController: _transformationController, 75 | //maxScale: _maxScale, 76 | //minScale: _minScale, 77 | builder: (BuildContext context, Quad viewport) { 78 | return TableBuilder( 79 | rowCount: 60, 80 | columnCount: 6, 81 | cellWidth: _cellWidth, 82 | builder: (BuildContext context, int row, int column) { 83 | if (!_isCellVisible(row, column, viewport)) { 84 | return Container(height: _cellHeight); 85 | } 86 | return Container( 87 | height: _cellHeight, 88 | color: row % 2 + column % 2 == 1 89 | ? Colors.white 90 | : Colors.grey.withOpacity(0.1), 91 | child: Align( 92 | alignment: Alignment.centerLeft, 93 | child: Text('$row x $column'), 94 | ), 95 | ); 96 | }); 97 | }, 98 | ); 99 | }, 100 | ), 101 | ), 102 | ); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /lib/iv_builderless_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:vector_math/vector_math_64.dart' show Vector3; 3 | 4 | import 'table_builder.dart'; 5 | 6 | // This page shows how to achieve a similar effect as InteractiveViewer.builder 7 | // but before builder was implemented in the framework. 8 | class IVBuilderlessPage extends StatefulWidget { 9 | const IVBuilderlessPage({Key? key}) : super(key: key); 10 | 11 | static const String routeName = '/iv-builder'; 12 | 13 | @override 14 | _IVBuilderlessPageState createState() => _IVBuilderlessPageState(); 15 | } 16 | 17 | class _IVBuilderlessPageState extends State { 18 | final TransformationController _transformationController = 19 | TransformationController(); 20 | 21 | static const double _cellWidth = 200.0; 22 | static const double _cellHeight = 26.0; 23 | 24 | bool _isCellVisible(int row, int column, Rect viewport) { 25 | if (viewport != _cachedViewport) { 26 | _calculateVisibleCells(viewport); 27 | } 28 | return row >= _firstVisibleRow && 29 | row <= _lastVisibleRow && 30 | column >= _firstVisibleColumn && 31 | column <= _lastVisibleColumn; 32 | } 33 | 34 | Rect? _cachedViewport; 35 | late int _firstVisibleColumn; 36 | late int _firstVisibleRow; 37 | late int _lastVisibleColumn; 38 | late int _lastVisibleRow; 39 | void _calculateVisibleCells(Rect viewport) { 40 | _cachedViewport = viewport; 41 | _firstVisibleRow = (viewport.top / _cellHeight).floor(); 42 | _firstVisibleColumn = (viewport.left / _cellWidth).floor(); 43 | _lastVisibleRow = (viewport.bottom / _cellHeight).floor(); 44 | _lastVisibleColumn = (viewport.right / _cellWidth).floor(); 45 | } 46 | 47 | void _onChangeTransformation() { 48 | setState(() {}); 49 | } 50 | 51 | @override 52 | void initState() { 53 | super.initState(); 54 | _transformationController.addListener(_onChangeTransformation); 55 | } 56 | 57 | @override 58 | void dispose() { 59 | _transformationController.removeListener(_onChangeTransformation); 60 | super.dispose(); 61 | } 62 | 63 | @override 64 | Widget build(BuildContext context) { 65 | return Scaffold( 66 | appBar: AppBar( 67 | title: const Text('MyIVBuilderless'), 68 | actions: [], 69 | ), 70 | body: Center( 71 | child: LayoutBuilder( 72 | builder: (BuildContext context, BoxConstraints constraints) { 73 | final Vector3 translation = 74 | _transformationController.value.getTranslation() * -1; 75 | // This does not handle scale. You'd need access to 76 | // _transformViewport in the framework, or you'd have to do that 77 | // calculation yourself. 78 | final Rect viewport = Rect.fromLTWH( 79 | translation.x, 80 | translation.y, 81 | constraints.maxWidth, 82 | constraints.maxHeight, 83 | ); 84 | return InteractiveViewer( 85 | alignPanAxis: false, 86 | constrained: false, 87 | transformationController: _transformationController, 88 | scaleEnabled: false, 89 | child: Builder( 90 | builder: (BuildContext context) { 91 | return TableBuilder( 92 | rowCount: 60, 93 | columnCount: 6, 94 | cellWidth: _cellWidth, 95 | builder: (BuildContext context, int row, int column) { 96 | if (!_isCellVisible(row, column, viewport)) { 97 | return Container(height: _cellHeight); 98 | } 99 | return Container( 100 | height: _cellHeight, 101 | //color: row % 2 + column % 2 == 1 ? Colors.white : Colors.grey.withOpacity(0.1), 102 | child: Align( 103 | alignment: Alignment.centerLeft, 104 | child: Text('$row x $column'), 105 | ), 106 | ); 107 | }); 108 | }, 109 | ), 110 | ); 111 | }, 112 | ), 113 | ), 114 | ); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /lib/iv_slow_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'marty.dart'; 4 | 5 | class IVSlowPage extends StatefulWidget { 6 | const IVSlowPage({Key? key}) : super(key: key); 7 | 8 | static const String routeName = '/iv-slow'; 9 | 10 | @override 11 | _IVSlowPageState createState() => _IVSlowPageState(); 12 | } 13 | 14 | class _IVSlowPageState extends State { 15 | final TransformationController _transformationController = 16 | TransformationController(); 17 | 18 | static const double _cellWidth = 200.0; 19 | static const double _cellHeight = 200.0; 20 | static const int _rowCount = 10; 21 | static const int _columnCount = 10; 22 | 23 | void _onChangeTransformation() { 24 | setState(() {}); 25 | } 26 | 27 | @override 28 | void initState() { 29 | super.initState(); 30 | _transformationController.addListener(_onChangeTransformation); 31 | } 32 | 33 | @override 34 | void dispose() { 35 | _transformationController.removeListener(_onChangeTransformation); 36 | super.dispose(); 37 | } 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | return Scaffold( 42 | appBar: AppBar( 43 | title: const Text('Two Dimensions - Naive'), 44 | actions: [], 45 | ), 46 | body: Center( 47 | child: InteractiveViewer( 48 | constrained: false, 49 | scaleEnabled: false, 50 | transformationController: _transformationController, 51 | child: Column( 52 | children: [ 53 | for (int row = 0; row < _rowCount; row++) 54 | Row( 55 | children: [ 56 | for (int column = 0; column < _columnCount; column++) 57 | Container( 58 | height: _cellHeight, 59 | width: _cellWidth, 60 | child: Marty(index: row * _columnCount + column), 61 | ), 62 | ], 63 | ), 64 | ], 65 | ), 66 | ), 67 | ), 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/layer.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui' show Size; 2 | import 'dart:math' show pow; 3 | 4 | import 'constants.dart'; 5 | 6 | enum LayerType { 7 | local, 8 | terrestrial, 9 | solar, 10 | galactic, 11 | } 12 | 13 | class Layer { 14 | const Layer({ 15 | this.scale, 16 | this.parent, 17 | this.child, 18 | this.level, 19 | }) : assert(scale == 1.0 || scale == 0.1 || scale == 0.01 || scale == 0.001), 20 | assert(level != null && level >= 0 && level < 4); 21 | 22 | // Each layer has 10x as many tiles as its parent. 23 | static const int layerScale = 10; 24 | 25 | final LayerType? parent; 26 | final LayerType? child; 27 | final double? scale; 28 | final int? level; 29 | 30 | Size get size { 31 | return Size( 32 | cellSize.width * pow(Layer.layerScale, level!), 33 | cellSize.height * pow(Layer.layerScale, level!), 34 | ); 35 | } 36 | } 37 | 38 | final Map layers = { 39 | LayerType.local: Layer( 40 | parent: LayerType.terrestrial, 41 | scale: 1.0, 42 | level: 0, 43 | ), 44 | LayerType.terrestrial: Layer( 45 | parent: LayerType.solar, 46 | child: LayerType.local, 47 | scale: 0.1, 48 | level: 1, 49 | ), 50 | LayerType.solar: Layer( 51 | parent: LayerType.galactic, 52 | child: LayerType.terrestrial, 53 | scale: 0.01, 54 | level: 2, 55 | ), 56 | LayerType.galactic: Layer( 57 | child: LayerType.solar, 58 | scale: 0.001, 59 | level: 3, 60 | ), 61 | }; 62 | -------------------------------------------------------------------------------- /lib/list_view_builder_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'marty.dart'; 4 | 5 | class ListViewBuilderPage extends StatefulWidget { 6 | const ListViewBuilderPage({Key? key}) : super(key: key); 7 | 8 | static const String routeName = '/list-view-builder'; 9 | 10 | @override 11 | _ListViewBuilderPageState createState() => _ListViewBuilderPageState(); 12 | } 13 | 14 | class _ListViewBuilderPageState extends State { 15 | static const _itemCount = 100; 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return Scaffold( 20 | appBar: AppBar( 21 | title: const Text('ListView.builder'), 22 | actions: [], 23 | ), 24 | body: Center( 25 | child: Container( 26 | width: 400.0, 27 | height: 400.0, 28 | child: ListView.builder( 29 | itemCount: _itemCount, 30 | itemBuilder: (BuildContext context, int index) { 31 | // print('building item #$index'); 32 | return Container( 33 | height: 200, 34 | color: Colors.teal.withOpacity(index / _itemCount), 35 | child: Marty( 36 | index: index, 37 | ), 38 | ); 39 | }, 40 | ), 41 | ), 42 | ), 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'iv_builder_page.dart'; 4 | import 'iv_slow_page.dart'; 5 | import 'iv_builder_table_page.dart'; 6 | import 'list_view_builder_page.dart'; 7 | import 'single_child_scroll_view_page.dart'; 8 | import 'procedural_generation_page.dart'; 9 | 10 | final List pages = [ 11 | IVBuilderPage, 12 | ]; 13 | 14 | void main() { 15 | runApp(MyApp()); 16 | } 17 | 18 | class MyApp extends StatelessWidget { 19 | // This widget is the root of your application. 20 | @override 21 | Widget build(BuildContext context) { 22 | return MaterialApp( 23 | title: 'Flutter Builder Performance Demo', 24 | theme: ThemeData( 25 | primarySwatch: Colors.blue, 26 | ), 27 | initialRoute: '/', 28 | routes: { 29 | '/': (BuildContext context) => MyHomePage(), 30 | SingleChildScrollViewPage.routeName: (BuildContext context) => 31 | SingleChildScrollViewPage(), 32 | ListViewBuilderPage.routeName: (BuildContext context) => 33 | ListViewBuilderPage(), 34 | IVSlowPage.routeName: (BuildContext context) => IVSlowPage(), 35 | IVBuilderPage.routeName: (BuildContext context) => IVBuilderPage(), 36 | IVBuilderTablePage.routeName: (BuildContext context) => 37 | IVBuilderTablePage(), 38 | ProceduralGenerationPage.routeName: (BuildContext context) => 39 | ProceduralGenerationPage(), 40 | }, 41 | ); 42 | } 43 | } 44 | 45 | class MyHomePage extends StatelessWidget { 46 | MyHomePage({Key? key}) : super(key: key); 47 | 48 | @override 49 | Widget build(BuildContext context) { 50 | return Scaffold( 51 | appBar: AppBar( 52 | title: Text('Lazy Performance Demos'), 53 | ), 54 | body: ListView( 55 | children: [ 56 | MyListItem( 57 | route: '/single-child-scroll-view', 58 | title: 'Naive List Example', 59 | subtitle: 'Build everything upfront.', 60 | ), 61 | MyListItem( 62 | route: '/list-view-builder', 63 | title: 'ListView.builder Example', 64 | subtitle: 'Build only the visible list items.', 65 | ), 66 | MyListItem( 67 | route: '/iv-slow', 68 | title: 'Naive InteractiveViewer Example', 69 | subtitle: "Build everything, even what's not visible.", 70 | ), 71 | MyListItem( 72 | route: '/iv-builder', 73 | title: 'InteractiveViewer.builder Example', 74 | subtitle: 'Build only the visible parts of a grid.', 75 | ), 76 | MyListItem( 77 | route: '/procedural-generation', 78 | title: 'InteractiveViewer.builder Procedural Generation Example', 79 | subtitle: 'Generate the content to build.', 80 | ), 81 | /* 82 | MyListItem( 83 | route: '/iv-builder-table', 84 | title: 'InteractiveViewer Builder Table Example', 85 | subtitle: 'Build only the visible parts of a table.', 86 | ), 87 | */ 88 | ], 89 | ), 90 | ); 91 | } 92 | } 93 | 94 | class MyListItem extends StatelessWidget { 95 | MyListItem({ 96 | Key? key, 97 | required this.route, 98 | required this.subtitle, 99 | required this.title, 100 | }) : super(key: key); 101 | 102 | final String route; 103 | final String subtitle; 104 | final String title; 105 | 106 | @override 107 | Widget build(BuildContext context) { 108 | return GestureDetector( 109 | onTap: () { 110 | Navigator.of(context).pushNamed(route); 111 | }, 112 | child: Card( 113 | margin: EdgeInsets.all(12.0), 114 | child: Padding( 115 | padding: EdgeInsets.all(24.0), 116 | child: ListTile( 117 | title: Text(title), 118 | subtitle: Text(subtitle), 119 | ), 120 | ), 121 | ), 122 | ); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /lib/map_data.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math' show Random; 2 | import 'dart:ui' show Offset, Size; 3 | 4 | import 'constants.dart'; 5 | import 'layer.dart'; 6 | 7 | class MapData { 8 | MapData({ 9 | required this.seed, 10 | }); 11 | 12 | final int seed; 13 | 14 | TileData getTileDataAt(Location location) { 15 | return TileData.generate(location, seed); 16 | } 17 | 18 | TileData getLowestTileDataAtScreenOffset(Offset offset) { 19 | return TileData.generate( 20 | Location( 21 | row: (offset.dy / cellSize.height).floor(), 22 | column: (offset.dx / cellSize.width).floor(), 23 | layerType: LayerType.local, 24 | ), 25 | seed); 26 | } 27 | } 28 | 29 | class TileData { 30 | TileData({ 31 | required this.location, 32 | required this.aLocations, 33 | required this.bLocations, 34 | this.parent, 35 | required this.seed, 36 | required this.terrain, 37 | }); 38 | 39 | factory TileData.generate(Location location, int seed) { 40 | TileData? parent; 41 | if (location.layerType != LayerType.galactic) { 42 | parent = TileData.generate( 43 | location.parent, 44 | seed, 45 | ); 46 | } 47 | 48 | final Random random = 49 | Random('${location.row},${location.column},$seed'.hashCode); 50 | final TerrainType terrainType = _getTerrainType(parent, location, random); 51 | 52 | final List aLocations = [ 53 | for (int i = 0; i < random.nextInt(_maxLocations); i++) 54 | Location( 55 | row: 1 + random.nextInt(Layer.layerScale - 2), 56 | column: 1 + random.nextInt(Layer.layerScale - 2), 57 | layerType: location.layerType, 58 | ), 59 | ]; 60 | final List bLocations = [ 61 | if (random.nextInt(1000) > 988) 62 | Location( 63 | row: 1 + random.nextInt(Layer.layerScale - 2), 64 | column: 1 + random.nextInt(Layer.layerScale - 2), 65 | layerType: location.layerType, 66 | ), 67 | ]; 68 | 69 | return TileData( 70 | location: location, 71 | aLocations: aLocations, 72 | bLocations: bLocations, 73 | seed: seed, 74 | terrain: _typeToTerrain[terrainType]!, 75 | parent: parent, 76 | ); 77 | } 78 | 79 | static const int _maxLocations = 3; 80 | 81 | static TerrainType _getTerrainType( 82 | TileData? parent, Location location, Random random) { 83 | if (parent == null) { 84 | return _galacticTerrainTypes[ 85 | random.nextInt(_galacticTerrainTypes.length)]; 86 | } 87 | 88 | // Always put a planet near the origin. 89 | if (location.row == 0 && location.column == 0) { 90 | switch (location.layerType) { 91 | case LayerType.galactic: 92 | return TerrainType.solarSystem; 93 | case LayerType.solar: 94 | return TerrainType.planet; 95 | case LayerType.terrestrial: 96 | case LayerType.local: 97 | break; 98 | /* 99 | case LayerType.terrestrial: 100 | return TerrainType.continent; 101 | case LayerType.local: 102 | return TerrainType.grassland; 103 | */ 104 | } 105 | } 106 | 107 | // Continents are surrounded by water. 108 | if (parent.terrain.terrainType == TerrainType.continent && 109 | location.isInCircularEdge()) { 110 | return TerrainType.water; 111 | } 112 | 113 | // Planets are surrounded by space. 114 | if ((parent.terrain.terrainType == TerrainType.planet || 115 | parent.terrain.terrainType == TerrainType.star) && 116 | location.isInCircularEdge()) { 117 | return TerrainType.terrestrialSpace; 118 | } 119 | 120 | // Stars are surrounded by space. 121 | if (parent.terrain.terrainType == TerrainType.planet && 122 | location.isInCircularEdge()) { 123 | return TerrainType.terrestrialSpace; 124 | } 125 | 126 | List childTerrainTypes = 127 | List.from(parent.terrain.childTerrainTypes!); 128 | 129 | // Only 1 star in a solar system. 130 | if (parent.terrain.terrainType == TerrainType.solarSystem) { 131 | if (location.row % 10 == 5 && location.column % 10 == 5) { 132 | return TerrainType.star; 133 | } 134 | if (location.isInCircularEdge()) { 135 | return TerrainType.solarSpace; 136 | } 137 | assert(childTerrainTypes.contains(TerrainType.star)); 138 | childTerrainTypes.remove(TerrainType.star); 139 | } 140 | 141 | // Choose a random type that fits the parent. 142 | return childTerrainTypes[random.nextInt(childTerrainTypes.length)]; 143 | } 144 | 145 | // Easy way to get a loation by row, column when stored in an iterable by a 146 | // 1D index. 147 | // 148 | // row and column are local to the parent, not global location. 149 | static TileData getByRowColumn( 150 | Iterable tileDatas, int row, int column) { 151 | final int index = row * Layer.layerScale + column; 152 | assert(index >= 0 && index < tileDatas.length, 153 | 'Invalid index $index for tileDatas of length ${tileDatas.length}.'); 154 | return tileDatas.elementAt(index); 155 | } 156 | 157 | final Location location; 158 | final Iterable aLocations; 159 | final Iterable bLocations; 160 | final TileData? parent; 161 | final int seed; 162 | final Terrain terrain; 163 | 164 | Iterable? _children; 165 | Iterable? get children { 166 | if (_children != null) { 167 | return _children; 168 | } 169 | _children = 170 | Iterable.generate(Layer.layerScale * Layer.layerScale, (int index) { 171 | return TileData.generate(location.children!.elementAt(index), seed); 172 | }); 173 | return _children; 174 | } 175 | 176 | Size get size => layers[location.layerType]!.size; 177 | 178 | @override 179 | String toString() { 180 | return 'TileData with terrain $terrain'; 181 | } 182 | 183 | @override 184 | int get hashCode => location.hashCode; 185 | 186 | @override 187 | bool operator ==(dynamic other) { 188 | if (other is! TileData) { 189 | return false; 190 | } 191 | 192 | return other.location == location; 193 | } 194 | } 195 | 196 | class Terrain { 197 | const Terrain({ 198 | this.layer, 199 | required this.terrainType, 200 | this.childTerrainTypes, 201 | this.limitPerParent, 202 | }); 203 | 204 | final TerrainType terrainType; 205 | final LayerType? layer; 206 | final List? childTerrainTypes; 207 | final int? limitPerParent; 208 | 209 | @override 210 | String toString() { 211 | return 'Terrain of type $terrainType with childTerrainTypes: $childTerrainTypes'; 212 | } 213 | } 214 | 215 | const Map _typeToTerrain = { 216 | TerrainType.solarSystem: Terrain( 217 | terrainType: TerrainType.solarSystem, 218 | layer: LayerType.galactic, 219 | limitPerParent: 30, 220 | childTerrainTypes: [ 221 | TerrainType.star, 222 | TerrainType.planet, 223 | TerrainType.solarSpace, 224 | TerrainType.solarSpace, 225 | TerrainType.solarSpace, 226 | TerrainType.solarSpace, 227 | TerrainType.solarSpace, 228 | ], 229 | ), 230 | TerrainType.galacticSpace: Terrain( 231 | terrainType: TerrainType.galacticSpace, 232 | layer: LayerType.galactic, 233 | childTerrainTypes: [ 234 | TerrainType.solarSpace, 235 | ], 236 | ), 237 | TerrainType.solarSpace: Terrain( 238 | terrainType: TerrainType.solarSpace, 239 | layer: LayerType.solar, 240 | childTerrainTypes: [ 241 | TerrainType.terrestrialSpace, 242 | ], 243 | ), 244 | TerrainType.star: Terrain( 245 | terrainType: TerrainType.star, 246 | layer: LayerType.solar, 247 | childTerrainTypes: [ 248 | TerrainType.terrestrialStar, 249 | ], 250 | ), 251 | TerrainType.planet: Terrain( 252 | terrainType: TerrainType.planet, 253 | layer: LayerType.solar, 254 | childTerrainTypes: [ 255 | TerrainType.ocean, 256 | TerrainType.continent, 257 | ], 258 | ), 259 | TerrainType.continent: Terrain( 260 | terrainType: TerrainType.continent, 261 | layer: LayerType.terrestrial, 262 | childTerrainTypes: [ 263 | TerrainType.grassland, 264 | TerrainType.grassland, 265 | TerrainType.grassland, 266 | TerrainType.grassland, 267 | TerrainType.grassland, 268 | TerrainType.water, 269 | ], 270 | ), 271 | TerrainType.ocean: Terrain( 272 | terrainType: TerrainType.ocean, 273 | layer: LayerType.terrestrial, 274 | childTerrainTypes: [ 275 | TerrainType.water, 276 | ], 277 | ), 278 | TerrainType.terrestrialSpace: Terrain( 279 | terrainType: TerrainType.terrestrialSpace, 280 | layer: LayerType.terrestrial, 281 | childTerrainTypes: [ 282 | TerrainType.localSpace, 283 | ], 284 | ), 285 | TerrainType.terrestrialStar: Terrain( 286 | terrainType: TerrainType.terrestrialStar, 287 | layer: LayerType.terrestrial, 288 | childTerrainTypes: [ 289 | TerrainType.localStar, 290 | ], 291 | ), 292 | TerrainType.grassland: Terrain( 293 | terrainType: TerrainType.grassland, 294 | layer: LayerType.local, 295 | ), 296 | TerrainType.water: Terrain( 297 | terrainType: TerrainType.water, 298 | layer: LayerType.local, 299 | ), 300 | TerrainType.localSpace: Terrain( 301 | terrainType: TerrainType.localSpace, 302 | layer: LayerType.local, 303 | ), 304 | TerrainType.localStar: Terrain( 305 | terrainType: TerrainType.localStar, 306 | layer: LayerType.local, 307 | ), 308 | }; 309 | 310 | const List _galacticTerrainTypes = [ 311 | TerrainType.solarSystem, 312 | TerrainType.galacticSpace, 313 | ]; 314 | 315 | enum TerrainType { 316 | grassland, 317 | water, 318 | localSpace, 319 | localStar, 320 | continent, 321 | ocean, 322 | galacticSpace, 323 | solarSpace, 324 | terrestrialSpace, 325 | solarSystem, 326 | star, 327 | terrestrialStar, 328 | planet, 329 | } 330 | 331 | // Row and column are local to the given layerType. 332 | class Location { 333 | Location({ 334 | required this.row, 335 | required this.column, 336 | required this.layerType, 337 | }); 338 | 339 | Location get parent { 340 | final LayerType parentLayerType = layers[layerType]!.parent!; 341 | return Location( 342 | row: (row / Layer.layerScale).floor(), 343 | column: (column / Layer.layerScale).floor(), 344 | layerType: parentLayerType, 345 | ); 346 | } 347 | 348 | bool isInCircularEdge() { 349 | final int normalRow = row % 10; 350 | final int normalColumn = column % 10; 351 | 352 | // Square edge. 353 | if (normalRow == 0 || 354 | normalRow == 9 || 355 | normalColumn == 0 || 356 | normalColumn == 9) { 357 | return true; 358 | } 359 | 360 | // Top cut out. 361 | if (normalRow == 1 && (normalColumn == 1 || normalColumn == 8)) { 362 | return true; 363 | } 364 | 365 | // Bottom cut out. 366 | if (normalRow == 8 && (normalColumn == 1 || normalColumn == 8)) { 367 | return true; 368 | } 369 | 370 | return false; 371 | } 372 | 373 | final int row; 374 | final int column; 375 | final LayerType layerType; 376 | 377 | // The index goes like this: 378 | // 0: (0, 0) 379 | // 1: (0, 1) 380 | // ... 381 | // 9: (0, 9) 382 | // 10: (1, 0) 383 | // 11: (1, 1) 384 | // ... 385 | Iterable? _children; 386 | Iterable? get children { 387 | if (_children != null) { 388 | return _children; 389 | } 390 | assert(layerType != LayerType.local); 391 | 392 | final int startingRow = row * Layer.layerScale; 393 | final int startingColumn = column * Layer.layerScale; 394 | _children = 395 | Iterable.generate(Layer.layerScale * Layer.layerScale, (int index) { 396 | return Location( 397 | row: startingRow + (index / Layer.layerScale).floor(), 398 | column: startingColumn + index % Layer.layerScale, 399 | layerType: layers[layerType]!.child!, 400 | ); 401 | }); 402 | return _children; 403 | } 404 | 405 | @override 406 | String toString() { 407 | return 'Location ($row, $column) in layer $layerType'; 408 | } 409 | 410 | @override 411 | int get hashCode => '$row,$column,$layerType'.hashCode; 412 | 413 | @override 414 | bool operator ==(dynamic other) { 415 | if (other is! Location) { 416 | return false; 417 | } 418 | 419 | return other.row == row && 420 | other.column == column && 421 | other.layerType == layerType; 422 | } 423 | } 424 | -------------------------------------------------------------------------------- /lib/marty.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math' show Random; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter/widgets.dart'; 5 | 6 | import 'rive_asset.dart'; 7 | 8 | class Marty extends RiveAsset { 9 | Marty({ 10 | Key? key, 11 | required int index, 12 | bool isBackgroundTransparent = false, 13 | }) : super( 14 | key: key, 15 | asset: isBackgroundTransparent 16 | ? 'assets/marty_transparent.riv' 17 | : 'assets/marty_v6.riv', 18 | //animationIndex: index % 2, 19 | animationIndex: Random().nextInt(2), 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /lib/planet.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'rive_asset.dart'; 5 | 6 | class Planet extends RiveAsset { 7 | const Planet({ 8 | Key? key, 9 | }) : super( 10 | key: key, 11 | asset: 'assets/planet.riv', 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /lib/procedural_generation_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math' show pow, max; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:vector_math/vector_math_64.dart' show Quad; 5 | 6 | import 'cloud.dart'; 7 | import 'constants.dart'; 8 | import 'fire.dart'; 9 | import 'grass.dart'; 10 | import 'helpers.dart'; 11 | import 'layer.dart'; 12 | import 'map_data.dart'; 13 | import 'marty.dart'; 14 | import 'planet.dart'; 15 | import 'star.dart'; 16 | import 'star_close.dart'; 17 | import 'ufo.dart'; 18 | import 'wave.dart'; 19 | 20 | class ProceduralGenerationPage extends StatefulWidget { 21 | const ProceduralGenerationPage({Key? key}) : super(key: key); 22 | 23 | static const String routeName = '/procedural-generation'; 24 | 25 | @override 26 | _ProceduralGenerationPageState createState() => 27 | _ProceduralGenerationPageState(); 28 | } 29 | 30 | class _ProceduralGenerationPageState extends State { 31 | final TransformationController _transformationController = 32 | TransformationController(); 33 | 34 | static const double _minScale = 0.006; 35 | static const double _maxScale = 10.5; 36 | 37 | void _onChangeTransformation() { 38 | setState(() {}); 39 | } 40 | 41 | @override 42 | void initState() { 43 | super.initState(); 44 | _transformationController.addListener(_onChangeTransformation); 45 | } 46 | 47 | @override 48 | void dispose() { 49 | _transformationController.removeListener(_onChangeTransformation); 50 | super.dispose(); 51 | } 52 | 53 | @override 54 | Widget build(BuildContext context) { 55 | return Scaffold( 56 | appBar: AppBar( 57 | title: const Text('Procedural Generation'), 58 | actions: [], 59 | ), 60 | body: Center( 61 | child: LayoutBuilder( 62 | builder: (BuildContext context, BoxConstraints constraints) { 63 | return InteractiveViewer.builder( 64 | transformationController: _transformationController, 65 | maxScale: _maxScale, 66 | minScale: _minScale, 67 | boundaryMargin: EdgeInsets.all(double.infinity), 68 | builder: (BuildContext context, Quad viewport) { 69 | return _MapGrid( 70 | viewport: axisAlignedBoundingBox(viewport), 71 | ); 72 | }, 73 | ); 74 | }, 75 | ), 76 | ), 77 | ); 78 | } 79 | } 80 | 81 | class _MapGrid extends StatefulWidget { 82 | _MapGrid({ 83 | Key? key, 84 | this.viewport, 85 | }) : super(key: key); 86 | 87 | final Rect? viewport; 88 | 89 | @override 90 | _MapGridState createState() => _MapGridState(); 91 | } 92 | 93 | class _MapGridState extends State<_MapGrid> { 94 | final MapData _mapData = MapData(seed: 80); 95 | Set _visibleTileDatas = Set(); 96 | 97 | Rect? _cachedViewport; 98 | late int _firstVisibleColumn; 99 | late int _firstVisibleRow; 100 | late int _lastVisibleColumn; 101 | late int _lastVisibleRow; 102 | bool _isCellVisible(int row, int column, final LayerType layerType) { 103 | if (widget.viewport != _cachedViewport) { 104 | _cachedViewport = widget.viewport; 105 | int layerExponent = 0; 106 | LayerType? currentLayerType = layers[layerType]!.child; 107 | while (currentLayerType != null) { 108 | layerExponent++; 109 | currentLayerType = layers[currentLayerType]!.child; 110 | } 111 | final int layerScale = pow(10, layerExponent) as int; 112 | _firstVisibleRow = 113 | (widget.viewport!.top / (cellSize.height * layerScale)).floor(); 114 | _firstVisibleColumn = 115 | (widget.viewport!.left / (cellSize.width * layerScale)).floor(); 116 | _lastVisibleRow = 117 | (widget.viewport!.bottom / (cellSize.height * layerScale)).floor(); 118 | _lastVisibleColumn = 119 | (widget.viewport!.right / (cellSize.width * layerScale)).floor(); 120 | } 121 | 122 | return row >= _firstVisibleRow && 123 | row <= _lastVisibleRow && 124 | column >= _firstVisibleColumn && 125 | column <= _lastVisibleColumn; 126 | } 127 | 128 | void _updateVisibleTileDatas(LayerType parentLayerType, TileData center) { 129 | Set nextVisibleTileDatas = Set(); 130 | for (int row = center.location.row - 1; 131 | row <= center.location.row + 1; 132 | row++) { 133 | for (int column = center.location.column - 1; 134 | column <= center.location.column + 1; 135 | column++) { 136 | final TileData tileData = _mapData.getTileDataAt(Location( 137 | row: row, 138 | column: column, 139 | layerType: parentLayerType, 140 | )); 141 | if (_visibleTileDatas.contains(tileData)) { 142 | nextVisibleTileDatas.add(_visibleTileDatas.lookup(tileData)); 143 | } else { 144 | nextVisibleTileDatas.add(tileData); 145 | } 146 | } 147 | } 148 | _visibleTileDatas = nextVisibleTileDatas; 149 | } 150 | 151 | @override 152 | Widget build(BuildContext context) { 153 | //LayerType parentLayerType = _visibleTileDatas.first.location.layerType; 154 | LayerType parentLayerType; 155 | if (max(widget.viewport!.width, widget.viewport!.height) < 100) { 156 | parentLayerType = LayerType.local; 157 | } else if (max(widget.viewport!.width, widget.viewport!.height) < 1000) { 158 | parentLayerType = LayerType.terrestrial; 159 | } else if (max(widget.viewport!.width, widget.viewport!.height) < 10000) { 160 | parentLayerType = LayerType.solar; 161 | } else { 162 | parentLayerType = LayerType.galactic; 163 | } 164 | 165 | TileData center = 166 | _mapData.getLowestTileDataAtScreenOffset(widget.viewport!.center); 167 | while (center.location.layerType != parentLayerType) { 168 | center = center.parent!; 169 | } 170 | _updateVisibleTileDatas(parentLayerType, center); 171 | 172 | final Size size = layers[parentLayerType]!.size; 173 | 174 | return Container( 175 | width: size.width * 3, 176 | height: size.height * 3, 177 | clipBehavior: Clip.none, 178 | child: Stack( 179 | clipBehavior: Clip.none, 180 | children: [ 181 | Positioned( 182 | top: center.location.row * size.width - size.width, 183 | left: center.location.column * size.height - size.height, 184 | child: Column( 185 | children: [ 186 | for (int row = center.location.row - 1; 187 | row <= center.location.row + 1; 188 | row++) 189 | Row( 190 | children: [ 191 | for (int column = center.location.column - 1; 192 | column <= center.location.column + 1; 193 | column++) 194 | _isCellVisible(row, column, parentLayerType) 195 | ? _ParentMapTile( 196 | viewport: widget.viewport!, 197 | tileData: _visibleTileDatas 198 | .lookup(_mapData.getTileDataAt(Location( 199 | row: row, 200 | column: column, 201 | layerType: parentLayerType, 202 | )))!, 203 | ) 204 | : Container( 205 | width: size.width, 206 | height: size.height, 207 | ), 208 | ], 209 | ), 210 | ], 211 | ), 212 | ), 213 | ], 214 | ), 215 | ); 216 | } 217 | } 218 | 219 | // Render all of the children tiles of the given parent tile. 220 | class _ParentMapTile extends StatelessWidget { 221 | _ParentMapTile( 222 | {Key? key, 223 | // Render all the children tiles of this given tile. 224 | required this.tileData, 225 | required this.viewport}) 226 | : super(key: key ?? GlobalObjectKey(tileData)); 227 | 228 | final TileData tileData; 229 | final Rect viewport; 230 | 231 | // The visibility of child tiles. 232 | late final int _firstRow; 233 | late final int _firstColumn; 234 | late final int _firstVisibleColumn; 235 | int? _firstVisibleRow; 236 | late final int _lastVisibleColumn; 237 | late final int _lastVisibleRow; 238 | void _calculateVisibility() { 239 | // Only calculate this once. Also, not needed at all for local. 240 | if (_firstVisibleRow != null || 241 | tileData.location.layerType == LayerType.local) { 242 | return; 243 | } 244 | 245 | final int layerExponent = layers[tileData.location.layerType]!.level!; 246 | final int childLayerScale = pow(10, layerExponent - 1) as int; 247 | _firstRow = tileData.location.row * Layer.layerScale; 248 | _firstColumn = tileData.location.column * Layer.layerScale; 249 | _firstVisibleRow = 250 | (viewport.top / (cellSize.height * childLayerScale)).floor(); 251 | _firstVisibleColumn = 252 | (viewport.left / (cellSize.width * childLayerScale)).floor(); 253 | _lastVisibleRow = 254 | (viewport.bottom / (cellSize.height * childLayerScale)).floor(); 255 | _lastVisibleColumn = 256 | (viewport.right / (cellSize.width * childLayerScale)).floor(); 257 | } 258 | 259 | bool _isCellVisible(int row, int column) { 260 | final bool visible = row >= _firstVisibleRow! && 261 | row <= _lastVisibleRow && 262 | column >= _firstVisibleColumn && 263 | column <= _lastVisibleColumn; 264 | return visible; 265 | } 266 | 267 | @override 268 | Widget build(BuildContext context) { 269 | _calculateVisibility(); 270 | 271 | // Local tiles have no children. Just render one big _MapTile. 272 | if (tileData.location.layerType == LayerType.local) { 273 | return _MapTile(tileData: tileData); 274 | } 275 | 276 | final Layer parentLayer = layers[tileData.location.layerType]!; 277 | final Size size = layers[parentLayer.child!]!.size; 278 | 279 | return Column( 280 | children: [ 281 | for (int row = _firstRow; row < _firstRow + Layer.layerScale; row++) 282 | Row( 283 | children: [ 284 | for (int column = _firstColumn; 285 | column < _firstColumn + Layer.layerScale; 286 | column++) 287 | _isCellVisible(row, column) 288 | ? _MapTile( 289 | tileData: TileData.getByRowColumn(tileData.children!, 290 | row % Layer.layerScale, column % Layer.layerScale)) 291 | : SizedBox(width: size.width, height: size.height), 292 | ], 293 | ), 294 | ], 295 | ); 296 | } 297 | } 298 | 299 | class _MapTile extends StatelessWidget { 300 | _MapTile({ 301 | Key? key, 302 | required this.tileData, 303 | }) : super(key: key); 304 | 305 | final TileData tileData; 306 | 307 | Color get color { 308 | switch (tileData.terrain.terrainType) { 309 | case TerrainType.grassland: 310 | return Color(0xffa0ffa0); 311 | case TerrainType.continent: 312 | return Colors.lightGreenAccent; 313 | case TerrainType.planet: 314 | case TerrainType.solarSpace: 315 | case TerrainType.galacticSpace: 316 | case TerrainType.localSpace: 317 | case TerrainType.terrestrialSpace: 318 | case TerrainType.star: 319 | return Colors.black; 320 | case TerrainType.solarSystem: 321 | case TerrainType.terrestrialStar: 322 | case TerrainType.localStar: 323 | return Colors.yellow; 324 | case TerrainType.water: 325 | case TerrainType.ocean: 326 | return Colors.blue; 327 | } 328 | } 329 | 330 | // TODO(justinmc): These a and b location tile widgets should be cached so 331 | // that they aren't rebuilt on every pan/zoom. 332 | Widget? get _aLocation { 333 | switch (tileData.terrain.terrainType) { 334 | case TerrainType.grassland: 335 | return Grass(); 336 | case TerrainType.continent: 337 | case TerrainType.ocean: 338 | return Cloud(); 339 | case TerrainType.water: 340 | return SizedBox( 341 | width: 20.0, 342 | height: 20.0, 343 | child: Wave(), 344 | ); 345 | case TerrainType.galacticSpace: 346 | case TerrainType.solarSpace: 347 | case TerrainType.terrestrialSpace: 348 | case TerrainType.localSpace: 349 | case TerrainType.solarSystem: 350 | return SizedBox( 351 | width: 20.0, 352 | height: 20.0, 353 | child: Star(), 354 | ); 355 | case TerrainType.terrestrialStar: 356 | case TerrainType.localStar: 357 | return SizedBox( 358 | width: 20.0, 359 | height: 20.0, 360 | child: Fire(), 361 | ); 362 | case TerrainType.planet: 363 | case TerrainType.star: 364 | return null; 365 | } 366 | } 367 | 368 | Widget? get _bLocation { 369 | switch (tileData.terrain.terrainType) { 370 | case TerrainType.grassland: 371 | return Marty(index: 0, isBackgroundTransparent: true); 372 | case TerrainType.localSpace: 373 | return SizedBox( 374 | width: 20.0, 375 | height: 20.0, 376 | child: UFO(), 377 | ); 378 | case TerrainType.continent: 379 | case TerrainType.planet: 380 | case TerrainType.solarSpace: 381 | case TerrainType.galacticSpace: 382 | case TerrainType.terrestrialSpace: 383 | case TerrainType.star: 384 | case TerrainType.solarSystem: 385 | case TerrainType.localStar: 386 | case TerrainType.terrestrialStar: 387 | case TerrainType.ocean: 388 | case TerrainType.water: 389 | return null; 390 | } 391 | } 392 | 393 | @override 394 | Widget build(BuildContext context) { 395 | final int layerExponent = layers[tileData.location.layerType]!.level!; 396 | final int layerScale = pow(10, layerExponent) as int; 397 | return Container( 398 | width: tileData.size.width, 399 | height: tileData.size.height, 400 | /* 401 | decoration: BoxDecoration( 402 | border: Border.all(color: Colors.black) 403 | ), 404 | */ 405 | color: color, 406 | child: Stack( 407 | children: [ 408 | if (tileData.terrain.terrainType == TerrainType.star) 409 | Positioned( 410 | top: 0, 411 | left: 0, 412 | child: SizedBox( 413 | width: tileData.size.width, 414 | height: tileData.size.height, 415 | child: StarClose(), 416 | ), 417 | ), 418 | if (tileData.terrain.terrainType == TerrainType.planet) 419 | Positioned( 420 | top: 20.0 * layerScale, 421 | left: 20.0 * layerScale, 422 | child: SizedBox( 423 | width: tileData.size.width - 40.0 * layerScale, 424 | height: tileData.size.height - 40.0 * layerScale, 425 | child: Planet(), 426 | ), 427 | ), 428 | Positioned( 429 | top: 0, 430 | left: 0, 431 | child: Text( 432 | '${tileData.terrain.terrainType.toString().substring(12)}\n${tileData.location.row}, ${tileData.location.column}', 433 | style: TextStyle( 434 | color: Colors.grey, 435 | fontSize: 10.0 * layerScale, 436 | ), 437 | ), 438 | ), 439 | for (Location location in tileData.aLocations) 440 | Positioned( 441 | left: location.column * 442 | cellSize.width / 443 | Layer.layerScale * 444 | layerScale, 445 | top: location.row * 446 | cellSize.height / 447 | Layer.layerScale * 448 | layerScale, 449 | child: SizedBox( 450 | width: 20.0 * layerScale, 451 | height: 20.0 * layerScale, 452 | child: _aLocation, 453 | ), 454 | ), 455 | for (Location _ in tileData.bLocations) 456 | Positioned( 457 | /* 458 | left: location.column * cellSize.width / Layer.layerScale * layerScale, 459 | top: location.row * cellSize.height / Layer.layerScale * layerScale, 460 | */ 461 | left: 25.0 * layerScale, 462 | top: 25.0 * layerScale, 463 | child: SizedBox( 464 | width: 50.0 * layerScale, 465 | height: 50.0 * layerScale, 466 | child: _bLocation, 467 | ), 468 | ), 469 | ], 470 | ), 471 | ); 472 | } 473 | } 474 | -------------------------------------------------------------------------------- /lib/rive_asset.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'package:flutter/widgets.dart'; 4 | import 'package:rive/rive.dart'; 5 | 6 | class RiveAsset extends StatefulWidget { 7 | const RiveAsset({ 8 | Key? key, 9 | required this.asset, 10 | this.animationIndex = 0, 11 | }) : super(key: key); 12 | 13 | final String asset; // The path to the .riv file. 14 | final int animationIndex; 15 | 16 | @override 17 | _RiveAssetState createState() => _RiveAssetState(); 18 | } 19 | 20 | class _RiveAssetState extends State { 21 | Artboard? _riveArtboard; 22 | late RiveAnimationController _controller; 23 | bool _disposed = false; 24 | 25 | @override 26 | void initState() { 27 | super.initState(); 28 | 29 | // This will naively reload the asset for every instance of this widget. 30 | rootBundle.load(widget.asset).then( 31 | (data) async { 32 | if (_disposed) { 33 | return; 34 | } 35 | final file = RiveFile.import(data); 36 | 37 | final artboard = file.mainArtboard; 38 | _controller = 39 | SimpleAnimation(artboard.animations[widget.animationIndex].name); 40 | artboard.addController(_controller); 41 | setState(() { 42 | _riveArtboard = artboard; 43 | _controller.isActive = true; 44 | }); 45 | }, 46 | ); 47 | } 48 | 49 | @override 50 | void dispose() { 51 | _disposed = true; 52 | super.dispose(); 53 | } 54 | 55 | @override 56 | Widget build(BuildContext context) { 57 | return _riveArtboard == null 58 | ? const SizedBox() 59 | : Rive(artboard: _riveArtboard!); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/single_child_scroll_view_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'marty.dart'; 4 | 5 | class SingleChildScrollViewPage extends StatefulWidget { 6 | const SingleChildScrollViewPage({Key? key}) : super(key: key); 7 | 8 | static const String routeName = '/single-child-scroll-view'; 9 | 10 | @override 11 | _SingleChildScrollViewPageState createState() => 12 | _SingleChildScrollViewPageState(); 13 | } 14 | 15 | class _SingleChildScrollViewPageState extends State { 16 | static const _itemCount = 10; 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return Scaffold( 21 | appBar: AppBar( 22 | title: const Text('SingleChildScrollView'), 23 | actions: [], 24 | ), 25 | body: Center( 26 | child: Container( 27 | width: 400.0, 28 | height: 400.0, 29 | child: SingleChildScrollView( 30 | child: Column( 31 | children: [ 32 | for (int i = 0; i < _itemCount; i++) 33 | Container( 34 | height: 200, 35 | color: Colors.teal.withOpacity(i / _itemCount), 36 | child: Marty( 37 | index: i, 38 | ), 39 | ), 40 | ], 41 | ), 42 | ), 43 | ), 44 | ), 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/star.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'rive_asset.dart'; 5 | 6 | class Star extends RiveAsset { 7 | const Star({ 8 | Key? key, 9 | }) : super( 10 | key: key, 11 | asset: 'assets/star.riv', 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /lib/star_close.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'rive_asset.dart'; 5 | 6 | class StarClose extends RiveAsset { 7 | const StarClose({ 8 | Key? key, 9 | }) : super( 10 | key: key, 11 | asset: 'assets/star_close.riv', 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /lib/table_builder.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | typedef _CellBuilder = Widget Function( 5 | BuildContext context, int row, int column); 6 | 7 | class TableBuilder extends StatelessWidget { 8 | const TableBuilder({ 9 | required this.rowCount, 10 | required this.columnCount, 11 | required this.cellWidth, 12 | this.builder, 13 | }) : assert(rowCount > 0), 14 | assert(columnCount > 0); 15 | 16 | final int rowCount; 17 | final int columnCount; 18 | final double cellWidth; 19 | final _CellBuilder? builder; 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return Table( 24 | // ignore: prefer_const_literals_to_create_immutables 25 | columnWidths: { 26 | for (int column = 0; column < columnCount; column++) 27 | column: FixedColumnWidth(cellWidth), 28 | }, 29 | // ignore: prefer_const_literals_to_create_immutables 30 | children: [ 31 | for (int row = 0; row < rowCount; row++) 32 | // ignore: prefer_const_constructors 33 | TableRow( 34 | // ignore: prefer_const_literals_to_create_immutables 35 | children: [ 36 | for (int column = 0; column < columnCount; column++) 37 | builder!(context, row, column), 38 | ], 39 | ), 40 | ], 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/ufo.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'rive_asset.dart'; 5 | 6 | class UFO extends RiveAsset { 7 | const UFO({ 8 | Key? key, 9 | }) : super( 10 | key: key, 11 | asset: 'assets/ufo.riv', 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /lib/wave.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/widgets.dart'; 3 | 4 | import 'rive_asset.dart'; 5 | 6 | class Wave extends RiveAsset { 7 | const Wave({ 8 | Key? key, 9 | }) : super( 10 | key: key, 11 | asset: 'assets/wave.riv', 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "ephemeral/Flutter-Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | 9 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 10 | } 11 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; 13 | buildPhases = ( 14 | 33CC111E2044C6BF0003C045 /* ShellScript */, 15 | ); 16 | dependencies = ( 17 | ); 18 | name = "Flutter Assemble"; 19 | productName = FLX; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 25 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 26 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 27 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 28 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = 33CC10E52044A3C60003C045 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = 33CC111A2044C6BA0003C045; 37 | remoteInfo = FLX; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXCopyFilesBuildPhase section */ 42 | 33CC110E2044A8840003C045 /* Bundle Framework */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = ""; 46 | dstSubfolderSpec = 10; 47 | files = ( 48 | ); 49 | name = "Bundle Framework"; 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXCopyFilesBuildPhase section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 56 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; 57 | 33CC10ED2044A3C60003C045 /* procedural_generation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "procedural_generation.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 59 | 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 60 | 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 61 | 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; 62 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; 63 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 64 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 65 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; 66 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 67 | 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 68 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 69 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 70 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | 33CC10EA2044A3C60003C045 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | 33BA886A226E78AF003329D5 /* Configs */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */, 88 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 89 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 90 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, 91 | ); 92 | path = Configs; 93 | sourceTree = ""; 94 | }; 95 | 33CC10E42044A3C60003C045 = { 96 | isa = PBXGroup; 97 | children = ( 98 | 33FAB671232836740065AC1E /* Runner */, 99 | 33CEB47122A05771004F2AC0 /* Flutter */, 100 | 33CC10EE2044A3C60003C045 /* Products */, 101 | D73912EC22F37F3D000D13A0 /* Frameworks */, 102 | ); 103 | sourceTree = ""; 104 | }; 105 | 33CC10EE2044A3C60003C045 /* Products */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 33CC10ED2044A3C60003C045 /* procedural_generation.app */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | 33CC11242044D66E0003C045 /* Resources */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 33CC10F22044A3C60003C045 /* Assets.xcassets */, 117 | 33CC10F42044A3C60003C045 /* MainMenu.xib */, 118 | 33CC10F72044A3C60003C045 /* Info.plist */, 119 | ); 120 | name = Resources; 121 | path = ..; 122 | sourceTree = ""; 123 | }; 124 | 33CEB47122A05771004F2AC0 /* Flutter */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, 128 | 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 129 | 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 130 | 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, 131 | ); 132 | path = Flutter; 133 | sourceTree = ""; 134 | }; 135 | 33FAB671232836740065AC1E /* Runner */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */, 139 | 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, 140 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */, 141 | 33E51914231749380026EE4D /* Release.entitlements */, 142 | 33CC11242044D66E0003C045 /* Resources */, 143 | 33BA886A226E78AF003329D5 /* Configs */, 144 | ); 145 | path = Runner; 146 | sourceTree = ""; 147 | }; 148 | D73912EC22F37F3D000D13A0 /* Frameworks */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | ); 152 | name = Frameworks; 153 | sourceTree = ""; 154 | }; 155 | /* End PBXGroup section */ 156 | 157 | /* Begin PBXNativeTarget section */ 158 | 33CC10EC2044A3C60003C045 /* Runner */ = { 159 | isa = PBXNativeTarget; 160 | buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; 161 | buildPhases = ( 162 | 33CC10E92044A3C60003C045 /* Sources */, 163 | 33CC10EA2044A3C60003C045 /* Frameworks */, 164 | 33CC10EB2044A3C60003C045 /* Resources */, 165 | 33CC110E2044A8840003C045 /* Bundle Framework */, 166 | 3399D490228B24CF009A79C7 /* ShellScript */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | 33CC11202044C79F0003C045 /* PBXTargetDependency */, 172 | ); 173 | name = Runner; 174 | productName = Runner; 175 | productReference = 33CC10ED2044A3C60003C045 /* procedural_generation.app */; 176 | productType = "com.apple.product-type.application"; 177 | }; 178 | /* End PBXNativeTarget section */ 179 | 180 | /* Begin PBXProject section */ 181 | 33CC10E52044A3C60003C045 /* Project object */ = { 182 | isa = PBXProject; 183 | attributes = { 184 | LastSwiftUpdateCheck = 0920; 185 | LastUpgradeCheck = 0930; 186 | ORGANIZATIONNAME = ""; 187 | TargetAttributes = { 188 | 33CC10EC2044A3C60003C045 = { 189 | CreatedOnToolsVersion = 9.2; 190 | LastSwiftMigration = 1100; 191 | ProvisioningStyle = Automatic; 192 | SystemCapabilities = { 193 | com.apple.Sandbox = { 194 | enabled = 1; 195 | }; 196 | }; 197 | }; 198 | 33CC111A2044C6BA0003C045 = { 199 | CreatedOnToolsVersion = 9.2; 200 | ProvisioningStyle = Manual; 201 | }; 202 | }; 203 | }; 204 | buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; 205 | compatibilityVersion = "Xcode 9.3"; 206 | developmentRegion = en; 207 | hasScannedForEncodings = 0; 208 | knownRegions = ( 209 | en, 210 | Base, 211 | ); 212 | mainGroup = 33CC10E42044A3C60003C045; 213 | productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; 214 | projectDirPath = ""; 215 | projectRoot = ""; 216 | targets = ( 217 | 33CC10EC2044A3C60003C045 /* Runner */, 218 | 33CC111A2044C6BA0003C045 /* Flutter Assemble */, 219 | ); 220 | }; 221 | /* End PBXProject section */ 222 | 223 | /* Begin PBXResourcesBuildPhase section */ 224 | 33CC10EB2044A3C60003C045 /* Resources */ = { 225 | isa = PBXResourcesBuildPhase; 226 | buildActionMask = 2147483647; 227 | files = ( 228 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, 229 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXResourcesBuildPhase section */ 234 | 235 | /* Begin PBXShellScriptBuildPhase section */ 236 | 3399D490228B24CF009A79C7 /* ShellScript */ = { 237 | isa = PBXShellScriptBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | ); 241 | inputFileListPaths = ( 242 | ); 243 | inputPaths = ( 244 | ); 245 | outputFileListPaths = ( 246 | ); 247 | outputPaths = ( 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | shellPath = /bin/sh; 251 | shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; 252 | }; 253 | 33CC111E2044C6BF0003C045 /* ShellScript */ = { 254 | isa = PBXShellScriptBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | inputFileListPaths = ( 259 | Flutter/ephemeral/FlutterInputs.xcfilelist, 260 | ); 261 | inputPaths = ( 262 | Flutter/ephemeral/tripwire, 263 | ); 264 | outputFileListPaths = ( 265 | Flutter/ephemeral/FlutterOutputs.xcfilelist, 266 | ); 267 | outputPaths = ( 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | shellPath = /bin/sh; 271 | shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; 272 | }; 273 | /* End PBXShellScriptBuildPhase section */ 274 | 275 | /* Begin PBXSourcesBuildPhase section */ 276 | 33CC10E92044A3C60003C045 /* Sources */ = { 277 | isa = PBXSourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, 281 | 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, 282 | 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin PBXTargetDependency section */ 289 | 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { 290 | isa = PBXTargetDependency; 291 | target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; 292 | targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; 293 | }; 294 | /* End PBXTargetDependency section */ 295 | 296 | /* Begin PBXVariantGroup section */ 297 | 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { 298 | isa = PBXVariantGroup; 299 | children = ( 300 | 33CC10F52044A3C60003C045 /* Base */, 301 | ); 302 | name = MainMenu.xib; 303 | path = Runner; 304 | sourceTree = ""; 305 | }; 306 | /* End PBXVariantGroup section */ 307 | 308 | /* Begin XCBuildConfiguration section */ 309 | 338D0CE9231458BD00FA5F75 /* Profile */ = { 310 | isa = XCBuildConfiguration; 311 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 316 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 317 | CLANG_CXX_LIBRARY = "libc++"; 318 | CLANG_ENABLE_MODULES = YES; 319 | CLANG_ENABLE_OBJC_ARC = YES; 320 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 326 | CLANG_WARN_EMPTY_BODY = YES; 327 | CLANG_WARN_ENUM_CONVERSION = YES; 328 | CLANG_WARN_INFINITE_RECURSION = YES; 329 | CLANG_WARN_INT_CONVERSION = YES; 330 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 335 | CODE_SIGN_IDENTITY = "-"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_NS_ASSERTIONS = NO; 339 | ENABLE_STRICT_OBJC_MSGSEND = YES; 340 | GCC_C_LANGUAGE_STANDARD = gnu11; 341 | GCC_NO_COMMON_BLOCKS = YES; 342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | MACOSX_DEPLOYMENT_TARGET = 10.11; 348 | MTL_ENABLE_DEBUG_INFO = NO; 349 | SDKROOT = macosx; 350 | SWIFT_COMPILATION_MODE = wholemodule; 351 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 352 | }; 353 | name = Profile; 354 | }; 355 | 338D0CEA231458BD00FA5F75 /* Profile */ = { 356 | isa = XCBuildConfiguration; 357 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | CLANG_ENABLE_MODULES = YES; 361 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; 362 | CODE_SIGN_STYLE = Automatic; 363 | COMBINE_HIDPI_IMAGES = YES; 364 | INFOPLIST_FILE = Runner/Info.plist; 365 | LD_RUNPATH_SEARCH_PATHS = ( 366 | "$(inherited)", 367 | "@executable_path/../Frameworks", 368 | ); 369 | PROVISIONING_PROFILE_SPECIFIER = ""; 370 | SWIFT_VERSION = 5.0; 371 | }; 372 | name = Profile; 373 | }; 374 | 338D0CEB231458BD00FA5F75 /* Profile */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | CODE_SIGN_STYLE = Manual; 378 | PRODUCT_NAME = "$(TARGET_NAME)"; 379 | }; 380 | name = Profile; 381 | }; 382 | 33CC10F92044A3C60003C045 /* Debug */ = { 383 | isa = XCBuildConfiguration; 384 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 385 | buildSettings = { 386 | ALWAYS_SEARCH_USER_PATHS = NO; 387 | CLANG_ANALYZER_NONNULL = YES; 388 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 390 | CLANG_CXX_LIBRARY = "libc++"; 391 | CLANG_ENABLE_MODULES = YES; 392 | CLANG_ENABLE_OBJC_ARC = YES; 393 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 394 | CLANG_WARN_BOOL_CONVERSION = YES; 395 | CLANG_WARN_CONSTANT_CONVERSION = YES; 396 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 397 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 398 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 399 | CLANG_WARN_EMPTY_BODY = YES; 400 | CLANG_WARN_ENUM_CONVERSION = YES; 401 | CLANG_WARN_INFINITE_RECURSION = YES; 402 | CLANG_WARN_INT_CONVERSION = YES; 403 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 404 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 405 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 406 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 407 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 408 | CODE_SIGN_IDENTITY = "-"; 409 | COPY_PHASE_STRIP = NO; 410 | DEBUG_INFORMATION_FORMAT = dwarf; 411 | ENABLE_STRICT_OBJC_MSGSEND = YES; 412 | ENABLE_TESTABILITY = YES; 413 | GCC_C_LANGUAGE_STANDARD = gnu11; 414 | GCC_DYNAMIC_NO_PIC = NO; 415 | GCC_NO_COMMON_BLOCKS = YES; 416 | GCC_OPTIMIZATION_LEVEL = 0; 417 | GCC_PREPROCESSOR_DEFINITIONS = ( 418 | "DEBUG=1", 419 | "$(inherited)", 420 | ); 421 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 422 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 424 | GCC_WARN_UNUSED_FUNCTION = YES; 425 | GCC_WARN_UNUSED_VARIABLE = YES; 426 | MACOSX_DEPLOYMENT_TARGET = 10.11; 427 | MTL_ENABLE_DEBUG_INFO = YES; 428 | ONLY_ACTIVE_ARCH = YES; 429 | SDKROOT = macosx; 430 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 431 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 432 | }; 433 | name = Debug; 434 | }; 435 | 33CC10FA2044A3C60003C045 /* Release */ = { 436 | isa = XCBuildConfiguration; 437 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 438 | buildSettings = { 439 | ALWAYS_SEARCH_USER_PATHS = NO; 440 | CLANG_ANALYZER_NONNULL = YES; 441 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 442 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 443 | CLANG_CXX_LIBRARY = "libc++"; 444 | CLANG_ENABLE_MODULES = YES; 445 | CLANG_ENABLE_OBJC_ARC = YES; 446 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 447 | CLANG_WARN_BOOL_CONVERSION = YES; 448 | CLANG_WARN_CONSTANT_CONVERSION = YES; 449 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 450 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 451 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 452 | CLANG_WARN_EMPTY_BODY = YES; 453 | CLANG_WARN_ENUM_CONVERSION = YES; 454 | CLANG_WARN_INFINITE_RECURSION = YES; 455 | CLANG_WARN_INT_CONVERSION = YES; 456 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 457 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 458 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 459 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 460 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 461 | CODE_SIGN_IDENTITY = "-"; 462 | COPY_PHASE_STRIP = NO; 463 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 464 | ENABLE_NS_ASSERTIONS = NO; 465 | ENABLE_STRICT_OBJC_MSGSEND = YES; 466 | GCC_C_LANGUAGE_STANDARD = gnu11; 467 | GCC_NO_COMMON_BLOCKS = YES; 468 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 469 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | MACOSX_DEPLOYMENT_TARGET = 10.11; 474 | MTL_ENABLE_DEBUG_INFO = NO; 475 | SDKROOT = macosx; 476 | SWIFT_COMPILATION_MODE = wholemodule; 477 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 478 | }; 479 | name = Release; 480 | }; 481 | 33CC10FC2044A3C60003C045 /* Debug */ = { 482 | isa = XCBuildConfiguration; 483 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 484 | buildSettings = { 485 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 486 | CLANG_ENABLE_MODULES = YES; 487 | CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; 488 | CODE_SIGN_STYLE = Automatic; 489 | COMBINE_HIDPI_IMAGES = YES; 490 | INFOPLIST_FILE = Runner/Info.plist; 491 | LD_RUNPATH_SEARCH_PATHS = ( 492 | "$(inherited)", 493 | "@executable_path/../Frameworks", 494 | ); 495 | PROVISIONING_PROFILE_SPECIFIER = ""; 496 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 497 | SWIFT_VERSION = 5.0; 498 | }; 499 | name = Debug; 500 | }; 501 | 33CC10FD2044A3C60003C045 /* Release */ = { 502 | isa = XCBuildConfiguration; 503 | baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; 504 | buildSettings = { 505 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 506 | CLANG_ENABLE_MODULES = YES; 507 | CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; 508 | CODE_SIGN_STYLE = Automatic; 509 | COMBINE_HIDPI_IMAGES = YES; 510 | INFOPLIST_FILE = Runner/Info.plist; 511 | LD_RUNPATH_SEARCH_PATHS = ( 512 | "$(inherited)", 513 | "@executable_path/../Frameworks", 514 | ); 515 | PROVISIONING_PROFILE_SPECIFIER = ""; 516 | SWIFT_VERSION = 5.0; 517 | }; 518 | name = Release; 519 | }; 520 | 33CC111C2044C6BA0003C045 /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | buildSettings = { 523 | CODE_SIGN_STYLE = Manual; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | }; 526 | name = Debug; 527 | }; 528 | 33CC111D2044C6BA0003C045 /* Release */ = { 529 | isa = XCBuildConfiguration; 530 | buildSettings = { 531 | CODE_SIGN_STYLE = Automatic; 532 | PRODUCT_NAME = "$(TARGET_NAME)"; 533 | }; 534 | name = Release; 535 | }; 536 | /* End XCBuildConfiguration section */ 537 | 538 | /* Begin XCConfigurationList section */ 539 | 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 33CC10F92044A3C60003C045 /* Debug */, 543 | 33CC10FA2044A3C60003C045 /* Release */, 544 | 338D0CE9231458BD00FA5F75 /* Profile */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { 550 | isa = XCConfigurationList; 551 | buildConfigurations = ( 552 | 33CC10FC2044A3C60003C045 /* Debug */, 553 | 33CC10FD2044A3C60003C045 /* Release */, 554 | 338D0CEA231458BD00FA5F75 /* Profile */, 555 | ); 556 | defaultConfigurationIsVisible = 0; 557 | defaultConfigurationName = Release; 558 | }; 559 | 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { 560 | isa = XCConfigurationList; 561 | buildConfigurations = ( 562 | 33CC111C2044C6BA0003C045 /* Debug */, 563 | 33CC111D2044C6BA0003C045 /* Release */, 564 | 338D0CEB231458BD00FA5F75 /* Profile */, 565 | ); 566 | defaultConfigurationIsVisible = 0; 567 | defaultConfigurationName = Release; 568 | }; 569 | /* End XCConfigurationList section */ 570 | }; 571 | rootObject = 33CC10E52044A3C60003C045 /* Project object */; 572 | } 573 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 64 | 65 | 71 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /macos/Runner/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | -------------------------------------------------------------------------------- /macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = Lazy Flutter Performance 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.proceduralGeneration 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2021 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.8.2" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.1.0" 18 | characters: 19 | dependency: transitive 20 | description: 21 | name: characters 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "1.2.0" 25 | charcode: 26 | dependency: transitive 27 | description: 28 | name: charcode 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.3.1" 32 | clock: 33 | dependency: transitive 34 | description: 35 | name: clock 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.0" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.16.0" 46 | cupertino_icons: 47 | dependency: "direct main" 48 | description: 49 | name: cupertino_icons 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.0.5" 53 | fake_async: 54 | dependency: transitive 55 | description: 56 | name: fake_async 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "1.3.0" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_test: 66 | dependency: "direct dev" 67 | description: flutter 68 | source: sdk 69 | version: "0.0.0" 70 | graphs: 71 | dependency: transitive 72 | description: 73 | name: graphs 74 | url: "https://pub.dartlang.org" 75 | source: hosted 76 | version: "2.1.0" 77 | http: 78 | dependency: transitive 79 | description: 80 | name: http 81 | url: "https://pub.dartlang.org" 82 | source: hosted 83 | version: "0.13.5" 84 | http_parser: 85 | dependency: transitive 86 | description: 87 | name: http_parser 88 | url: "https://pub.dartlang.org" 89 | source: hosted 90 | version: "4.0.1" 91 | matcher: 92 | dependency: transitive 93 | description: 94 | name: matcher 95 | url: "https://pub.dartlang.org" 96 | source: hosted 97 | version: "0.12.11" 98 | material_color_utilities: 99 | dependency: transitive 100 | description: 101 | name: material_color_utilities 102 | url: "https://pub.dartlang.org" 103 | source: hosted 104 | version: "0.1.4" 105 | meta: 106 | dependency: transitive 107 | description: 108 | name: meta 109 | url: "https://pub.dartlang.org" 110 | source: hosted 111 | version: "1.7.0" 112 | path: 113 | dependency: transitive 114 | description: 115 | name: path 116 | url: "https://pub.dartlang.org" 117 | source: hosted 118 | version: "1.8.1" 119 | rive: 120 | dependency: "direct main" 121 | description: 122 | name: rive 123 | url: "https://pub.dartlang.org" 124 | source: hosted 125 | version: "0.9.1" 126 | sky_engine: 127 | dependency: transitive 128 | description: flutter 129 | source: sdk 130 | version: "0.0.99" 131 | source_span: 132 | dependency: transitive 133 | description: 134 | name: source_span 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "1.8.2" 138 | stack_trace: 139 | dependency: transitive 140 | description: 141 | name: stack_trace 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "1.10.0" 145 | stream_channel: 146 | dependency: transitive 147 | description: 148 | name: stream_channel 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "2.1.0" 152 | string_scanner: 153 | dependency: transitive 154 | description: 155 | name: string_scanner 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "1.1.0" 159 | term_glyph: 160 | dependency: transitive 161 | description: 162 | name: term_glyph 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "1.2.0" 166 | test_api: 167 | dependency: transitive 168 | description: 169 | name: test_api 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "0.4.9" 173 | typed_data: 174 | dependency: transitive 175 | description: 176 | name: typed_data 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "1.3.1" 180 | vector_math: 181 | dependency: transitive 182 | description: 183 | name: vector_math 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "2.1.2" 187 | sdks: 188 | dart: ">=2.17.0-0 <3.0.0" 189 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: procedural_generation 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: '>=2.12.0 <3.0.0' 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.5 31 | rive: ^0.9.1 32 | 33 | dev_dependencies: 34 | flutter_test: 35 | sdk: flutter 36 | 37 | # For information on the generic Dart part of this file, see the 38 | # following page: https://dart.dev/tools/pub/pubspec 39 | 40 | # The following section is specific to Flutter. 41 | flutter: 42 | 43 | # The following line ensures that the Material Icons font is 44 | # included with your application, so that you can use the icons in 45 | # the material Icons class. 46 | uses-material-design: true 47 | 48 | # To add assets to your application, add an assets section, like this: 49 | assets: 50 | - assets/cloud.riv 51 | - assets/fire.riv 52 | - assets/grass.riv 53 | - assets/marty_v6.riv 54 | - assets/marty_transparent.riv 55 | - assets/planet.riv 56 | - assets/star.riv 57 | - assets/star_close.riv 58 | - assets/ufo.riv 59 | - assets/wave.riv 60 | 61 | # An image asset can refer to one or more resolution-specific "variants", see 62 | # https://flutter.dev/assets-and-images/#resolution-aware. 63 | 64 | # For details regarding adding assets from package dependencies, see 65 | # https://flutter.dev/assets-and-images/#from-packages 66 | 67 | # To add custom fonts to your application, add a fonts section here, 68 | # in this "flutter" section. Each entry in this list should have a 69 | # "family" key with the font family name, and a "fonts" key with a 70 | # list giving the asset and other descriptors for the font. For 71 | # example: 72 | # fonts: 73 | # - family: Schyler 74 | # fonts: 75 | # - asset: fonts/Schyler-Regular.ttf 76 | # - asset: fonts/Schyler-Italic.ttf 77 | # style: italic 78 | # - family: Trajan Pro 79 | # fonts: 80 | # - asset: fonts/TrajanPro.ttf 81 | # - asset: fonts/TrajanPro_Bold.ttf 82 | # weight: 700 83 | # 84 | # For details regarding fonts from package dependencies, 85 | # see https://flutter.dev/custom-fonts/#from-packages 86 | -------------------------------------------------------------------------------- /screenshots/1d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/screenshots/1d.png -------------------------------------------------------------------------------- /screenshots/2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/screenshots/2d.png -------------------------------------------------------------------------------- /screenshots/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/screenshots/menu.png -------------------------------------------------------------------------------- /screenshots/proc_gen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/screenshots/proc_gen.png -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:procedural_generation/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justinmc/flutter-lazy-performance/aff514fb62fd5172ce4c687d38a102f3a86e1633/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | procedural_generation 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "procedural_generation", 3 | "short_name": "procedural_generation", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | --------------------------------------------------------------------------------