// <auto-generated>
//  automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>

namespace MyGame.Example
{

using global::System;
using global::FlatBuffers;

public struct NestedStruct : IFlatbufferObject
{
  private Struct __p;
  public ByteBuffer ByteBuffer { get { return __p.bb; } }
  public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
  public NestedStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }

  public int A(int j) { return __p.bb.GetInt(__p.bb_pos + 0 + j * 4); }
  public void MutateA(int j, int a) { __p.bb.PutInt(__p.bb_pos + 0 + j * 4, a); }
  public MyGame.Example.TestEnum B { get { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 8); } }
  public void MutateB(MyGame.Example.TestEnum b) { __p.bb.PutSbyte(__p.bb_pos + 8, (sbyte)b); }
  public MyGame.Example.TestEnum C(int j) { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 9 + j * 1); }
  public void MutateC(int j, MyGame.Example.TestEnum c) { __p.bb.PutSbyte(__p.bb_pos + 9 + j * 1, (sbyte)c); }

  public static Offset<MyGame.Example.NestedStruct> CreateNestedStruct(FlatBufferBuilder builder, int[] A, MyGame.Example.TestEnum B, MyGame.Example.TestEnum[] C) {
    builder.Prep(4, 12);
    builder.Pad(1);
    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
      builder.PutSbyte((sbyte)C[_idx0-1]);
    }
    builder.PutSbyte((sbyte)B);
    for (int _idx0 = 2; _idx0 > 0; _idx0--) {
      builder.PutInt(A[_idx0-1]);
    }
    return new Offset<MyGame.Example.NestedStruct>(builder.Offset);
  }
};


}
