// 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_12_19() }

  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_12_19() }
  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_12_19() }
  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_12_19() }
  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) }

}
