Skip to content

Commit

Permalink
Add README to Dart bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
Dampfwalze committed Aug 15, 2024
1 parent 5460dc2 commit 8ba21f0
Show file tree
Hide file tree
Showing 4 changed files with 301 additions and 58 deletions.
207 changes: 184 additions & 23 deletions rust/bindings/dart/README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,200 @@
<!--
This README describes the package. If you publish this package to pub.dev,
this README's contents appear on the landing page for your package.
Control
[`virtual-display-rs`](https://github.com/MolotovCherry/virtual-display-rs)
using Dart, to create and manage virtual monitors on Windows.

For information about how to write a good package README, see the guide for
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
`virtual-display-rs` uses windows named pipes to connect to the driver.

For general information about developing packages, see the Dart guide for
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
and the Flutter guide for
[developing packages and plugins](https://flutter.dev/developing-packages).
-->

TODO: Put a short description of the package here that helps potential users
know whether this package might be useful for them.
> Note: This package uses [native
> assets](https://github.com/dart-lang/sdk/issues/50565), which are not yet
> stable. To use this package, you must enable it using the
> `--enable-experiment=native-assets` as the first flag on every dart command,
> or, when using flutter, enable it in the flutter config using `flutter config
> --enable-native-assets`.
## Features

TODO: List what your package can do. Maybe include images, gifs, or videos.
- Add/Remove/Change virtual monitors
- Add/Remove/Change monitor resolutions and framerate
- Persist driver state across restarts
- Get continues state updates from the driver, no matter why it changed

## Getting started

TODO: List prerequisites and provide or point to information on how to
start using the package.
1. [Install the driver](https://github.com/MolotovCherry/virtual-display-rs?tab=readme-ov-file#how-to-install)
2. Install Rust using [rustup](https://www.rust-lang.org/learn/get-started)
3. Add dependency to `pubspec.yaml`:

```yaml
dependencies:
vdd:
git:
url: https://github.com/MolotovCherry/virtual-display-rs.git
ref: master
path: rust/bindings/dart
```
## Usage
TODO: Include short and useful examples for package users. Add longer examples
to `/example` folder.
Import the relevant packages:
```dart
import 'package:vdd/vdd.dart' as vdd;

// Imports all errors, that might be thrown by dart_vdd
import 'package:vdd/errors.dart' as vdd;
```

### Initialization

Before using the driver, `vdd` must be initialized:

```dart
await vdd.init();
```

There are two clients with a different level of abstraction.

### `Client`

This client does not manage its own state.

```dart
const like = 'sample';
// Connect to driver using the default named pipe
final client = await vdd.Client.connect();
// Listen to all state changes
client.receiveEvents().listen((monitors) {
print("Driver state changed: $monitors");
});
final monitors = [
vdd.Monitor(
id: 0,
enabled: true,
modes: [
vdd.Mode(
width: 1920,
height: 1080,
refreshRates: Uint32List.fromList([60, 120]),
),
],
),
];
// Override driver state with new monitor
await client.notify(monitors: monitors);
// Make this state persistent across restarts
await vdd.Client.persist(monitors: monitors);
```

### `DriverClient`

This client manages its own state, separate from the driver. This state might
become stale. To refresh it, call `DriverClient.refreshState`. To apply state
changes to the driver, call `DriverClient.notify`.

```dart
// Connect to the driver, using the default pipe name
final client = await vdd.DriverClient.connect();
// Listen to all state changes
client.receiveEvents().listen((monitors) async {
print("Driver state changed: $monitors");
// Refresh local state when driver state changes
await client.refreshState();
});
print("Current driver state: ${client.state}");
// Get a free id for a new monitor
final monitorId = client.newId()!;
// Add a new monitor
client.add(
monitor: vdd.Monitor(
id: monitorId,
enabled: true,
modes: [
vdd.Mode(
width: 1920,
height: 1080,
refreshRates: Uint32List.fromList([60, 120]),
),
],
),
);
// Apply changes to the driver
await client.notify();
// Make changes persistent across restarts
await client.persist();
```

## Testing

`vdd` provides a mock server, simulating the driver on the other end of the
named pipe.

Additionally, import `package:vdd/test.dart` to get access to the mock server.

```dart
import 'package:vdd/vdd.dart' as vdd;
import 'package:vdd/test.dart' as vdd;
```

```dart
setUpAll(() async {
await vdd.init();
});
test('test', () async {
// Pass in a unique pipe name
final server = await vdd.MockServer.create(pipeName: "my_pipe_name");
final client = await vdd.Client.connect(server.pipeName);
// Use the client
await client.notify(...);
// Pump the server, to handle exactly one request
await server.pump();
expect(server.state, ...);
await server.setState(...);
expect(client.requestState(), ...);
});
```

For more examples, see the
[tests](https://github.com/MolotovCherry/virtual-display-rs/tree/master/rust/bindings/dart/test/vdd_test.dart)
in `test/`.

## Maintaining

To regenerate bindings, run:

```bash
cargo make generate
```

or

```bash
cargo make generate-watch
```

To run unit tests, run:

```bash
cargo make test
```

## Additional information
To run examples, run:

TODO: Tell users more about the package: where to find more information, how to
contribute to the package, how to file issues, what response they can expect
from the package authors, and more.
```bash
dart --enable-experiment=native-assets run example/<example>.dart
```
50 changes: 50 additions & 0 deletions rust/bindings/dart/example/client_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import 'dart:typed_data';

import 'package:vdd/errors.dart' as vdd;
import 'package:vdd/vdd.dart' as vdd;

void main(List<String> args) async {
await vdd.init();

// Connect to driver using the default named pipe
final client = await vdd.Client.connect();

try {
print("Current state: ${await client.requestState()}");
} on vdd.RequestError catch (e) {
print("Did you forget to install the driver?\n$e");
return;
}

// Listen to all state changes
client.receiveEvents().listen((monitors) {
print("Driver state changed: $monitors");
});

final monitors = [
vdd.Monitor(
id: 0,
enabled: true,
modes: [
vdd.Mode(
width: 1920,
height: 1080,
refreshRates: Uint32List.fromList([60, 120]),
),
],
),
];

// Override driver state with new monitor
await client.notify(monitors: monitors);

// Make this state persistent across restarts
await vdd.Client.persist(monitors: monitors);

await Future.delayed(Duration(seconds: 5));

// Remove all monitors
await client.removeAll();

await vdd.Client.persist(monitors: []);
}
67 changes: 67 additions & 0 deletions rust/bindings/dart/example/driver_client_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'dart:typed_data';

import 'package:vdd/errors.dart' as vdd;
import 'package:vdd/vdd.dart' as vdd;

void main(List<String> args) async {
await vdd.init();

try {
// Connect to the driver, using the default pipe name
final client = await vdd.DriverClient.connect();

// Listen to all state changes
client.receiveEvents().listen((monitors) async {
print("Driver state changed: $monitors");

// Refresh local state when driver state changes
await client.refreshState();
});

print("Current driver state: ${client.state}");

// Get a free id for a new monitor
final monitorId = client.newId()!;

// Add a new monitor
client.add(
monitor: vdd.Monitor(
id: monitorId,
enabled: true,
modes: [
vdd.Mode(
width: 1920,
height: 1080,
refreshRates: Uint32List.fromList([60, 120]),
),
],
),
);

client.addMode(
id: monitorId,
mode: vdd.Mode(
width: 2560,
height: 1440,
refreshRates: Uint32List.fromList([60, 120]),
),
);

// Apply changes to the driver
await client.notify();

// Make changes persistent across restarts
await client.persist();

await Future.delayed(Duration(seconds: 5));

// Remove all monitors
client.removeAll();

await client.notify();

await client.persist();
} on vdd.InitError catch (e) {
print("Did you forget to install the driver?\n$e");
}
}
35 changes: 0 additions & 35 deletions rust/bindings/dart/example/vdd_example.dart

This file was deleted.

0 comments on commit 8ba21f0

Please sign in to comment.