# automatically generated by the FlatBuffers compiler, do not modify

# namespace: Example

import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()

class StructOfStructs(object):
    __slots__ = ['_tab']

    @classmethod
    def SizeOf(cls):
        return 20

    # StructOfStructs
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # StructOfStructs
    def A(self, obj):
        obj.Init(self._tab.Bytes, self._tab.Pos + 0)
        return obj

    # StructOfStructs
    def B(self, obj):
        obj.Init(self._tab.Bytes, self._tab.Pos + 8)
        return obj

    # StructOfStructs
    def C(self, obj):
        obj.Init(self._tab.Bytes, self._tab.Pos + 12)
        return obj


def CreateStructOfStructs(builder, a_id, a_distance, b_a, b_b, c_id, c_distance):
    builder.Prep(4, 20)
    builder.Prep(4, 8)
    builder.PrependUint32(c_distance)
    builder.PrependUint32(c_id)
    builder.Prep(2, 4)
    builder.Pad(1)
    builder.PrependInt8(b_b)
    builder.PrependInt16(b_a)
    builder.Prep(4, 8)
    builder.PrependUint32(a_distance)
    builder.PrependUint32(a_id)
    return builder.Offset()

import MyGame.Example.Ability
import MyGame.Example.Test
try:
    from typing import Optional
except:
    pass

class StructOfStructsT(object):

    # StructOfStructsT
    def __init__(self):
        self.a = None  # type: Optional[MyGame.Example.Ability.AbilityT]
        self.b = None  # type: Optional[MyGame.Example.Test.TestT]
        self.c = None  # type: Optional[MyGame.Example.Ability.AbilityT]

    @classmethod
    def InitFromBuf(cls, buf, pos):
        structOfStructs = StructOfStructs()
        structOfStructs.Init(buf, pos)
        return cls.InitFromObj(structOfStructs)

    @classmethod
    def InitFromPackedBuf(cls, buf, pos=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, pos)
        return cls.InitFromBuf(buf, pos+n)

    @classmethod
    def InitFromObj(cls, structOfStructs):
        x = StructOfStructsT()
        x._UnPack(structOfStructs)
        return x

    # StructOfStructsT
    def _UnPack(self, structOfStructs):
        if structOfStructs is None:
            return
        if structOfStructs.A(MyGame.Example.Ability.Ability()) is not None:
            self.a = MyGame.Example.Ability.AbilityT.InitFromObj(structOfStructs.A(MyGame.Example.Ability.Ability()))
        if structOfStructs.B(MyGame.Example.Test.Test()) is not None:
            self.b = MyGame.Example.Test.TestT.InitFromObj(structOfStructs.B(MyGame.Example.Test.Test()))
        if structOfStructs.C(MyGame.Example.Ability.Ability()) is not None:
            self.c = MyGame.Example.Ability.AbilityT.InitFromObj(structOfStructs.C(MyGame.Example.Ability.Ability()))

    # StructOfStructsT
    def Pack(self, builder):
        return CreateStructOfStructs(builder, self.a.id, self.a.distance, self.b.a, self.b.b, self.c.id, self.c.distance)
