#macro #packets #netcode #gamedev #packet #durian

durian_macros

duriancrate的宏,便于创建Packet结构体

5个版本 (3个破坏性更新)

0.4.1 2023年7月30日
0.4.0 2023年7月30日
0.3.0 2023年2月19日
0.2.0 2022年12月10日
0.1.0 2022年12月8日

#682 in 游戏开发


3个Crate中使用(通过durian

MIT许可证

13KB
59 代码行

durian_macros

duriancrate的宏

这些宏不应单独使用!这些宏依赖于在durian中定义的Traits和路径

过程宏

用于轻松注释结构体为Packets并自动实现PacketBuilders的过程宏。唯一的要求是结构体必须是可反序列化的,这意味着所有嵌套字段也必须是可反序列化的。

#[bincode_packet]将使用bincode反/序列化您的Packet,并自动为您应用必要的derive宏。

use durian::bincode_packet;

// Automatically implements Packet, and generates a PositionPacketBuilder that implements 
// PacketBuilder.  You can also add other macros such as derive macros so long s they don't
// conflict with what #[bincode_packet] adds (See bincode_packet documentation).
#[bincode_packet]
#[derive(Debug)]
struct Position {
    x: i32,
    y: i32
}

// Works for Unit (empty) structs as well
#[bincode_packet]
struct Ack;

您还可以手动使用derive宏(BinPacketUnitPacket

use durian::serde::{Deserialize, Serialize};
use durian::{BinPacket, UnitPacket};

#[derive(Serialize, Deserialize, BinPacket)]
#[serde(crate = "durian::serde")]
struct Position { x: i32, y: i32 }

#[derive(UnitPacket)]
struct Ack;

声明式宏

用于轻松简洁地调用PacketManager的常规宏。

这包括用于注册所有您的sendreceive数据包的宏

其中<send packets>是一个您的send数据包类型的序列,或这些类型的切片,而<receive packets>是包含(您的receive数据包类型和关联的数据包构建器)的元组的序列,或这些元组的切片。

示例

use durian::{bincode_packet, register_send, register_receive, PacketManager};

// Send packets
#[bincode_packet]
struct Position { x: i32, y: i32 }
#[bincode_packet]
struct Ack;

// Receive packets
#[bincode_packet]
struct UpdatePosition { x: i32, y: i32 }
#[bincode_packet]
struct NewMessage { message: String }

fn main() {
    let manager = PacketManager::new();
    let register_receive_results = register_receive!(
        manager, 
        (UpdatePosition, UpdatePositionPacketBuilder), 
        (NewMessage, NewMessagePacketBuilder)
    );
    // Or equivalently in a slice, 
    // register_receive_results!(manager, 
    //      [(UpdatePosition, UpdatePositionPacketBuilder), (NewMessage, NewMessagePacketBuilder)]
    // );`

    let register_send_results = register_send!(manager, Position, Ack);
    // Or equivalently in a slice, `register_send!(manager, [Position, Ack]);`

    // You can then validate that all the registrations were successful:
    assert!(register_receive_results.iter().all(|r| r.is_ok()));
    assert!(register_send_results.iter().all(|r| r.is_ok()));

    // The macros used above are equivalent to the following manual registration:
    //
    // manager.register_receive_packet::<UpdatePosition>(UpdatePositionPacketBuilder);
    // manager.register_receive_packet::<NewMessage>(NewMessagePacketBuilder);
    // manager.register_send_packet::<Position>();
    // manager.register_send_packet::<Ack>();
}

依赖项

~0.6–1.2MB
~29K SLoC