// 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 struct VT {
    static let pos: VOffset = 4
    static let mana: VOffset = 6
    static let hp: VOffset = 8
    static let name: VOffset = 10
    static let inventory: VOffset = 14
    static let color: VOffset = 16
    static let weapons: VOffset = 18
    static let equippedType: VOffset = 20
    static let equipped: VOffset = 22
    static let path: VOffset = 24
  }

  public var pos: MyGame_Sample_Vec3? { let o = _accessor.offset(VT.pos); return o == 0 ? nil : _accessor.readBuffer(of: MyGame_Sample_Vec3.self, at: o) }
  public var mutablePos: MyGame_Sample_Vec3_Mutable? { let o = _accessor.offset(VT.pos); return o == 0 ? nil : MyGame_Sample_Vec3_Mutable(_accessor.bb, o: o + _accessor.position) }
  public var mana: Int16 { let o = _accessor.offset(VT.mana); return o == 0 ? 150 : _accessor.readBuffer(of: Int16.self, at: o) }
  @discardableResult public func mutate(mana: Int16) -> Bool {let o = _accessor.offset(VT.mana);  return _accessor.mutate(mana, index: o) }
  public var hp: Int16 { let o = _accessor.offset(VT.hp); return o == 0 ? 100 : _accessor.readBuffer(of: Int16.self, at: o) }
  @discardableResult public func mutate(hp: Int16) -> Bool {let o = _accessor.offset(VT.hp);  return _accessor.mutate(hp, index: o) }
  public var name: String? { let o = _accessor.offset(VT.name); return o == 0 ? nil : _accessor.string(at: o) }
  public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VT.name) }
  public var inventory: FlatbufferVector<UInt8> { return _accessor.vector(at: VT.inventory, byteSize: 1) }
  public func mutate(inventory: UInt8, at index: Int32) -> Bool { let o = _accessor.offset(VT.inventory); 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: VT.inventory, body: body) }
  public var color: MyGame_Sample_Color { let o = _accessor.offset(VT.color); 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(VT.color);  return _accessor.mutate(color.rawValue, index: o) }
  public var weapons: FlatbufferVector<MyGame_Sample_Weapon> { return _accessor.vector(at: VT.weapons, byteSize: 4) }
  public var equippedType: MyGame_Sample_Equipment { let o = _accessor.offset(VT.equippedType); 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(VT.equipped); return o == 0 ? nil : _accessor.union(o) }
  public var path: FlatbufferVector<MyGame_Sample_Vec3> { return _accessor.vector(at: VT.path, byteSize: 12) }
  public var mutablePath: FlatbufferVector<MyGame_Sample_Vec3_Mutable> { return _accessor.vector(at: VT.path, byteSize: 12) }
  public func withUnsafePointerToPath<T>(_ body: (UnsafeRawBufferPointer, Int) throws -> T) rethrows -> T? { return try _accessor.withUnsafePointerToSlice(at: VT.path, 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: VT.pos) }
  public static func add(mana: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: VT.mana) }
  public static func add(hp: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: VT.hp) }
  public static func add(name: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: name, at: VT.name) }
  public static func addVectorOf(inventory: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: inventory, at: VT.inventory) }
  public static func add(color: MyGame_Sample_Color, _ fbb: inout FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 2, at: VT.color) }
  public static func addVectorOf(weapons: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: weapons, at: VT.weapons) }
  public static func add(equippedType: MyGame_Sample_Equipment, _ fbb: inout FlatBufferBuilder) { fbb.add(element: equippedType.rawValue, def: 0, at: VT.equippedType) }
  public static func add(equipped: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: equipped, at: VT.equipped) }
  public static func addVectorOf(path: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: path, at: VT.path) }
  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: VT.pos, fieldName: "pos", required: false, type: MyGame_Sample_Vec3.self)
    try _v.visit(field: VT.mana, fieldName: "mana", required: false, type: Int16.self)
    try _v.visit(field: VT.hp, fieldName: "hp", required: false, type: Int16.self)
    try _v.visit(field: VT.name, fieldName: "name", required: false, type: ForwardOffset<String>.self)
    try _v.visit(field: VT.inventory, fieldName: "inventory", required: false, type: ForwardOffset<Vector<UInt8, UInt8>>.self)
    try _v.visit(field: VT.color, fieldName: "color", required: false, type: MyGame_Sample_Color.self)
    try _v.visit(field: VT.weapons, fieldName: "weapons", required: false, type: ForwardOffset<Vector<ForwardOffset<MyGame_Sample_Weapon>, MyGame_Sample_Weapon>>.self)
    try _v.visit(unionKey: VT.equippedType, unionField: VT.equipped, 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: VT.path, 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 struct VT {
    static let name: VOffset = 4
    static let damage: VOffset = 6
  }

  public var name: String? { let o = _accessor.offset(VT.name); return o == 0 ? nil : _accessor.string(at: o) }
  public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: VT.name) }
  public var damage: Int16 { let o = _accessor.offset(VT.damage); return o == 0 ? 0 : _accessor.readBuffer(of: Int16.self, at: o) }
  @discardableResult public func mutate(damage: Int16) -> Bool {let o = _accessor.offset(VT.damage);  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: VT.name) }
  public static func add(damage: Int16, _ fbb: inout FlatBufferBuilder) { fbb.add(element: damage, def: 0, at: VT.damage) }
  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: VT.name, fieldName: "name", required: false, type: ForwardOffset<String>.self)
    try _v.visit(field: VT.damage, 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) }

}
