const std = @import("std"); const c = @import("./c.zig"); const Lookup = @import("./main.zig").Lookup; const Entity = @import("./entity.zig").Entity; const Pair = @import("./pair.zig").Pair; const Id = @import("./id.zig").Id; /// Converts the specified value to an `ecs_entity_t`. /// /// If `null` is passed to this function, either directly or through an /// optional type of one of the supported types, `0` is returned. It's up to /// the caller to do any necessary testing for `0` values, and whether the /// returned entity is valid or alive. /// /// The following can be converted: /// - `Entity` and `ecs_entity_t` - Self-explanatory. /// - `type` - Looks up the entity associated with that type. pub fn anyToEntity(comptime ctx: anytype, value: anytype) c.ecs_entity_t { return switch (@TypeOf(value)) { @TypeOf(null) => 0, c.ecs_entity_t => value, Entity(ctx) => value.raw, ?Entity(ctx) => if (value) |v| v.raw else 0, type => Lookup(ctx, value).id, else => @compileError("Value of type " ++ @typeName(@TypeOf(value)) ++ " can't be converted to Entity"), }; } /// Converts the specified value to an `ecs_id_t`. /// /// If `null` is passed to this function, either directly or through an /// optional type of one of the supported types, `0` is returned. It's up to /// the caller to do any necessary testing for `0` values, and whether the /// returned id is valid. /// /// The following can be converted: /// - `Id` and `ecs_id_it` - Self-explanatory. /// - `Entity` and `ecs_entity_t` - Self-explanatory. /// - `Pair` - Converts to the equivalent `Id`. /// - `.{ relation, target }` - A `Pair`, converted using `anyToEntity()`. /// - `type` - Looks up the entity associated with that type. pub fn anyToId(comptime ctx: anytype, value: anytype) c.ecs_id_t { const T = @TypeOf(value); if (comptime std.meta.trait.isTuple(T)) { if (@typeInfo(T).Struct.fields.len != 2) @compileError("Value of type " ++ @typeName(T) ++ " must be a tuple with 2 elements, to be a Pair"); const relation = anyToEntity(ctx, value[0]); const target = anyToEntity(ctx, value[1]); return c.ecs_make_pair(relation, target); } return switch (T) { @TypeOf(null) => 0, c.ecs_id_t => value, Id(ctx) => value.raw, ?Id(ctx) => if (value) |v| v.raw else 0, Pair(ctx) => value.raw, ?Pair(ctx) => if (value) |v| v.raw else 0, // Technically same type as `ecs_id_it`. // c.ecs_entity_t => value, Entity(ctx) => value.raw, ?Entity(ctx) => if (value) |v| v.raw else 0, type => Lookup(ctx, value).id, else => @compileError("Value of type " ++ @typeName(T) ++ " can't be converted to Id"), }; } /// Gets the simplified type name of the specified type. /// That is, without any namespace qualifiers. pub fn simpleTypeName(comptime T: type) [:0]const u8 { const fullName = @typeName(T); const index = std.mem.lastIndexOf(u8, fullName, "."); return if (index) |i| fullName[(i + 1)..] else fullName; }