Skip to content

Instantly share code, notes, and snippets.

@lukepighetti
Last active October 3, 2019 12:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukepighetti/67cc0a3bb77baddec8b064511fcce1f2 to your computer and use it in GitHub Desktop.
Save lukepighetti/67cc0a3bb77baddec8b064511fcce1f2 to your computer and use it in GitHub Desktop.
An idea for "federated" platform packages that gives more power to platform specific packages while still allowing them to provide a consistent API that could be fit easily into an intersection package.
/// Given some `dart:io` method that returns a PlatformType enum
PlatformType get currentPlatform => PlatformType.windows;
enum PlatformType { android, fuschia, iOS, linux, macOS, windows }
/// Intersection package, ie `video_player` exposes a common interface
abstract class PlatformVideoController {
Stream<double> get progress;
Future<void> play();
Future<void> pause();
}
/// It also exposes a glorified switch block that allows people to load in their own implementations while
/// consuming normally. ie, `video_player_ios`, `video_player_windows`, etc
class VideoController implements PlatformVideoController {
static final implementations = Map<PlatformType, PlatformVideoController>();
static addImplementations(Map<PlatformType, PlatformVideoController> i) =>
implementations.addAll(i);
PlatformVideoController get _this {
final implementation = implementations[currentPlatform];
/// Guard unimplemented
if (implementation == null)
throw UnimplementedError(
"Platform $currentPlatform is not yet implemented.");
return implementation;
}
@override
Future<void> pause() => _this.pause();
@override
Future<void> play() => _this.play();
@override
Stream<double> get progress => _this.progress;
}
/// An example adapter/implementation that might be on `video_player_windows`
class WindowsVideoController implements PlatformVideoController {
final controller = AwesomeWindowsVideoController();
@override
Stream<double> get progress => controller.playheadLocation
.map((l) => l.inMilliseconds / controller.videoLength.inMilliseconds);
@override
Future<void> play() => controller.isPlaying(true);
@override
Future<void> pause() => controller.isPlaying(false);
}
/// The underlying platform specific controller that has way more methods than the intersection package
/// because it provides a ton of unique Windows related tooling
class AwesomeWindowsVideoController {
Duration get videoLength => Duration(seconds: 15);
Stream<Duration> get playheadLocation => Stream.fromIterable(
List.generate(15000, (i) => Duration(milliseconds: i)));
Future<void> isPlaying(bool isPlaying) => Future.value(null);
}
/// Consumed by Flutter developers
main() {
VideoController.addImplementations({
PlatformType.windows: WindowsVideoController(),
});
/// You can use the intersection package to make your life easier
final intersectionController = VideoController();
intersectionController.play();
/// Or you can consume the platform specific package and get more features
final platformController = AwesomeWindowsVideoController();
platformController.isPlaying(true);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment