Dart包的条件导入/代码

时间:2013-10-22 18:20:33

标签: dart dart-mirrors

有没有办法根据Dart中的环境标志或目标平台有条件地导入库/代码?我正试图在dart:io的ZLibDecoder / ZLibEncoder类和基于目标平台的zlib.js之间切换。

有一篇文章描述了create a unified interface的方法,但是我无法想象这种技术不会创建重复的代码和冗余的测试来测试重复的代码。 game_loop employs this technique,但使用的单独类(GameLoopHtml和GameLoopIsolate)似乎没有任何共享。

我的代码看起来有点像这样:

class Parser {
  Layer parse(String data) {
    List<int> rawBytes = /* ... */;
    /* stuff you don't care about */
    return new Layer(_inflateBytes(rawBytes));
  }
  String _inflateBytes(List<int> bytes) {
    // Uses ZLibEncoder on dartvm, zlib.js in browser
  }
}

我希望通过两个单独的类(ParserHtml和ParserServer)来避免重复代码,这些类实现除了_inflateBytes之外的所有内容。

编辑:具体示例:https://github.com/radicaled/citadel/blob/master/lib/tilemap/parser.dart。它是TMX(Tile Map XML)解析器。

2 个答案:

答案 0 :(得分:2)

您可以使用镜像(反射)来解决此问题。 pub包 path 使用反射来访问独立VM上的dart:io或浏览器中的dart:html

来源位于here。好的是,他们使用@MirrorsUsed,因此镜像api只包含必需的类。在我看来,代码记录得非常好,应该很容易为您的代码采用解决方案。

从getters _io_html开始(在第72行说明),它们表明您可以加载一个库,而不是它们在您的VM类型上可用。如果库不可用,则加载只返回false。

/// If we're running in the server-side Dart VM, this will return a
/// [LibraryMirror] that gives access to the `dart:io` library.
///
/// If `dart:io` is not available, this returns null.
LibraryMirror get _io => currentMirrorSystem().libraries[Uri.parse('dart:io')];

// TODO(nweiz): when issue 6490 or 6943 are fixed, make this work under dart2js.
/// If we're running in Dartium, this will return a [LibraryMirror] that gives
/// access to the `dart:html` library.
///
/// If `dart:html` is not available, this returns null.
LibraryMirror get _html =>
  currentMirrorSystem().libraries[Uri.parse('dart:html')];

稍后您可以使用镜像来调用方法或getter。有关示例实现,请参阅getter current(从第86行开始)。

/// Gets the path to the current working directory.
///
/// In the browser, this means the current URL. When using dart2js, this
/// currently returns `.` due to technical constraints. In the future, it will
/// return the current URL.
String get current {
  if (_io != null) {
    return _io.classes[#Directory].getField(#current).reflectee.path;
  } else if (_html != null) {
    return _html.getField(#window).reflectee.location.href;
  } else {
    return '.';
  }
}

正如您在评论中看到的那样,此刻仅适用于Dart VM。问题6490解决后,它也应该在Dart2Js中工作。这可能意味着此解决方案目前不适用于您,但稍后会成为解决方案。

问题6943也可能有所帮助,但描述了尚未实施的另一种解决方案。

答案 1 :(得分:1)

可以根据dart:htmldart:io的存在情况进行有条件的导入,例如,请参见resource_loader.dartpackage:resource的import语句。

我尚不确定如何在Flutter平台上进行导入。