Add lookups for (some) builtin Flecs types

main
copygirl 2 months ago
parent e728e47136
commit d9882bf86e
  1. 158
      src/builtin/flecs.core.zig
  2. 13
      src/builtin/flecs.doc.zig
  3. 19
      src/builtin/flecs.pipeline.zig
  4. 4
      src/builtin/flecs.system.zig
  5. 6
      src/builtin/flecs.zig
  6. 66
      src/context.zig
  7. 3
      src/main.zig
  8. 10
      src/meta.zig
  9. 3
      src/world.zig

@ -0,0 +1,158 @@
//! Module with Flecs builtin components.
const c = @import("../c.zig");
/// Entity associated with world.
pub const World = struct {};
// Builtin components
/// Component that is added to entities which are components.
pub const Component: type = c.EcsComponent;
/// Component used for entity names, symbols, etc.
pub const Identifier: type = c.EcsIdentifier;
/// Used as `.{ Identifier, Name }` to store entity name.
pub const Name = struct {};
/// Used as `.{ Identifier, Symbol }` to store entity symbol.
pub const Symbol = struct {};
/// Used as `.{ Identifier, Alias }` to store entity alias.
pub const Alias = struct {};
/// Internal component to make (query) entities iterable.
pub const Iterable: type = c.EcsIterable;
/// Internal component that stores pointer to poly objects.
pub const Poly: type = c.EcsPoly;
// Builtin tags
/// Tag that is added to modules, which act as a container for logically
/// grouping tags, components, systems, other sub-modules and more.
pub const Module = struct {};
/// Tag that is added to prefabsm, which can be inherited from, and are ignored by queries (by default).
pub const Prefab = struct {};
/// Tag that added to disabled entities, which are ignored by queries (by default).
pub const Disabled = struct {};
/// Tag that is added to private components, which hides them in the explorer (by default).
pub const Private = struct {};
/// Tag that is added to query entities.
pub const Query = struct {};
/// Tag that is added to observer entities, which listen for events involving entities.
pub const Observer = struct {};
/// Internal tag for tracking IDs with special ID flags.
pub const Flag = struct {};
// Builtin relationships
/// Relationship used for expressing inheritance.
pub const IsA = struct {};
/// Relationship used for expressing hierarchies.
pub const ChildOf = struct {};
/// Relationship used for expressing dependencies.
pub const DependsOn = struct {};
/// Relationship used for expressing prefab slots.
pub const SlotOf = struct {};
// Relationship properties
/// Trait that enables transitive evaluation of relationships.
pub const Transitive = struct {};
/// Trait that enables reflexive evaluation of relationships.
pub const Reflexive = struct {};
/// Trait that indicates an entity cannot be inherited from.
pub const Final = struct {};
/// Trait that indicates it should not be inherited.
pub const DontInherit = struct {};
/// Trait that ensures a pair cannot contain a value.
pub const Tag = struct {};
/// Trait that indicates a relationship is acyclic.
pub const Acyclic = struct {};
/// Trait that indicates a relationship is traversable.
pub const Traversable = struct {};
/// Trait that ensures a relationship can only have one target.
pub const Exclusive = struct {};
/// Trait that causes a relationship to be two-way.
pub const Symmetric = struct {};
/// Trait for adding additional components when a component is added.
pub const With = struct {};
/// Trait that indicates a component should always be overridden.
pub const AlwaysOverride = struct {};
/// Trait for creating a non-fragmenting relationship.
pub const Union = struct {};
/// Trait that enforces target of relationship is a child of <specified>.
pub const OneOf = struct {};
// Builtin event tags
/// Event emitted when component is added.
pub const OnAdd = struct {};
/// Event emitted when component is removed.
pub const OnRemove = struct {};
/// Event emitted when component is set.
pub const OnSet = struct {};
/// Event emitted when component is unset.
pub const UnSet = struct {};
/// Event emitted when table is created.
pub const OnTableCreate = struct {};
/// Event emitted when table becomes empty.
pub const OnTableDelete = struct {};
/// Event emitted when table becomes empty.
pub const OnTableEmpty = struct {};
/// Event emitted when table becomes non-empty.
pub const OnTableFilled = struct {};
// Cleanup policies
// For example, components have `.{ OnDelete, Panic }` by default.
/// Cleanup trait for specifying what happens when component is deleted.
pub const OnDelete = struct {};
/// Cleanup trait for specifying what happens when pair target is deleted.
pub const OnDeleteTarget = struct {};
/// Cleanup action to delete entity from other entities. (default)
pub const Remove = struct {};
/// Cleanup action to delete all entities that have this entity.
pub const Delete = struct {};
/// Cleanup action to panic when entity is deleted.
pub const Panic = struct {};
// Query markers
/// Query marker to express `$this` variable.
pub const This = struct {};
pub const _This_Name = "$";
/// Query marker to express match all wildcard (`*` in query DSL).
pub const Wildcard = struct {};
pub const _Wildcard_Name = "*";
/// Query marker to express match at least one wildcard (`_` in query DSL).
pub const Any = struct {};
pub const _Any_Name = "_";
/// Query marker to express `==` operator.
pub const PredEq = struct {};
/// Query marker to express `~=` operator.
pub const PredMatch = struct {};
/// Query marker to express by-name lookup.
pub const PredLookup = struct {};
/// Query marker to express scope open.
pub const ScopeOpen = struct {};
/// Query marker to express scope close.
pub const ScopeClose = struct {};
/// Tag used to indicate a query has no results.
pub const Empty = struct {};
// Misc
/// Internal component that stores information for flattened trees.
pub const Target: type = c.EcsTarget;
/// Tag that when added to assembly automatically flattens tree.
pub const Flatten = struct {};
/// Sets default component hint for children of entity.
pub const DefaultChildComponent = struct {};

@ -0,0 +1,13 @@
//! Flecs module with documentation components.
const c = @import("../c.zig");
/// Component used to add documentation.
pub const Description = c.EcsDocDescription;
/// Used as `.{ Description, Brief }` to add a brief description.
pub const Brief = struct {};
/// Used as `.{ Description, Detail }` to add a detailed description.
pub const Detail = struct {};
/// Used as `.{ Description, Link }` to add a link.
pub const Link = struct {};

@ -0,0 +1,19 @@
//! Module that schedules and runs systems.
pub const Pipeline = struct {};
pub const Phase = struct {};
// Builtin pipeline phases
// See also "Selecting a Phase" in the Flecs docs.
pub const OnStart = struct {};
pub const PreFrame = struct {};
pub const OnLoad = struct {};
pub const PostLoad = struct {};
pub const PreUpdate = struct {};
pub const OnUpdate = struct {};
pub const OnValidate = struct {};
pub const PostUpdate = struct {};
pub const PreStore = struct {};
pub const OnStore = struct {};
pub const PostFrame = struct {};

@ -0,0 +1,4 @@
//! Module that implements Flecs systems.
pub const System = struct {};
pub const TickSource = struct {};

@ -0,0 +1,6 @@
//! Flecs root module.
pub const core = @import("./flecs.core.zig");
pub const doc = @import("./flecs.doc.zig");
pub const pipeline = @import("./flecs.pipeline.zig");
pub const system = @import("./flecs.system.zig");

@ -1,3 +1,5 @@
const std = @import("std");
const c = @import("./c.zig");
const meta = @import("./meta.zig");
@ -84,5 +86,69 @@ pub fn Context(comptime ctx: anytype) type {
else => @compileError("Value of type " ++ @typeName(T) ++ " can't be converted to Id"),
};
}
/// Registers type lookups for the builtin Flecs entities.
/// These are defined in the `./src/builtin/` directory.
pub fn registerFlecsLookups(world: *World) !void {
const error_writer = std.io.getStdErr().writer();
const flecs = @import("./builtin/flecs.zig");
const root = try lookupAndRegister(world, null, "flecs", flecs, error_writer);
try lookupAndRegisterDeclarations(world, root, flecs, error_writer);
}
pub fn registerFlecsCoreLookups(world: *World) !void {
const error_writer = std.io.getStdErr().writer();
const flecs = @import("./builtin/flecs.zig");
const flecs_core = @import("./builtin/flecs.core.zig");
const root = try lookupAndRegister(world, null, "flecs", flecs, error_writer);
const core = try lookupAndRegister(world, root, "core", flecs_core, error_writer);
try lookupAndRegisterDeclarations(world, core, flecs_core, error_writer);
}
fn lookupAndRegister(
world: *World,
parent: ?Entity,
comptime name: []const u8,
comptime T: type,
error_writer: anytype,
) !Entity {
if (world.lookupChild(parent, name)) |entity| {
const id_ptr = lookupMut(T);
if (id_ptr.* != 0 and id_ptr.* != entity.raw) {
if (!meta.isNull(error_writer))
try std.fmt.format(error_writer, "Trying to register lookup for entity '{any}' as {d}, but it's already registered as {d}", .{ entity, entity.raw, id_ptr.* });
return error.LookupIdMismatch;
}
id_ptr.* = entity.raw;
return entity;
} else {
if (!meta.isNull(error_writer)) {
if (parent) |p|
try std.fmt.format(error_writer, "Could not find child '{s}' of parent '{any}'", .{ name, p })
else
try std.fmt.format(error_writer, "Could not find root entity '{s}'", .{name});
}
return error.EntityNotFound;
}
}
fn lookupAndRegisterDeclarations(
world: *World,
parent: Entity,
comptime T: type,
error_writer: anytype,
) !void {
inline for (@typeInfo(T).Struct.decls) |decl| {
const ChildType = @field(T, decl.name);
if (@TypeOf(ChildType) != type) continue;
comptime var child_name = decl.name;
if (@hasDecl(T, "_" ++ decl.name ++ "_Name"))
child_name = @field(T, "_" ++ decl.name ++ "_Name");
const child = try lookupAndRegister(world, parent, child_name, ChildType, error_writer);
try lookupAndRegisterDeclarations(world, child, ChildType, error_writer);
}
}
};
}

@ -6,6 +6,9 @@ const Allocator = std.mem.Allocator;
pub const errors = @import("./errors.zig");
pub const c = @import("./c.zig");
// Allows access to types built into Flecs, useful for type lookups.
pub const flecs = @import("./builtin/flecs.zig");
pub const FlecsError = errors.FlecsError;
pub const Path = @import("./path.zig");

@ -3,6 +3,16 @@
const std = @import("std");
/// Returns if the provided value is either a `null`
/// constant or an optional type with a `null` value.
pub fn isNull(value: anytype) bool {
return switch (@typeInfo(@TypeOf(value))) {
.Null => true,
.Optional => value == null,
else => false,
};
}
/// Returns if the provided type is a tuple.
pub fn isTuple(comptime T: type) bool {
return @typeInfo(T) == .Struct and @typeInfo(T).Struct.is_tuple;

@ -21,6 +21,7 @@ pub fn World(comptime ctx: anytype) type {
std.debug.assert(flecszigble.is_initialized);
var result = try flecszigble.allocator.create(Self);
result.raw = c.ecs_init().?;
try Context.registerFlecsLookups(result);
return result;
}
@ -28,6 +29,7 @@ pub fn World(comptime ctx: anytype) type {
std.debug.assert(flecszigble.is_initialized);
var result = try flecszigble.allocator.create(Self);
result.raw = c.ecs_init_w_args(args.len, args.ptr).?;
try Context.registerFlecsLookups(result);
return result;
}
@ -35,6 +37,7 @@ pub fn World(comptime ctx: anytype) type {
std.debug.assert(flecszigble.is_initialized);
var result = try flecszigble.allocator.create(Self);
result.raw = c.ecs_mini().?;
try Context.registerFlecsCoreLookups(result);
return result;
}

Loading…
Cancel
Save