Syntax:
#[entity_id(WrapperName)] -- default policy (256)
#[entity_id(WrapperName, options...)] -- custom policy (named argument)
#[entity_id(WrapperName, opaque)] -- opaque ID with default policy (256)
#[entity_id(WrapperName, options..., opaque)] -- opaque ID with custom policy
pub struct|enum|union ObjType { ... }
Options:
policy = <PolicyType>: specify allocation policy type, e.g.,256 | Policy256 | AllocPolicy256.opaque: makes the wrapper opaque (restricts field visibility to crate-only)allocator_type = AllocTypeName: generates a type alias for the correspondingEntityAlloc<Obj, Policy>backend = ptr | index: choose backend ID type (default:ptr)
Example (pointer backend, allocator alias):
#[entity_id(MyInstID, policy = 256, backend = ptr, allocator_type = MyInstAlloc)]
struct Inst { /* fields */ }
let alloc: MyInstAlloc = MyInstAlloc::new();
let raw = alloc.allocate_ptr(Inst { /* init */ });
let id = MyInstID::from(raw);
let obj = id.deref_alloc(&alloc);
Example (index backend):
#[entity_id(MyIdxID, policy = 256, backend = index)]
struct Inst { /* fields */ }
let alloc: EntityAlloc<Inst, AllocPolicy256> = EntityAlloc::new();
let raw = IndexedID::allocate_from(&alloc, Inst { /* init */ });
let id = MyIdxID::from_backend(raw);
let obj = id.deref_alloc(&alloc);
Wrapper types intentionally DO NOT expose high-level allocate/free convenience methods.
Allocation always happens at the raw layer (allocate_ptr, allocate_index, or
IEntityAllocID::allocate_from), then wrapped via from_backend.
Generates:
/// non-opaque wrapper
pub struct $WrapperName(pub $ObjType);
/// opaque wrapper
pub struct $WrapperName(pub(crate) $ObjType);
Implements `$crate::IPoliciedID` so the wrapper can be used anywhere
a raw policy-bound ID is expected. Allocation remains at the lower layer:
create a value with the allocator, then wrap with `WrapperName::from_backend(...)`.