From 337f38809361fd67fb6edd4c5656b35588d4a0a9 Mon Sep 17 00:00:00 2001 From: Ukendio Date: Sat, 3 Aug 2024 22:22:36 +0200 Subject: [PATCH 1/3] Fix ts types --- src/index.d.ts | 253 +++++++++++++++++++++++++------------------------ 1 file changed, 127 insertions(+), 126 deletions(-) diff --git a/src/index.d.ts b/src/index.d.ts index 6a42670..19c5ed7 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,155 +1,156 @@ type Query = { - /** - * this: Query is necessary to use a colon instead of a period for emits. - */ - - /** - * Modifies the Query to exclude specified components - * @param components The components to exclude - * @returns Modified Query - */ - without: (this: Query, ...components: Entity[]) => Query; - /** - * Modifies component data with a callback function - * @param fn The function to modify data - */ - replace: (this: Query, fn: (...components: T) => T extends [infer U] ? U : LuaTuple) => void; + /** + * this: Query is necessary to use a colon instead of a period for emits. + */ + drain: (this: Query) => Query + with: (this: Query, ...components: Entity[]) => Query + /** + * Modifies the Query to exclude specified components + * @param components The components to exclude + * @returns Modified Query + */ + without: (this: Query, ...components: Entity[]) => Query; + /** + * Modifies component data with a callback function + * @param fn The function to modify data + */ + replace: (this: Query, fn: (...components: T) => T extends [infer U] ? U : LuaTuple) => void; } & IterableFunction>; // Utility Types export type Entity = number & { __nominal_type_dont_use: T }; export type EntityType = T extends Entity ? A : never; export type InferComponents = { - [K in keyof A]: EntityType; + [K in keyof A]: EntityType; }; type Nullable = { - [K in keyof T]: T[K] | undefined; + [K in keyof T]: T[K] | undefined; }; export class World { - /** - * Creates a new World - */ - constructor(); + /** + * Creates a new World + */ + constructor(); - /** - * Creates a new entity - * @returns Entity - */ - entity(): Entity; + /** + * Creates a new entity + * @returns Entity + */ + entity(): Entity; - /** - * Creates a new entity located in the first 256 ids. - * These should be used for static components for fast access. - * @returns Entity - */ - component(): Entity; + /** + * Creates a new entity located in the first 256 ids. + * These should be used for static components for fast access. + * @returns Entity + */ + component(): Entity; - /** - * Gets the target of a relationship. For example, when a user calls - * `world.target(id, ChildOf(parent))`, you will obtain the parent entity. - * @param id Entity - * @param relation The Relationship - * @returns The Parent Entity if it exists - */ - target(id: Entity, relation: Entity): Entity | undefined; + /** + * Gets the target of a relationship. For example, when a user calls + * `world.target(id, ChildOf(parent))`, you will obtain the parent entity. + * @param id Entity + * @param relation The Relationship + * @returns The Parent Entity if it exists + */ + target(id: Entity, relation: Entity): Entity | undefined; - /** - * Clears an entity from the world. - * @praram id Entity to be cleared - */ - clear(id: Entity): void; + /** + * Clears an entity from the world. + * @praram id Entity to be cleared + */ + clear(id: Entity): void; - /** - * Deletes an entity and all its related components and relationships. - * @param id Entity to be destroyed - */ - delete(id: Entity): void; + /** + * Deletes an entity and all its related components and relationships. + * @param id Entity to be destroyed + */ + delete(id: Entity): void; - /** - * Adds a component to the entity with no value - * @param id Target Entity - * @param component Component - */ - add(id: Entity, component: Entity): void; + /** + * Adds a component to the entity with no value + * @param id Target Entity + * @param component Component + */ + add(id: Entity, component: Entity): void; - /** - * Assigns a value to a component on the given entity - * @param id Target Entity - * @param component Target Component - * @param data Component Data - */ - set(id: Entity, component: Entity, data: T): void; + /** + * Assigns a value to a component on the given entity + * @param id Target Entity + * @param component Target Component + * @param data Component Data + */ + set(id: Entity, component: Entity, data: T): void; - /** - * Removes a component from the given entity - * @param id Target Entity - * @param component Target Component - */ - remove(id: Entity, component: Entity): void; + /** + * Removes a component from the given entity + * @param id Target Entity + * @param component Target Component + */ + remove(id: Entity, component: Entity): void; - // Manually typed out get since there is a hard limit. + // Manually typed out get since there is a hard limit. - /** - * Retrieves the value of one component. This value may be undefined. - * @param id Target Entity - * @param component Target Component - * @returns Data associated with the component if it exists - */ - get(id: number, component: Entity): A | undefined; + /** + * Retrieves the value of one component. This value may be undefined. + * @param id Target Entity + * @param component Target Component + * @returns Data associated with the component if it exists + */ + get(id: number, component: Entity): A | undefined; - /** - * Retrieves the value of two components. This value may be undefined. - * @param id Target Entity - * @param component Target Component 1 - * @param component2 Target Component 2 - * @returns Data associated with the components if it exists - */ - get( - id: number, - component: Entity, - component2: Entity - ): LuaTuple>; + /** + * Retrieves the value of two components. This value may be undefined. + * @param id Target Entity + * @param component Target Component 1 + * @param component2 Target Component 2 + * @returns Data associated with the components if it exists + */ + get( + id: number, + component: Entity, + component2: Entity + ): LuaTuple>; - /** - * Retrieves the value of three components. This value may be undefined. - * @param id Target Entity - * @param component Target Component 1 - * @param component2 Target Component 2 - * @param component3 Target Component 3 - * @returns Data associated with the components if it exists - */ - get( - id: number, - component: Entity, - component2: Entity, - component3: Entity - ): LuaTuple>; + /** + * Retrieves the value of three components. This value may be undefined. + * @param id Target Entity + * @param component Target Component 1 + * @param component2 Target Component 2 + * @param component3 Target Component 3 + * @returns Data associated with the components if it exists + */ + get( + id: number, + component: Entity, + component2: Entity, + component3: Entity + ): LuaTuple>; - /** - * Retrieves the value of four components. This value may be undefined. - * @param id Target Entity - * @param component Target Component 1 - * @param component2 Target Component 2 - * @param component3 Target Component 3 - * @param component4 Target Component 4 - * @returns Data associated with the components if it exists - */ - get( - id: number, - component: Entity, - component2: Entity, - component3: Entity, - component4: Entity - ): LuaTuple>; + /** + * Retrieves the value of four components. This value may be undefined. + * @param id Target Entity + * @param component Target Component 1 + * @param component2 Target Component 2 + * @param component3 Target Component 3 + * @param component4 Target Component 4 + * @returns Data associated with the components if it exists + */ + get( + id: number, + component: Entity, + component2: Entity, + component3: Entity, + component4: Entity + ): LuaTuple>; - /** - * Searches the world for entities that match a given query - * @param components Queried Components - * @returns Query - */ - query(...components: T): Query>; + /** + * Searches the world for entities that match a given query + * @param components Queried Components + * @returns Query + */ + query(...components: T): Query>; } /** @@ -176,4 +177,4 @@ export const OnAdd: Entity; export const OnRemove: Entity; export const OnSet: Entity; export const Wildcard: Entity; -export const Rest: Entity; \ No newline at end of file +export const Rest: Entity; From 843f8c1914c78c758db381995d037170f6dd67ee Mon Sep 17 00:00:00 2001 From: Ukendio Date: Sat, 3 Aug 2024 22:39:45 +0200 Subject: [PATCH 2/3] Fix luau types --- src/init.luau | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/init.luau b/src/init.luau index c7cccdd..d9d4986 100644 --- a/src/init.luau +++ b/src/init.luau @@ -16,7 +16,6 @@ type ArchetypeEdge = { remove: Archetype, } - type Archetype = { id: number, edges: { [i53]: ArchetypeEdge }, @@ -723,7 +722,6 @@ local Arm = function(self: Query, ...) end local world_query do - local EmptyQuery: Query = { __iter = function(): Item return noop @@ -1214,9 +1212,10 @@ export type Entity = number & { __DO_NOT_USE_OR_YOU_WILL_BE_FIRED: T } export type Pair = number export type QueryShim = typeof(setmetatable({ - without = function(...): QueryShim - return nil :: any - end, + without = noop :: (QueryShim, ...i53) -> QueryShim, + with = noop :: (QueryShim, ...i53) -> QueryShim, + drain = noop :: (QueryShim) -> QueryShim, + replace = noop :: (QueryShim, fn: (T...) -> T...) -> (), }, { __iter = function(): () -> (number, T...) return nil :: any From ec9d58fe5d36e7896cb4e2e98fd5f780190c38ce Mon Sep 17 00:00:00 2001 From: Ukendio Date: Sun, 4 Aug 2024 23:07:32 +0200 Subject: [PATCH 3/3] Add archetypes to EmptyQuery --- src/init.luau | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/init.luau b/src/init.luau index d9d4986..eac3ef6 100644 --- a/src/init.luau +++ b/src/init.luau @@ -36,7 +36,7 @@ type EntityIndex = { dense: { [i24]: i53 }, sparse: { [i53]: Record } } type ArchetypeRecord = { count: number, - column: number + column: number, } type ArchetypeMap = { @@ -722,6 +722,7 @@ local Arm = function(self: Query, ...) end local world_query do + local empty_list = {} local EmptyQuery: Query = { __iter = function(): Item return noop @@ -731,6 +732,9 @@ do replace = noop :: (Query, ...any) -> (), with = Arm, without = Arm, + archetypes = function() + return empty_list + end } setmetatable(EmptyQuery, EmptyQuery) @@ -994,7 +998,7 @@ do local function query_init(query) if init and drain then - return + return true end init = true @@ -1061,18 +1065,19 @@ do end local function world_query_without(query, ...) - local withoutComponents = { ... } + local N = select("#", ...) for i = #compatible_archetypes, 1, -1 do local archetype = compatible_archetypes[i] - local records = archetype.records + local tr = archetype.records local shouldRemove = false - for _, componentId in withoutComponents do - if records[componentId] then - shouldRemove = true - break - end - end + for j = 1, N do + local id = select(i, ...) + if tr[id] then + shouldRemove = true + break + end + end if shouldRemove then local last = #compatible_archetypes @@ -1135,18 +1140,19 @@ do end local function world_query_with(query, ...) - local with = { ... } + local N = select("#", ...) for i = #compatible_archetypes, 1, -1 do local archetype = compatible_archetypes[i] local tr = archetype.records local shouldRemove = false - for _, id in with do - if not tr[id] then + for j = 1, N do + local id = select(i, ...) + if not tr[id] then shouldRemove = true break end - end + end if shouldRemove then local last = #compatible_archetypes