3

ダーツでリフレクション (別名ダーツ:ミラー) を使用しています。最初: ここに表示されているすべてのコードは、dartium (dart ネイティブ) で完全に機能しますが、dart2js でコンパイルして chrome で実行すると部分的にしか機能しません。

バイトストリームからクラスを読み取る BinaryReader というクラスがあります。これを行うコード(繰り返し部分を取り除いたもの)は次のとおりです。

  void readObject(dynamic obj) {
    var inst = reflect(obj);
    inst.type.declarations.forEach((Symbol name, DeclarationMirror decl) {
      if(decl is VariableMirror) {
        var variable = decl;
        if(variable.metadata.length == 0) {
          return;
        }

        InstanceMirror attrib = variable.metadata.first;
        if(attrib.hasReflectee == false) {
          return;
        }

        if(attrib.reflectee is Field) {
          var field = attrib.reflectee as Field;
          var value;
          switch(field.type) {
            case I8: 
              value = getInt8();
              break;

            // ...

            case V3:
              value = new Vector3(getFloat(), getFloat(), getFloat());
              break;

            default:
              value = null;
              break;
          }

          if(value == null) {
            return;
          }

          inst.setField(name, value);
        }
      }
    });
  }

ミラーのインポートは、次の方法で行います。

import 'model/M4SubMesh.dart';
import 'model/M4Model.dart';
import 'package:vector_math/vector_math.dart';
@MirrorsUsed(targets: const["M4SubMesh", "M4Model", "vector_math"], override: '*')
import 'dart:mirrors';

M4SubMesh と M4Model は、それぞれの dart ファイルのライブラリ名です。vector_math vector_math.dart の 1 つ

最初に、ストリームから M4Model ライブラリの一部である M4Header のインスタンスを読み取ります。すべての値は正しいです。次のようになります。

class M4Header
{
  @Field(UI32)
  int Signature;
  @Field(UI32)
  int Version;
  @Field(UI32)
  int numSubMeshes;
  @Field(UI32)
  int ofsSubMeshes;  
}

その後、次のような M4SubMeshHeader を読み取ろうとします。

class M4SubMeshHeader
{
  @Field(UI32)
  int gridX, gridY, gridZ;
  @Field(F32)
  num blockSize;
  @Field(V3)
  Vector3 bboxMin, bboxMax;
}

読み取り後、blockSize はランダムな値になります。bboxMin と bboxMax は null です。ここで何がうまくいかないのですか?

こんにちはクロモン

4

2 に答える 2

1

解決策を見つけました!注釈は、宣言リストの最初の要素にのみ適用されます。したがって、上記の例は実際には次のように展開されます。

class M4SubMeshHeader
{
  @Field(UI32)
  int gridX;
  int gridY;
  int gridZ;
  @Field(F32)
  num blockSize;
  @Field(V3)
  Vector3 bboxMin;
  Vector3 bboxMax;
}

私の意見では、これはエラーと見なすことができます。ドキュメントをよく見て、そこに記載されていない場合は報告してください。そのため、最終的に blockSize は gridY に割り当てられるべき値になり、ランダムに見えました。しかし、正直に言うと、私も責任を負わなければなりません。「bboxMin と bboxMax は null です」、これは間違っています。bboxMin は null ではありませんでしたが、無効な値がありましたが、印刷する前に bboxMax を使用したコードに行を残したので、bboxMin で既に壊れていると思いました。

こんにちはクロモン

于 2014-01-31T23:51:50.797 に答える