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

import * as flatbuffers from 'flatbuffers';

import { TableB, TableBT } from './my-game/other-name-space/table-b.js';


export class TableA implements flatbuffers.IUnpackableObject<TableAT> {
  bb: flatbuffers.ByteBuffer|null = null;
  bb_pos = 0;
  __init(i:number, bb:flatbuffers.ByteBuffer):TableA {
  this.bb_pos = i;
  this.bb = bb;
  return this;
}

static getRootAsTableA(bb:flatbuffers.ByteBuffer, obj?:TableA):TableA {
  return (obj || new TableA()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}

static getSizePrefixedRootAsTableA(bb:flatbuffers.ByteBuffer, obj?:TableA):TableA {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new TableA()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}

b(obj?:TableB):TableB|null {
  const offset = this.bb!.__offset(this.bb_pos, 4);
  return offset ? (obj || new TableB()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
}

static getFullyQualifiedName():string {
  return 'TableA';
}

static startTableA(builder:flatbuffers.Builder) {
  builder.startObject(1);
}

static addB(builder:flatbuffers.Builder, bOffset:flatbuffers.Offset) {
  builder.addFieldOffset(0, bOffset, 0);
}

static endTableA(builder:flatbuffers.Builder):flatbuffers.Offset {
  const offset = builder.endObject();
  return offset;
}

static createTableA(builder:flatbuffers.Builder, bOffset:flatbuffers.Offset):flatbuffers.Offset {
  TableA.startTableA(builder);
  TableA.addB(builder, bOffset);
  return TableA.endTableA(builder);
}

serialize():Uint8Array {
  return this.bb!.bytes();
}

static deserialize(buffer: Uint8Array):TableA {
  return TableA.getRootAsTableA(new flatbuffers.ByteBuffer(buffer))
}

unpack(): TableAT {
  return new TableAT(
    (this.b() !== null ? this.b()!.unpack() : null)
  );
}


unpackTo(_o: TableAT): void {
  _o.b = (this.b() !== null ? this.b()!.unpack() : null);
}
}

export class TableAT implements flatbuffers.IGeneratedObject {
constructor(
  public b: TableBT|null = null
){}


pack(builder:flatbuffers.Builder): flatbuffers.Offset {
  const b = (this.b !== null ? this.b!.pack(builder) : 0);

  return TableA.createTableA(builder,
    b
  );
}
}
