Skip to content

Commit

Permalink
Makes example app null-safe (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
giovannicampagnolo committed Nov 19, 2022
1 parent d48ada7 commit 8b6dc98
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 217 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,8 @@
# Changelog

##0.7.3
* Update the examples with null-safety

## 0.7.2
* Fixes missing texturing on iOS

Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -20,7 +20,7 @@ Or manually add this to your `pubspec.yaml` file (and run `flutter pub get`):

```yaml
dependencies:
ar_flutter_plugin: ^0.7.2
ar_flutter_plugin: ^0.7.3
```

### Importing
Expand Down
108 changes: 53 additions & 55 deletions example/lib/examples/cloudanchorexample.dart
Expand Up @@ -19,7 +19,7 @@ import 'package:geoflutterfire/geoflutterfire.dart';
import 'package:geolocator/geolocator.dart';

class CloudAnchorWidget extends StatefulWidget {
CloudAnchorWidget({Key key}) : super(key: key);
CloudAnchorWidget({Key? key}) : super(key: key);
@override
_CloudAnchorWidgetState createState() => _CloudAnchorWidgetState();
}
Expand All @@ -31,10 +31,10 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
FirebaseManager firebaseManager = FirebaseManager();
Map<String, Map> anchorsInDownloadProgress = Map<String, Map>();

ARSessionManager arSessionManager;
ARObjectManager arObjectManager;
ARAnchorManager arAnchorManager;
ARLocationManager arLocationManager;
ARSessionManager? arSessionManager;
ARObjectManager? arObjectManager;
ARAnchorManager? arAnchorManager;
ARLocationManager? arLocationManager;

List<ARNode> nodes = [];
List<ARAnchor> anchors = [];
Expand All @@ -56,7 +56,7 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
@override
void dispose() {
super.dispose();
arSessionManager.dispose();
arSessionManager!.dispose();
}

@override
Expand Down Expand Up @@ -142,23 +142,23 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
this.arAnchorManager = arAnchorManager;
this.arLocationManager = arLocationManager;

this.arSessionManager.onInitialize(
this.arSessionManager!.onInitialize(
showFeaturePoints: false,
showPlanes: true,
customPlaneTexturePath: "Images/triangle.png",
showWorldOrigin: true,
);
this.arObjectManager.onInitialize();
this.arAnchorManager.initGoogleCloudAnchorMode();
this.arObjectManager!.onInitialize();
this.arAnchorManager!.initGoogleCloudAnchorMode();

this.arSessionManager.onPlaneOrPointTap = onPlaneOrPointTapped;
this.arObjectManager.onNodeTap = onNodeTapped;
this.arAnchorManager.onAnchorUploaded = onAnchorUploaded;
this.arAnchorManager.onAnchorDownloaded = onAnchorDownloaded;
this.arSessionManager!.onPlaneOrPointTap = onPlaneOrPointTapped;
this.arObjectManager!.onNodeTap = onNodeTapped;
this.arAnchorManager!.onAnchorUploaded = onAnchorUploaded;
this.arAnchorManager!.onAnchorDownloaded = onAnchorDownloaded;

this
.arLocationManager
.startLocationUpdates()
!.startLocationUpdates()
.then((value) => null)
.onError((error, stackTrace) {
switch (error.toString()) {
Expand All @@ -169,7 +169,7 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
"Action Required",
"To use cloud anchor functionality, please enable your location services",
"Settings",
this.arLocationManager.openLocationServicesSettings,
this.arLocationManager!.openLocationServicesSettings,
"Cancel");
break;
}
Expand All @@ -181,7 +181,7 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
"Action Required",
"To use cloud anchor functionality, please allow the app to access your device's location",
"Retry",
this.arLocationManager.startLocationUpdates,
this.arLocationManager!.startLocationUpdates,
"Cancel");
break;
}
Expand All @@ -193,24 +193,24 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
"Action Required",
"To use cloud anchor functionality, please allow the app to access your device's location",
"Settings",
this.arLocationManager.openAppPermissionSettings,
this.arLocationManager!.openAppPermissionSettings,
"Cancel");
break;
}

default:
{
this.arSessionManager.onError(error.toString());
this.arSessionManager!.onError(error.toString());
break;
}
}
this.arSessionManager.onError(error.toString());
this.arSessionManager!.onError(error.toString());
});
}

Future<void> onRemoveEverything() async {
anchors.forEach((anchor) {
this.arAnchorManager.removeAnchor(anchor);
this.arAnchorManager!.removeAnchor(anchor);
});
anchors = [];
if (lastUploadedAnchor != "") {
Expand All @@ -229,7 +229,7 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
Future<void> onNodeTapped(List<String> nodeNames) async {
var foregroundNode =
nodes.firstWhere((element) => element.name == nodeNames.first);
this.arSessionManager.onError(foregroundNode.data["onTapText"]);
this.arSessionManager!.onError(foregroundNode.data!["onTapText"]);
}

Future<void> onPlaneOrPointTapped(
Expand All @@ -239,36 +239,35 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
if (singleHitTestResult != null) {
var newAnchor = ARPlaneAnchor(
transformation: singleHitTestResult.worldTransform, ttl: 2);
bool? didAddAnchor = await this.arAnchorManager.addAnchor(newAnchor);
bool? didAddAnchor = await this.arAnchorManager!.addAnchor(newAnchor);
if (didAddAnchor ?? false) {
this.anchors.add(newAnchor);
// Add note to anchor
var newNode = ARNode(
type: NodeType.webGLB,
uri:
"https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/Duck/glTF-Binary/Duck.glb",
uri: "https://github.com/KhronosGroup/glTF-Sample-Models/raw/master/2.0/Duck/glTF-Binary/Duck.glb",
scale: Vector3(0.2, 0.2, 0.2),
position: Vector3(0.0, 0.0, 0.0),
rotation: Vector4(1.0, 0.0, 0.0, 0.0),
data: {"onTapText": "Ouch, that hurt!"});
bool? didAddNodeToAnchor =
await this.arObjectManager.addNode(newNode, planeAnchor: newAnchor);
await this.arObjectManager!.addNode(newNode, planeAnchor: newAnchor);
if (didAddNodeToAnchor ?? false) {
this.nodes.add(newNode);
setState(() {
readyToUpload = true;
});
} else {
this.arSessionManager.onError("Adding Node to Anchor failed");
this.arSessionManager!.onError("Adding Node to Anchor failed");
}
} else {
this.arSessionManager.onError("Adding Anchor failed");
this.arSessionManager!.onError("Adding Anchor failed");
}
}
}

Future<void> onUploadButtonPressed() async {
this.arAnchorManager.uploadAnchor(this.anchors.last);
this.arAnchorManager!.uploadAnchor(this.anchors.last);
setState(() {
readyToUpload = false;
});
Expand All @@ -277,7 +276,7 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
onAnchorUploaded(ARAnchor anchor) {
// Upload anchor information to firebase
firebaseManager.uploadAnchor(anchor,
currentLocation: this.arLocationManager.currentLocation);
currentLocation: this.arLocationManager!.currentLocation);
// Upload child nodes to firebase
if (anchor is ARPlaneAnchor) {
anchor.childNodes.forEach((nodeName) => firebaseManager.uploadObject(
Expand All @@ -287,20 +286,19 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
readyToDownload = true;
readyToUpload = false;
});
this.arSessionManager.onError("Upload successful");
this.arSessionManager!.onError("Upload successful");
}

ARAnchor onAnchorDownloaded(Map<String, dynamic> serializedAnchor) {
final anchor = ARPlaneAnchor.fromJson(
anchorsInDownloadProgress[serializedAnchor["cloudanchorid"]]);
ARAnchor onAnchorDownloaded(Map<String, dynamic>serializedAnchor) {
final anchor = ARPlaneAnchor.fromJson(anchorsInDownloadProgress[serializedAnchor["cloudanchorid"]] as Map<String, dynamic>);
anchorsInDownloadProgress.remove(anchor.cloudanchorid);
this.anchors.add(anchor);

// Download nodes attached to this anchor
firebaseManager.getObjectsFromAnchor(anchor, (snapshot) {
snapshot.docs.forEach((objectDoc) {
ARNode object = ARNode.fromMap(objectDoc.data());
arObjectManager.addNode(object, planeAnchor: anchor);
ARNode object = ARNode.fromMap(objectDoc.data() as Map<String, dynamic>);
arObjectManager!.addNode(object, planeAnchor: anchor);
this.nodes.add(object);
});
});
Expand All @@ -317,18 +315,18 @@ class _CloudAnchorWidgetState extends State<CloudAnchorWidget> {
//});

// Get anchors within a radius of 100m of the current device's location
if (this.arLocationManager.currentLocation != null) {
if (this.arLocationManager!.currentLocation != null) {
firebaseManager.downloadAnchorsByLocation((snapshot) {
final cloudAnchorId = snapshot.get("cloudanchorid");
anchorsInDownloadProgress[cloudAnchorId] = snapshot.data();
arAnchorManager.downloadAnchor(cloudAnchorId);
}, this.arLocationManager.currentLocation, 0.1);
anchorsInDownloadProgress[cloudAnchorId] = snapshot.data() as Map<String, dynamic>;
arAnchorManager!.downloadAnchor(cloudAnchorId);
}, this.arLocationManager!.currentLocation, 0.1);
setState(() {
readyToDownload = false;
});
} else {
this
.arSessionManager
.arSessionManager!
.onError("Location updates not running, can't download anchors");
}
}
Expand Down Expand Up @@ -376,10 +374,10 @@ typedef FirebaseDocumentStreamListener = void Function(
DocumentSnapshot snapshot);

class FirebaseManager {
FirebaseFirestore firestore;
Geoflutterfire geo;
CollectionReference anchorCollection;
CollectionReference objectCollection;
FirebaseFirestore? firestore;
Geoflutterfire? geo;
CollectionReference? anchorCollection;
CollectionReference? objectCollection;

// Firebase initialization function
Future<bool> initializeFlutterFire() async {
Expand All @@ -396,7 +394,7 @@ class FirebaseManager {
}
}

void uploadAnchor(ARAnchor anchor, {Position currentLocation}) {
void uploadAnchor(ARAnchor anchor, {Position? currentLocation}) {
if (firestore == null) return;

var serializedAnchor = anchor.toJson();
Expand All @@ -405,13 +403,13 @@ class FirebaseManager {
serializedAnchor["expirationTime"] = expirationTime;
// Add location
if (currentLocation != null) {
GeoFirePoint myLocation = geo.point(
GeoFirePoint myLocation = geo!.point(
latitude: currentLocation.latitude,
longitude: currentLocation.longitude);
serializedAnchor["position"] = myLocation.data;
}

anchorCollection
anchorCollection!
.add(serializedAnchor)
.then((value) =>
print("Successfully added anchor: " + serializedAnchor["name"]))
Expand All @@ -423,15 +421,15 @@ class FirebaseManager {

var serializedNode = node.toMap();

objectCollection
objectCollection!
.add(serializedNode)
.then((value) =>
print("Successfully added object: " + serializedNode["name"]))
.catchError((error) => print("Failed to add object: $error"));
}

void downloadLatestAnchor(FirebaseListener listener) {
anchorCollection
anchorCollection!
.orderBy("expirationTime", descending: false)
.limitToLast(1)
.get()
Expand All @@ -443,10 +441,10 @@ class FirebaseManager {
void downloadAnchorsByLocation(FirebaseDocumentStreamListener listener,
Position location, double radius) {
GeoFirePoint center =
geo.point(latitude: location.latitude, longitude: location.longitude);
geo!.point(latitude: location.latitude, longitude: location.longitude);

Stream<List<DocumentSnapshot>> stream = geo
.collection(collectionRef: anchorCollection)
Stream<List<DocumentSnapshot>> stream = geo!
.collection(collectionRef: anchorCollection!)
.within(center: center, radius: radius, field: 'position');

stream.listen((List<DocumentSnapshot> documentList) {
Expand All @@ -459,7 +457,7 @@ class FirebaseManager {
void downloadAnchorsByChannel() {}

void getObjectsFromAnchor(ARPlaneAnchor anchor, FirebaseListener listener) {
objectCollection
objectCollection!
.where("name", whereIn: anchor.childNodes)
.get()
.then((value) => listener(value))
Expand All @@ -468,13 +466,13 @@ class FirebaseManager {

void deleteExpiredDatabaseEntries() {
WriteBatch batch = FirebaseFirestore.instance.batch();
anchorCollection
anchorCollection!
.where("expirationTime",
isLessThan: DateTime.now().millisecondsSinceEpoch / 1000)
.get()
.then((anchorSnapshot) => anchorSnapshot.docs.forEach((anchorDoc) {
// Delete all objects attached to the expired anchor
objectCollection
objectCollection!
.where("name", arrayContainsAny: anchorDoc.get("childNodes"))
.get()
.then((objectSnapshot) => objectSnapshot.docs.forEach(
Expand Down
12 changes: 6 additions & 6 deletions example/lib/examples/debugoptionsexample.dart
Expand Up @@ -13,8 +13,8 @@ class DebugOptionsWidget extends StatefulWidget {
}

class _DebugOptionsWidgetState extends State<DebugOptionsWidget> {
late ARSessionManager arSessionManager;
late ARObjectManager arObjectManager;
ARSessionManager? arSessionManager;
ARObjectManager? arObjectManager;
bool _showFeaturePoints = false;
bool _showPlanes = false;
bool _showWorldOrigin = false;
Expand All @@ -25,7 +25,7 @@ class _DebugOptionsWidgetState extends State<DebugOptionsWidget> {
@override
void dispose() {
super.dispose();
arSessionManager.dispose();
arSessionManager!.dispose();
}

@override
Expand Down Expand Up @@ -95,19 +95,19 @@ class _DebugOptionsWidgetState extends State<DebugOptionsWidget> {
this.arSessionManager = arSessionManager;
this.arObjectManager = arObjectManager;

this.arSessionManager.onInitialize(
this.arSessionManager!.onInitialize(
showFeaturePoints: _showFeaturePoints,
showPlanes: _showPlanes,
customPlaneTexturePath: _planeTexturePath,
showWorldOrigin: _showWorldOrigin,
showAnimatedGuide: _showAnimatedGuide,
handleTaps: _handleTaps,
);
this.arObjectManager.onInitialize();
this.arObjectManager!.onInitialize();
}

void updateSessionSettings() {
this.arSessionManager.onInitialize(
this.arSessionManager!.onInitialize(
showFeaturePoints: _showFeaturePoints,
showPlanes: _showPlanes,
customPlaneTexturePath: _planeTexturePath,
Expand Down

0 comments on commit 8b6dc98

Please sign in to comment.