#tags #unique-identifier #bevy #cheap #moonshine #prelude #filter

moonshine-tag

为 Bevy 设计的廉价、快速、大部分唯一的标识符

1 个不稳定版本

0.1.0 2024 年 7 月 24 日

#1091游戏开发

Download history 95/week @ 2024-07-20 28/week @ 2024-07-27

123 每月下载量

MIT 许可证

23KB
416

🏷️ Moonshine Tag

crates.io downloads docs.rs license stars

为 Bevy 设计的廉价、快速、大部分唯一的标识符。

概述

Tag 代表一个廉价、通用、稍微唯一的标识符,可以用于将“事物”相互关联或用于动态标记实体。

use bevy::prelude::*;
use moonshine_tag::{prelude::*, self as tag};

tags! { APPLE, ORANGE, JUICY, CRUNCHY, POISONED }

let mut world = World::new();

// Spawn some fruits!
let a = world.spawn([APPLE, CRUNCHY].into_tags()).id();
let b = world.spawn([ORANGE, JUICY].into_tags()).id();
let c = world.spawn([APPLE, CRUNCHY, POISONED].into_tags()).id();

// Only crunchy, edible apples, please! :)
let filter: TagFilter = (APPLE & CRUNCHY) & !POISONED;

assert!(filter.allows(world.tags(a)));

assert!(!filter.allows(world.tags(b)));
assert!(!filter.allows(world.tags(c)));

功能

  • 标签易于创建、复制、比较,并且“足够唯一”。它仅仅是一个 u64
  • 支持标签和标签过滤器的序列化
  • 能够定义复杂的标签过滤表达式
  • 简单的实现,没有样板代码和过程宏 🧘

用法

标签

您可以从任何任意字符串定义标签

use moonshine_tag::prelude::*;

tags! { A0 }; // Convenient macro

const A1: Tag = Tag::new("A"); // Manual constant

let a2 = Tag::new("A"); // Runtime

assert_eq!(A0, A1);
assert_eq!(A0, a2);

具有相同名称的两个标签被认为是相等的。

Tags 是用于管理标签集合的专用集合

use moonshine_tag::prelude::*;

tags! { A, B, C }

let a: Tags = A.into_tags();
let ab = [A, B].into_tags();
let c = C.into_tags();
let ac = a.union(c);

标签过滤器

TagFilter 用于测试给定的 Tags 集合是否匹配某个模式

use moonshine_tag::prelude::*;

tags! { A, B, C }

let a = A.into_tags();
let c = C.into_tags();

let a_or_b: TagFilter = A | B;

assert!(a_or_b.allows(a));
assert!(!a_or_b.allows(c));

标签过滤器可以组合在一起以创建复杂的表达式

use moonshine_tag::prelude::*;

tags! { A, B, C, D }

let ab = [A, B].into_tags();
let c = C.into_tags();
let cd = [C, D].into_tags();

let filter = ([A, B] | C) & D;

assert!(!filter.allows(ab));
assert!(!filter.allows(c));
assert!(filter.allows(cd));

限制和指南

在内部,标签只是它们字符串表示的 FNV-1a (为什么?) 哈希。这使得它们非常廉价地使用,但这意味着它们 不能保证是唯一的

该库的假设是,在大多数游戏应用领域,这是一个小而可能的问题。

在大多数应用程序中,同一子系统内两个不同标签之间的冲突可能性很低,非致命,并且容易纠正(只需重命名其中一个标签即可!)。

但是,您 不应 使用标签进行任何加密目的,或作为全局唯一标识符。

相反,最好将它们用于方便的动态模式匹配或标记系统中的“事物”,特别是实体。

依赖关系

~11MB
~194K SLoC