-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
> * Created Electrical Message and Metrics > * Changed Wrapped Message > * Message Receiver, Message Sender edited > * Moved Protobuf into metrics.dart > * Updated analyzer test to use new protobuf files > Added Protobuf files to `build.yaml` and `.gitignore`, so now you can run > > ``` > dart run build_runner build > ``` > > from `dashboard` instead of running > > ``` > protoc --dart_out=./generated Protobuf/*.proto > ``` > > from `dashboard/lib/src/data`. Co-authored-by: Levi Lesches <[email protected]>
- Loading branch information
1 parent
dbee83a
commit 9f77896
Showing
20 changed files
with
572 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
# Protobuf code is generated here | ||
lib/src/data/generated | ||
|
||
# Miscellaneous | ||
*.class | ||
*.log | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "lib/src/data/Protobuf"] | ||
path = lib/src/data/Protobuf | ||
url = https://github.com/BinghamtonRover/Protobuf.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
targets: | ||
$default: | ||
sources: | ||
- $package$ | ||
- lib/$lib$ | ||
- lib/src/data/Protobuf/**.proto | ||
builders: | ||
protoc_builder: | ||
options: | ||
# Directory which is treated as the root of all Protobuf files. | ||
# (Default: "proto/") | ||
root_dir: "lib/src/data/Protobuf/" | ||
# Include paths given to the Protobuf compiler during compilation. | ||
# (Default: ["proto/"]) | ||
proto_paths: | ||
- "lib/src/data/Protobuf/" | ||
# The root directory for generated Dart output files. | ||
# (Default: "lib/src/proto") | ||
out_dir: "lib/src/data/generated" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import "package:protobuf/protobuf.dart" as proto; | ||
import "package:rover_dashboard/data.dart"; | ||
|
||
/// A cleaner name for any message generated by Protobuf. | ||
typedef Message = proto.GeneratedMessage; | ||
|
||
/// A function that decodes a Protobuf messages serialized form. | ||
/// | ||
/// The `.fromBuffer` constructor is a type of [MessageDecoder]. | ||
typedef MessageDecoder<T extends Message> = T Function(List<int> data); | ||
|
||
/// Decodes a wrapped Protobuf message. | ||
extension Unwrapper on WrappedMessage { | ||
/// Decodes the wrapped message into a message of type [T]. | ||
T decode<T extends Message>(MessageDecoder<T> decoder) => decoder(data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import "package:flutter/foundation.dart"; | ||
|
||
/// A data model that handles data from services. | ||
abstract class Model with ChangeNotifier { | ||
/// Initializes any data needed by this model. | ||
Future<void> init(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import "model.dart"; | ||
|
||
/// Handles incoming data about the vitals of the rover, like voltage, power and temperature. | ||
class Vitals extends Model { | ||
/// The temperature of the rover, in degrees F. | ||
int temperature = 0; | ||
|
||
@override | ||
Future<void> init() async { | ||
// Subscribe to ElectricalMessages using the MessageReceiver service. | ||
// When a new message arrives, update the relevant fields and call [notifyListeners]. | ||
} | ||
|
||
@override | ||
Future<void> dispose() async { | ||
// Cancel the subscription. | ||
super.dispose(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import "dart:async"; | ||
import "dart:io"; | ||
|
||
import "package:rover_dashboard/data.dart"; | ||
import "service.dart"; | ||
|
||
/// A callback to execute with raw Protobuf data. | ||
typedef RawMessageHandler = void Function(List<int> data); | ||
|
||
/// A callback to execute with a specific serialized Protobuf message. | ||
// typedef MessageHandler<T extends Message> = void Function(T); | ||
typedef Handler<T> = void Function(T); | ||
|
||
/// The port to listen for messages on. | ||
const port = 22201; | ||
|
||
/// A function that handles incoming data. | ||
extension on RawDatagramSocket { | ||
StreamSubscription listenForData(Handler<List<int>> handler) => listen((event) { | ||
final datagram = receive(); | ||
if (datagram == null) return; | ||
handler(datagram.data); | ||
}); | ||
} | ||
|
||
/// A service that receives messages over a UDP connection. | ||
/// | ||
/// To listen to certain messages, call [registerHandler] with the type of message you want | ||
/// to receive, as well as a decoder and the handler callback itself. | ||
class MessageReceiver extends Service { | ||
/// Handlers for every possible type of Protobuf message in serialized form. | ||
final Map<String, RawMessageHandler> _handlers = {}; | ||
|
||
/// The UDP socket to listen on. | ||
/// | ||
/// Initialized in [init]. | ||
late final RawDatagramSocket _socket; | ||
|
||
/// The subscription that listens to [_socket]. | ||
late final StreamSubscription _subscription; | ||
|
||
@override | ||
Future<void> init() async { | ||
_socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, port); | ||
_subscription = _socket.listenForData(_listener); | ||
} | ||
|
||
@override | ||
Future<void> dispose() async { | ||
await _subscription.cancel(); | ||
_socket.close(); | ||
} | ||
|
||
/// Runs every time data is received by the socket. | ||
/// | ||
/// The datagram contains a [WrappedMessage]. These are Protobuf messages that wrap an | ||
/// underlying message and record their name. We use the type of the underlying message | ||
/// to get the appropriate handler from [_handlers] which decodes the message to the | ||
/// correct type and processes it. | ||
void _listener(List<int> data) { | ||
final wrapped = WrappedMessage.fromBuffer(data); | ||
final RawMessageHandler? rawHandler = _handlers[wrapped.name]; | ||
if (rawHandler == null) { /* Log in some meaningful way, through the UI */ } | ||
else { rawHandler(wrapped.data); } | ||
} | ||
|
||
/// Adds a handler for a given type. | ||
/// | ||
/// [decoder] is a function that decodes a byte buffer to a Protobuf message class. [handler] | ||
/// then handles that message somehow. | ||
void registerHandler<T extends Message>({ | ||
required String name, | ||
required MessageDecoder<T> decoder, | ||
required Handler<T> handler | ||
}) { | ||
if (T == Message) { // no T was actually passed, [Message] is the default | ||
throw ArgumentError("No message type was passed"); | ||
} else if (_handlers.containsKey(name)) { // handler was already registered | ||
throw ArgumentError("Message handler for type [$T] already registered"); | ||
} else { | ||
_handlers[name] = (List<int> data) => handler(decoder(data)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import "dart:io"; | ||
|
||
import "package:rover_dashboard/data.dart"; | ||
|
||
import "service.dart"; | ||
|
||
/// A service to send [Message] objects to the rover. | ||
class MessageSender extends Service { | ||
/// The IP address of the rover. | ||
static final address = InternetAddress("127.0.0.1"); | ||
|
||
/// The port on the rover to send to. | ||
static const port = 8082; | ||
|
||
/// The socket for the UDP connection. | ||
late final RawDatagramSocket _socket; | ||
|
||
@override | ||
Future<void> init() async { | ||
_socket = await RawDatagramSocket.bind(InternetAddress.anyIPv4, port); | ||
} | ||
|
||
@override | ||
Future<void> dispose() async { | ||
_socket.close(); | ||
} | ||
|
||
/// Resets the connection. | ||
/// | ||
/// When in doubt, turn it off and back on again. | ||
Future<void> reset() async { | ||
await dispose(); | ||
await init(); | ||
} | ||
|
||
/// Wraps the [message] in a [WrappedMessage] container and sends it to the rover. | ||
Future<void> sendMessage(Message message) async { | ||
final wrapper = WrappedMessage(name: message.info_.messageName, data: message.writeToBuffer()); | ||
_socket.send(wrapper.writeToBuffer(), address, port); | ||
} | ||
} |
Oops, something went wrong.