// automatically generated by the FlatBuffers compiler, do not modify

package MyGame.Example;

import java.nio.*;
import java.lang.*;
import java.util.*;
import com.google.flatbuffers.*;

@SuppressWarnings("unused")
public final class StructOfStructs extends Struct {
  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
  public StructOfStructs __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public MyGame.Example.Ability a() { return a(new MyGame.Example.Ability()); }
  public MyGame.Example.Ability a(MyGame.Example.Ability obj) { return obj.__assign(bb_pos + 0, bb); }
  public MyGame.Example.Test b() { return b(new MyGame.Example.Test()); }
  public MyGame.Example.Test b(MyGame.Example.Test obj) { return obj.__assign(bb_pos + 8, bb); }
  public MyGame.Example.Ability c() { return c(new MyGame.Example.Ability()); }
  public MyGame.Example.Ability c(MyGame.Example.Ability obj) { return obj.__assign(bb_pos + 12, bb); }

  public static int createStructOfStructs(FlatBufferBuilder builder, long a_id, long a_distance, short b_a, byte b_b, long c_id, long c_distance) {
    builder.prep(4, 20);
    builder.prep(4, 8);
    builder.putInt((int) c_distance);
    builder.putInt((int) c_id);
    builder.prep(2, 4);
    builder.pad(1);
    builder.putByte(b_b);
    builder.putShort(b_a);
    builder.prep(4, 8);
    builder.putInt((int) a_distance);
    builder.putInt((int) a_id);
    return builder.offset();
  }

  public static final class Vector extends BaseVector {
    public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }

    public StructOfStructs get(int j) { return get(new StructOfStructs(), j); }
    public StructOfStructs get(StructOfStructs obj, int j) {  return obj.__assign(__element(j), bb); }
  }
  public StructOfStructsT unpack() {
    StructOfStructsT _o = new StructOfStructsT();
    unpackTo(_o);
    return _o;
  }
  public void unpackTo(StructOfStructsT _o) {
    a().unpackTo(_o.getA());
    b().unpackTo(_o.getB());
    c().unpackTo(_o.getC());
  }
  public static int pack(FlatBufferBuilder builder, StructOfStructsT _o) {
    if (_o == null) return 0;
    int _a_id = _o.getA().getId();
    int _a_distance = _o.getA().getDistance();
    short _b_a = _o.getB().getA();
    byte _b_b = _o.getB().getB();
    int _c_id = _o.getC().getId();
    int _c_distance = _o.getC().getDistance();
    return createStructOfStructs(
      builder,
      _a_id,
      _a_distance,
      _b_a,
      _b_b,
      _c_id,
      _c_distance);
  }
}

