Last active
October 3, 2019 12:49
-
-
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.
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
/// 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