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

package MyGame.Example;

import com.google.flatbuffers.BaseVector;
import com.google.flatbuffers.BooleanVector;
import com.google.flatbuffers.ByteVector;
import com.google.flatbuffers.Constants;
import com.google.flatbuffers.DoubleVector;
import com.google.flatbuffers.FlatBufferBuilder;
import com.google.flatbuffers.FloatVector;
import com.google.flatbuffers.IntVector;
import com.google.flatbuffers.LongVector;
import com.google.flatbuffers.ShortVector;
import com.google.flatbuffers.StringVector;
import com.google.flatbuffers.Struct;
import com.google.flatbuffers.Table;
import com.google.flatbuffers.UnionVector;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

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

  public int a(int j) { return bb.getInt(bb_pos + 0 + j * 4); }
  public void mutateA(int j, int a) { bb.putInt(bb_pos + 0 + j * 4, a); }
  public byte b() { return bb.get(bb_pos + 8); }
  public void mutateB(byte b) { bb.put(bb_pos + 8, b); }
  public byte c(int j) { return bb.get(bb_pos + 9 + j * 1); }
  public void mutateC(int j, byte c) { bb.put(bb_pos + 9 + j * 1, c); }
  public long d(int j) { return bb.getLong(bb_pos + 16 + j * 8); }
  public void mutateD(int j, long d) { bb.putLong(bb_pos + 16 + j * 8, d); }

  public static int createNestedStruct(FlatBufferBuilder builder, int[] a, byte b, byte[] c, long[] d) {
    builder.prep(8, 32);
    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
      builder.putLong(d[_idx0-1]);
    }
    builder.pad(5);
    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
      builder.putByte(c[_idx0-1]);
    }
    builder.putByte(b);
    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
      builder.putInt(a[_idx0-1]);
    }
    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 NestedStruct get(int j) { return get(new NestedStruct(), j); }
    public NestedStruct get(NestedStruct obj, int j) {  return obj.__assign(__element(j), bb); }
  }
  public NestedStructT unpack() {
    NestedStructT _o = new NestedStructT();
    unpackTo(_o);
    return _o;
  }
  public void unpackTo(NestedStructT _o) {
    int[] _oA = _o.getA();
    for (int _j = 0; _j < 2; ++_j) { _oA[_j] = a(_j); }
    byte _oB = b();
    _o.setB(_oB);
    byte[] _oC = _o.getC();
    for (int _j = 0; _j < 2; ++_j) { _oC[_j] = c(_j); }
    long[] _oD = _o.getD();
    for (int _j = 0; _j < 2; ++_j) { _oD[_j] = d(_j); }
  }
  public static int pack(FlatBufferBuilder builder, NestedStructT _o) {
    if (_o == null) return 0;
    int[] _a = _o.getA();
    byte[] _c = _o.getC();
    long[] _d = _o.getD();
    return createNestedStruct(
      builder,
      _a,
      _o.getB(),
      _c,
      _d);
  }
}

