// automatically generated by the FlatBuffers compiler, do not modify
// swiftlint:disable all
// swiftformat:disable all

#if canImport(Common)
import Common
#endif

import FlatBuffers

public enum MyGame_Sample_Color: Int8, FlatbuffersVectorInitializable, Enum, Verifiable {
  public typealias T = Int8
  public static var byteSize: Int { return MemoryLayout<Int8>.size }
  public var value: Int8 { return self.rawValue }
  case red = 0
  case green = 1
  case blue = 2

  public static var max: MyGame_Sample_Color { return .blue }
  public static var min: MyGame_Sample_Color { return .red }
}

extension MyGame_Sample_Color: Encodable {
  public func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    switch self {
    case .red: try container.encode("Red")
    case .green: try container.encode("Green")
    case .blue: try container.encode("Blue")
    }
  }
}

public enum MyGame_Sample_Equipment: UInt8, FlatbuffersVectorInitializable, UnionEnum {
  public typealias T = UInt8

  public init?(value: T) {
    self.init(rawValue: value)
  }

  public static var byteSize: Int { return MemoryLayout<UInt8>.size }
  public var value: UInt8 { return self.rawValue }
  case none_ = 0
  case weapon = 1

  public static var max: MyGame_Sample_Equipment { return .weapon }
  public static var min: MyGame_Sample_Equipment { return .none_ }
}

extension MyGame_Sample_Equipment: Encodable {
  public func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    switch self {
    case .none_: try container.encode("NONE")
    case .weapon: try container.encode("Weapon")
    }
  }
}

public struct MyGame_Sample_EquipmentUnion {
  public var type: MyGame_Sample_Equipment
  public var value: NativeObject?
  public init(_ v: NativeObject?, type: MyGame_Sample_Equipment) {
    self.type = type
    self.value = v
  }
  public func pack(builder: inout FlatBufferBuilder) -> Offset {
    switch type {
    case .weapon:
      var __obj = value as? MyGame_Sample_WeaponT
      return MyGame_Sample_Weapon.pack(&builder, obj: &__obj)
    default: return Offset()
    }
  }
}
public struct MyGame_Sample_Vec3: NativeStruct, FlatbuffersVectorInitializable, Verifiable, FlatbuffersInitializable, NativeObject {

  static func validateVersion() { FlatBuffersVersion_25_9_23() }

  private var _x: Float32
  private var _y: Float32
  private var _z: Float32

  public init(_ bb: ByteBuffer, o: Int32) {
    self = bb.read(def: Self.self, position: Int(o))
  }

  public init(x: Float32, y: Float32, z: Float32) {
    _x = x
    _y = y
    _z = z
  }

  public init() {
    _x = 0.0
    _y = 0.0
    _z = 0.0
  }

  public init(_ _t: borrowing MyGame_Sample_Vec3_Mutable) {
    _x = _t.x
    _y = _t.y
    _z = _t.z
  }

  public var x: Float32 { _x }
  public var y: Float32 { _y }
  public var z: Float32 { _z }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    try verifier.inBuffer(position: position, of: MyGame_Sample_Vec3.self)
  }
}

extension MyGame_Sample_Vec3: Encodable {

  enum CodingKeys: String, CodingKey {
    case x = "x"
    case y = "y"
    case z = "z"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    if x != 0.0 {
      try container.encodeIfPresent(x, forKey: .x)
    }
    if y != 0.0 {
      try container.encodeIfPresent(y, forKey: .y)
    }
    if z != 0.0 {
      try container.encodeIfPresent(z, forKey: .z)
    }
  }
}

public struct MyGame_Sample_Vec3_Mutable: FlatBufferStruct, FlatbuffersVectorInitializable {

  static func validateVersion() { FlatBuffersVersion_25_9_23() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Struct

  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }

  public var x: Float32 { return _accessor.readBuffer(of: Float32.self, at: 0) }
  @discardableResult public func mutate(x: Float32) -> Bool { return _accessor.mutate(x, index: 0) }
  public var y: Float32 { return _accessor.readBuffer(of: Float32.self, at: 4) }
  @discardableResult public func mutate(y: Float32) -> Bool { return _accessor.mutate(y, index: 4) }
  public var z: Float32 { return _accessor.readBuffer(of: Float32.self, at: 8) }
  @discardableResult public func mutate(z: Float32) -> Bool { return _accessor.mutate(z, index: 8) }

  public func unpack() -> MyGame_Sample_Vec3 {
    return MyGame_Sample_Vec3(self)
  }
  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MyGame_Sample_Vec3?) -> Offset {
    guard var obj = obj else { return Offset() }
    return pack(&builder, obj: &obj)
  }

  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MyGame_Sample_Vec3) -> Offset {
    return builder.create(struct: obj)
  }
}

public struct MyGame_Sample_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {

  static func validateVersion() { FlatBuffersVersion_25_9_23() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Table

  private init(_ t: Table) { _accessor = t }
  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }

  private enum VTOFFSET: VOffset {
    case pos = 4
    case mana = 6
    case hp = 8
    case name = 10
    case inventory = 14
    case color = 16
    case weapons = 18
    case equippedType = 20
    case equipped = 22
    case path = 24
    var v: Int32 { Int32(self.rawValue) }
    var p: VOffset { self.rawValue }
  }

  public var pos: MyGame_Sample_Vec3? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : _accessor.readBuffer(of: MyGame_Sample_Vec3.self, at: o) }
  public var mutablePos: MyGame_Sample_Vec3_Mutable? { let o = _accessor.offset(VTOFFSET.pos.v); return o == 0 ? nil : MyGame_Sample_Vec3_Mutable(_accessor.bb, o: o + _accessor.position) }
  public var mana: Int16 { let o = _accessor.offset(VTOFFSET.mana.v); return o == 0 ? 150 : _accessor.readBuffer(of: Int16.self, at: o) }
  @discardableResult public func mutate(mana: Int16) -> Bool {let o = _accessor.offset(VTOFFSET.mana.v);  return _accessor.mutate(mana, index: o) }
  public var hp: Int16 { let o = _accessor.offset(VTOFFSET.hp.v); return o == 0 ? 100 : _accessor.readBuffer(of: Int16.self, at: o) }
  @discardableResult public func mutate(hp: Int16) -> Bool {let o = _accessor.offset(VTOFFSET.hp.v);  return _accessor.mutate(hp, index: o) }
  public var name: String? { let o = _accessor.offset(VTOFFSET.name.v); return o == 0 ? nil : _accessor.string(at: o) }
  public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.name.v) }
  public var inventory: FlatbufferVector<UInt8> { return _accessor.vector(at: VTOFFSET.inventory.v, byteSize: 1) }
  public func mutate(inventory: UInt8, at index: Int32) -> Bool { let o = _accessor.offset(VTOFFSET.inventory.v); return _accessor.directMutate(inventory, index: _accessor.vector(at: o) + index * 1) }
  public func withUnsafePointerToInventory<T>(_ body: (UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return try _accessor.withUnsafePointerToSlice(at: VTOFFSET.inventory.v, body: body) }
  public var color: MyGame_Sample_Color { let o = _accessor.offset(VTOFFSET.color.v); return o == 0 ? .blue : MyGame_Sample_Color(rawValue: _accessor.readBuffer(of: Int8.self, at: o)) ?? .blue }
  @discardableResult public func mutate(color: MyGame_Sample_Color) -> Bool {let o = _accessor.offset(VTOFFSET.color.v);  return _accessor.mutate(color.rawValue, index: o) }
  public var weapons: FlatbufferVector<MyGame_Sample_Weapon> { return _accessor.vector(at: VTOFFSET.weapons.v, byteSize: 4) }
  public var equippedType: MyGame_Sample_Equipment { let o = _accessor.offset(VTOFFSET.equippedType.v); return o == 0 ? .none_ : MyGame_Sample_Equipment(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none_ }
  public func equipped<T: FlatbuffersInitializable>(type: T.Type) -> T? { let o = _accessor.offset(VTOFFSET.equipped.v); return o == 0 ? nil : _accessor.union(o) }
  public var path: FlatbufferVector<MyGame_Sample_Vec3> { return _accessor.vector(at: VTOFFSET.path.v, byteSize: 12) }
  public var mutablePath: FlatbufferVector<MyGame_Sample_Vec3_Mutable> { return _accessor.vector(at: VTOFFSET.path.v, byteSize: 12) }
  public func withUnsafePointerToPath<T>(_ body: (UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return try _accessor.withUnsafePointerToSlice(at: VTOFFSET.path.v, body: body) }
  public static func startMonster(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 11) }
  public static func add(pos: MyGame_Sample_Vec3?, _ fbb: inout FlatBufferBuilder) { guard let pos = pos else { return }; fbb.create(struct: pos, position: VTOFFSET.pos.p) }
  public static func add(mana: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: VTOFFSET.mana.p) }
  public static func add(hp: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: VTOFFSET.hp.p) }
  public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
  public static func addVectorOf(inventory: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: inventory, at: VTOFFSET.inventory.p) }
  public static func add(color: MyGame_Sample_Color, _ fbb: inout FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 2, at: VTOFFSET.color.p) }
  public static func addVectorOf(weapons: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: weapons, at: VTOFFSET.weapons.p) }
  public static func add(equippedType: MyGame_Sample_Equipment, _ fbb: inout FlatBufferBuilder) { fbb.add(element: equippedType.rawValue, def: 0, at: VTOFFSET.equippedType.p) }
  public static func add(equipped: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: equipped, at: VTOFFSET.equipped.p) }
  public static func addVectorOf(path: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: path, at: VTOFFSET.path.p) }
  public static func startVectorOfPath(_ size: Int, in builder: inout FlatBufferBuilder) {
    builder.startVector(size * MemoryLayout<MyGame_Sample_Vec3>.size, elementSize: MemoryLayout<MyGame_Sample_Vec3>.alignment)
  }
  public static func endMonster(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
  public static func createMonster(
    _ fbb: inout FlatBufferBuilder,
    pos: MyGame_Sample_Vec3? = nil,
    mana: Int16 = 150,
    hp: Int16 = 100,
    nameOffset name: Offset = Offset(),
    inventoryVectorOffset inventory: Offset = Offset(),
    color: MyGame_Sample_Color = .blue,
    weaponsVectorOffset weapons: Offset = Offset(),
    equippedType: MyGame_Sample_Equipment = .none_,
    equippedOffset equipped: Offset = Offset(),
    pathVectorOffset path: Offset = Offset()
  ) -> Offset {
    let __start = MyGame_Sample_Monster.startMonster(&fbb)
    MyGame_Sample_Monster.add(pos: pos, &fbb)
    MyGame_Sample_Monster.add(mana: mana, &fbb)
    MyGame_Sample_Monster.add(hp: hp, &fbb)
    MyGame_Sample_Monster.add(name: name, &fbb)
    MyGame_Sample_Monster.addVectorOf(inventory: inventory, &fbb)
    MyGame_Sample_Monster.add(color: color, &fbb)
    MyGame_Sample_Monster.addVectorOf(weapons: weapons, &fbb)
    MyGame_Sample_Monster.add(equippedType: equippedType, &fbb)
    MyGame_Sample_Monster.add(equipped: equipped, &fbb)
    MyGame_Sample_Monster.addVectorOf(path: path, &fbb)
    return MyGame_Sample_Monster.endMonster(&fbb, start: __start)
  }

  public func unpack() -> MyGame_Sample_MonsterT {
    return MyGame_Sample_MonsterT(self)
  }
  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MyGame_Sample_MonsterT?) -> Offset {
    guard var obj = obj else { return Offset() }
    return pack(&builder, obj: &obj)
  }

  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MyGame_Sample_MonsterT) -> Offset {
    let __name: Offset
    if let s = obj.name {
      __name = builder.create(string: s)
    } else {
      __name = Offset()
    }

    let __inventory = builder.createVector(obj.inventory)
    var __weapons__: [Offset] = []
    for var i in obj.weapons {
      __weapons__.append(MyGame_Sample_Weapon.pack(&builder, obj: &i))
    }
    let __weapons = builder.createVector(ofOffsets: __weapons__)
    let __equipped = obj.equipped?.pack(builder: &builder) ?? Offset()
    MyGame_Sample_Monster.startVectorOfPath(obj.path.count, in: &builder)
    for val in obj.path {
      builder.create(struct: val)
    }
    let __path = builder.endVector(len: obj.path.count)
    let __root = MyGame_Sample_Monster.startMonster(&builder)
    MyGame_Sample_Monster.add(pos: obj.pos, &builder)
    MyGame_Sample_Monster.add(mana: obj.mana, &builder)
    MyGame_Sample_Monster.add(hp: obj.hp, &builder)
    MyGame_Sample_Monster.add(name: __name, &builder)
    MyGame_Sample_Monster.addVectorOf(inventory: __inventory, &builder)
    MyGame_Sample_Monster.add(color: obj.color, &builder)
    MyGame_Sample_Monster.addVectorOf(weapons: __weapons, &builder)
    if let o = obj.equipped?.type {
      MyGame_Sample_Monster.add(equippedType: o, &builder)
      MyGame_Sample_Monster.add(equipped: __equipped, &builder)
    }

    MyGame_Sample_Monster.addVectorOf(path: __path, &builder)
    return MyGame_Sample_Monster.endMonster(&builder, start: __root)
  }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    var _v = try verifier.visitTable(at: position)
    try _v.visit(field: VTOFFSET.pos.p, fieldName: "pos", required: false, type: MyGame_Sample_Vec3.self)
    try _v.visit(field: VTOFFSET.mana.p, fieldName: "mana", required: false, type: Int16.self)
    try _v.visit(field: VTOFFSET.hp.p, fieldName: "hp", required: false, type: Int16.self)
    try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: false, type: ForwardOffset<String>.self)
    try _v.visit(field: VTOFFSET.inventory.p, fieldName: "inventory", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
    try _v.visit(field: VTOFFSET.color.p, fieldName: "color", required: false, type: MyGame_Sample_Color.self)
    try _v.visit(field: VTOFFSET.weapons.p, fieldName: "weapons", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Sample_Weapon>, MyGame_Sample_Weapon>>.self)
    try _v.visit(unionKey: VTOFFSET.equippedType.p, unionField: VTOFFSET.equipped.p, unionKeyName: "equippedType", fieldName: "equipped", required: false, completion: { (verifier, key: MyGame_Sample_Equipment, pos) in
      switch key {
      case .none_:
        break // NOTE - SWIFT doesnt support none
      case .weapon:
        try ForwardOffset<MyGame_Sample_Weapon>.verify(&verifier, at: pos, of: MyGame_Sample_Weapon.self)
      }
    })
    try _v.visit(field: VTOFFSET.path.p, fieldName: "path", required: false, type: ForwardOffset<Vector<MyGame_Sample_Vec3, MyGame_Sample_Vec3>>.self)
    _v.finish()
  }
}

extension MyGame_Sample_Monster: Encodable {

  enum CodingKeys: String, CodingKey {
    case pos = "pos"
    case mana = "mana"
    case hp = "hp"
    case name = "name"
    case inventory = "inventory"
    case color = "color"
    case weapons = "weapons"
    case equippedType = "equipped_type"
    case equipped = "equipped"
    case path = "path"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encodeIfPresent(pos, forKey: .pos)
    if mana != 150 {
      try container.encodeIfPresent(mana, forKey: .mana)
    }
    if hp != 100 {
      try container.encodeIfPresent(hp, forKey: .hp)
    }
    try container.encodeIfPresent(name, forKey: .name)
    try container.encodeIfPresent(inventory, forKey: .inventory)
    if color != .blue {
      try container.encodeIfPresent(color, forKey: .color)
    }
    try container.encodeIfPresent(weapons, forKey: .weapons)
    if equippedType != .none_ {
      try container.encodeIfPresent(equippedType, forKey: .equippedType)
    }
    switch equippedType {
    case .weapon:
      let _v = equipped(type: MyGame_Sample_Weapon.self)
      try container.encodeIfPresent(_v, forKey: .equipped)
    default: break;
    }
    try container.encodeIfPresent(path, forKey: .path)
  }
}

public class MyGame_Sample_MonsterT: NativeObject {

  public var pos: MyGame_Sample_Vec3?
  public var mana: Int16
  public var hp: Int16
  public var name: String?
  public var inventory: [UInt8]
  public var color: MyGame_Sample_Color
  public var weapons: [MyGame_Sample_WeaponT?]
  public var equipped: MyGame_Sample_EquipmentUnion?
  public var path: [MyGame_Sample_Vec3]

  public init(_ _t: borrowing MyGame_Sample_Monster) {
    pos = _t.pos
    mana = _t.mana
    hp = _t.hp
    name = _t.name
    inventory = []
    inventory.append(contentsOf: _t.inventory)
    color = _t.color
    weapons = []
    for val in _t.weapons{
        weapons.append(val.unpack())
    }
    switch _t.equippedType {
    case .weapon:
      let _v = _t.equipped(type: MyGame_Sample_Weapon.self)
      equipped = MyGame_Sample_EquipmentUnion(_v?.unpack(), type: .weapon)
    default: break
    }
    path = []
    path.append(contentsOf: _t.path)
  }

  public init() {
    pos = MyGame_Sample_Vec3()
    mana = 150
    hp = 100
    inventory = []
    color = .blue
    weapons = []
    path = []
  }

  public func serialize() -> ByteBuffer { return serialize(type: MyGame_Sample_Monster.self) }

}
public struct MyGame_Sample_Weapon: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker {

  static func validateVersion() { FlatBuffersVersion_25_9_23() }
  public var __buffer: ByteBuffer! { return _accessor.bb }
  private var _accessor: Table

  private init(_ t: Table) { _accessor = t }
  public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }

  private enum VTOFFSET: VOffset {
    case name = 4
    case damage = 6
    var v: Int32 { Int32(self.rawValue) }
    var p: VOffset { self.rawValue }
  }

  public var name: String? { let o = _accessor.offset(VTOFFSET.name.v); return o == 0 ? nil : _accessor.string(at: o) }
  public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VTOFFSET.name.v) }
  public var damage: Int16 { let o = _accessor.offset(VTOFFSET.damage.v); return o == 0 ? 0 : _accessor.readBuffer(of: Int16.self, at: o) }
  @discardableResult public func mutate(damage: Int16) -> Bool {let o = _accessor.offset(VTOFFSET.damage.v);  return _accessor.mutate(damage, index: o) }
  public static func startWeapon(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) }
  public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VTOFFSET.name.p) }
  public static func add(damage: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: damage, def: 0, at: VTOFFSET.damage.p) }
  public static func endWeapon(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
  public static func createWeapon(
    _ fbb: inout FlatBufferBuilder,
    nameOffset name: Offset = Offset(),
    damage: Int16 = 0
  ) -> Offset {
    let __start = MyGame_Sample_Weapon.startWeapon(&fbb)
    MyGame_Sample_Weapon.add(name: name, &fbb)
    MyGame_Sample_Weapon.add(damage: damage, &fbb)
    return MyGame_Sample_Weapon.endWeapon(&fbb, start: __start)
  }

  public func unpack() -> MyGame_Sample_WeaponT {
    return MyGame_Sample_WeaponT(self)
  }
  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MyGame_Sample_WeaponT?) -> Offset {
    guard var obj = obj else { return Offset() }
    return pack(&builder, obj: &obj)
  }

  public static func pack(_ builder: inout FlatBufferBuilder, obj: inout MyGame_Sample_WeaponT) -> Offset {
    let __name: Offset
    if let s = obj.name {
      __name = builder.create(string: s)
    } else {
      __name = Offset()
    }

    let __root = MyGame_Sample_Weapon.startWeapon(&builder)
    MyGame_Sample_Weapon.add(name: __name, &builder)
    MyGame_Sample_Weapon.add(damage: obj.damage, &builder)
    return MyGame_Sample_Weapon.endWeapon(&builder, start: __root)
  }

  public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
    var _v = try verifier.visitTable(at: position)
    try _v.visit(field: VTOFFSET.name.p, fieldName: "name", required: false, type: ForwardOffset<String>.self)
    try _v.visit(field: VTOFFSET.damage.p, fieldName: "damage", required: false, type: Int16.self)
    _v.finish()
  }
}

extension MyGame_Sample_Weapon: Encodable {

  enum CodingKeys: String, CodingKey {
    case name = "name"
    case damage = "damage"
  }
  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encodeIfPresent(name, forKey: .name)
    if damage != 0 {
      try container.encodeIfPresent(damage, forKey: .damage)
    }
  }
}

public class MyGame_Sample_WeaponT: NativeObject {

  public var name: String?
  public var damage: Int16

  public init(_ _t: borrowing MyGame_Sample_Weapon) {
    name = _t.name
    damage = _t.damage
  }

  public init() {
    damage = 0
  }

  public func serialize() -> ByteBuffer { return serialize(type: MyGame_Sample_Weapon.self) }

}
