Package: bridgestream
BridgeStreamBridgeStream is a order oriented binary serialization library developed for performance and efficiency.BridgeStream is used as a part of an real-time online game to
transmit data between the client and servers.You can encode/decode primitive types, collection on primitives, custom serializers and other BridgeStream's easily
and efficiently.InstallpipinstallbridgestreamBasic UsageCreate a streamfrombridgestreamimportBridgeStreamstream=BridgeStream()Write some datastream.write_int(1)stream.write_string("test")stream.write_float(0.1)stream.write_bool(True)Encodedata=stream.encode()Decodestream=BridgeStream(data)Read in orderstream.read_int()# 1stream.read_string()# teststream.read_float()# 0.1stream.read_bool()# TrueCustom TypesYou can define your own serializers to abstract your common data types usingBridgeSerializer.You must implement thewritemethod ofBridgeSerializerto be able to encode it as astreamand you must implement thereadmethod to be able to decode it as astream.frombridgestreamimportBridgeSerializer@dataclass# dataclass is not required but recommendedclassVector3(BridgeSerializer):x:inty:intz:intdefwrite(self,stream:BridgeStream):stream.write_int(self.x)stream.write_int(self.y)stream.write_int(self.z)defread(self,stream:BridgeStream):self.x=stream.write_int(x)self.y=stream.write_int(y)self.z=stream.write_int(z)You can encode custom serializers using thewritemethod ofBridgeStream.vector=Vector3(1,0,2)stream=BridgeStream()stream.write(vector)data=stream.encode()You can decode a custom serializer using theread(BirdgeSerializer)method ofBridgeStream.stream=BridgeStream(data)vector=stream.read(Vector3)# Vector3(x=1, y=0, z=2)You can also read/write list of custom serializers.vectors=[Vector3(1,0,2),Vector3(3,-1,4)]stream=BridgeStream()stream.write_list(vector)data=stream.encode()stream=BridgeStream(data)vector=stream.read_list(Vector3)# [Vector3(x=1, y=0, z=2), ector3(x=3, y=-1, z=4)]Nested BridgeStreamSome times it is necessary to write a bridgestream within another bridgestream. In this example; we have 2 different serializers that have the same purposes. Each Serializer can do its business logic within its own read/write methods and still can be serialized as a whole.Class definitions@dataclassclassWarriorLevel(BridgeSerializer):health:intattack_radious:intshield:intdefwrite(self,stream:BridgeStream):stream.write_int(self.health)stream.write_int(self.attack_radious)stream.write_int(self.shield)defread(self,stream:BridgeStream):self.health=stream.read_int()self.attack_radious=stream.read_int()self.shield=stream.read_int()@dataclassclassMageLevel(BridgeSerializer):health:intprojectile_damage:intregeneration:intdefwrite(self,stream:BridgeStream):stream.write_int(self.health)stream.write_int(self.projectile_damage)stream.write_int(self.regeneration)defread(self,stream:BridgeStream):self.health=stream.read_int()self.projectile_damage=stream.read_int()self.regeneration=stream.read_int()@dataclassclassWarrior(BridgeSerializer):id:strattack_speed:floatatack_cooldown:floatlevels:List[WarriorLevel]defwrite(self,stream):stream.write_string(self.id)stream.write_float(self.attack_speed)stream.write_float(self.atack_cooldown)stream.write_list(self.levels)defread(self,stream):self.id=stream.read_string()self.attack_speed=stream.read_float()self.atack_cooldown=stream.read_float()self.levels=stream.read_list(WarriorLevel)@dataclassclassMage(BridgeSerializer):id:strprojectile_range:floatprojectile_speed:floatlevels:List[MageLevel]defwrite(self,stream:BridgeStream):stream.write_string(self.id)stream.write_float(self.projectile_range)stream.write_float(self.projectile_speed)stream.write_list(self.levels)defread(self,stream:BridgeStream):self.id=stream.read_string()self.attack_speed=stream.read_float()self.atack_cooldown=stream.read_float()self.levels=stream.read_list(MageLevel)@dataclassclassPlayer(BridgeSerializer):name:strlevel:intheroes:List[str]defwrite(self,stream:BridgeStream):stream.write_string(self.name)stream.write_int(self.level)stream.write_string_list(self.heroes)defread(self,stream:BridgeStream):self.name=stream.read_string()self.level=stream.read_int()self.heroes=stream.read_string_list()Initializationplayer=Player(name="player-1",level=5,heroes=["w-1","m-1"])hero_cofigurations={"warrior":Warrior(id="w-1",attack_speed=0.4,atack_cooldown=0.2,levels=[WarriorLevel(300,50,1),WarriorLevel(340,55,1.2)]),"mage":Mage(id="m-1",projectile_range=400,projectile_speed=1.4,levels=[MageLevel(1.5,30,5),MageLevel(340,35,10)]),}Nested encoding & decodingstream=BridgeStream()stream.write(player)hero_config_stream=BridgeStream()forclass_name,configinhero_cofigurations.items():hero_config_stream.write_string(class_name)hero_config_stream.write(config)stream.write_stream(hero_config_stream)data=stream.encode()stream=BridgeStream(data)player=stream.read(Player)# Player(name="player-1", level=5, heroes=["w-1", "m-1"])# Read the stream to the end and create config by typeshero_classes={"warrior":Warrior,"mage":Mage}hero_cofigurations={}whilestream.has_more():class_name=stream.read_string()config=stream.read(hero_classes[class_name])hero_cofigurations[class_name]=confighero_cofigurations"""{"warrior": Warrior(id="w-1",attack_speed=0.4,atack_cooldown=0.2,levels=[WarriorLevel(300, 50, 1), WarriorLevel(340, 55, 1.2)]),"mage": Mage(id="m-1",projectile_range=400,projectile_speed=1.4,levels=[MageLevel(1.5, 30, 5), MageLevel(340, 35, 10)]),}"""