// 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 ArrayStruct extends Struct {
  public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
  public ArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public float a() { return bb.getFloat(bb_pos + 0); }
  public void mutateA(float a) { bb.putFloat(bb_pos + 0, a); }
  public int b(int j) { return bb.getInt(bb_pos + 4 + j * 4); }
  public void mutateB(int j, int b) { bb.putInt(bb_pos + 4 + j * 4, b); }
  public byte c() { return bb.get(bb_pos + 64); }
  public void mutateC(byte c) { bb.put(bb_pos + 64, c); }
  public MyGame.Example.NestedStruct d(MyGame.Example.NestedStruct obj, int j) { return obj.__assign(bb_pos + 68 + j * 12, bb); }

  public static int createArrayStruct(FlatBufferBuilder builder, float a, int[] b, byte c, int[][] d_a, byte[] d_b, byte[][] d_c) {
    builder.prep(4, 92);
    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
      builder.prep(4, 12);
      builder.pad(1);
      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
        builder.putByte(d_c[_idx0-1][_idx1-1]);
      }
      builder.putByte(d_b[_idx0-1]);
      for (int _idx1 = 2; _idx1 > 0; _idx1--) {
        builder.putInt(d_a[_idx0-1][_idx1-1]);
      }
    }
    builder.pad(3);
    builder.putByte(c);
    for (int _idx0 = 15; _idx0 > 0; _idx0--) {
      builder.putInt(b[_idx0-1]);
    }
    builder.putFloat(a);
    return builder.offset();
  }
}

