2013-10-22 1 views
3

다트의 환경 플래그 또는 대상 플랫폼을 기반으로 라이브러리/코드를 조건부로 가져 오는 방법이 있습니까? dart:io의 ZLibDecoder/ZLibEncoder 클래스와 대상 플랫폼을 기반으로 한 zlib.js 사이를 전환하려고합니다.다트 패키지의 조건부 가져 오기/코드

create a unified interface을 설명하는 기사가 있지만 중복 코드를 만들지 않는 기술과 중복 된 코드를 테스트하지 못합니다. game_loopemploys 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) 파서입니다.

+0

둘 다 모두 동일하게 구현하는 경우 추출 클래스에 구현 한 다음 ParserHtml 및 ParserServer에서 해당 클래스를 확장해야하는 이유는 무엇입니까? – Nathanial

+0

'Parser'에 직접 접근하거나 인스턴스화하는 다른 클래스를 가지려고합니다. ParserHtml이나 ParserServer를 직접 참조하지 않고 어떻게 처리 할 수 ​​있는지 잘 모르겠습니다. 어쩌면 내가 사용할 수있는 공장 패턴이 있을지도 모른다. – ALW

+0

import parserhtml.dart. 실제 파생 클래스이며 html 버전에 대한 팩토리 생성자가있는 Parser 클래스를 정의합니다. 서버 버전에서도 마찬가지입니다. 그런 다음 코드는 가져 오는 항목을 제외하고 동일 할 수 있습니다. –

답변

2

이 문제를 해결하기 위해 거울 (반성)을 사용할 수 있습니다. pub 패키지 path은 리플렉션을 사용하여 독립 실행 형 VM에서 dart:io에 액세스하거나 브라우저에서 dart:html에 액세스합니다.

출처는 here입니다. 좋은 점은 @MirrorsUsed을 사용하기 때문에 필요한 API 만 미러 API에 포함된다는 것입니다. 필자의 견해로는 코드가 매우 잘 문서화되어 있으므로 코드에 대한 솔루션을 채택하는 것이 쉬워야합니다.

getter _io_html (72 행부터 시작)에서 시작하여 라이브러리 유형을 사용하지 않고 라이브러리를로드 할 수 있음을 보여줍니다. 라이브러리를 사용할 수없는 경우 로딩은 단지 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이 해결 된 후에도 Dart2J에서 작동해야합니다. 이것은 현재이 솔루션이 귀하에게 해당되지 않지만 나중에 솔루션이 될 수 있음을 의미합니다.

문제 6943도 도움이 될 수 있지만 아직 구현되지 않은 다른 해결책을 설명합니다.

+0

이것은 장기적인 잠재력이 가장 좋은 것 같아서 답변으로 표시하고 있습니다. – ALW