diff --git a/lib/init.lua b/lib/init.lua index 9ef0b10..ebcfd0e 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -845,14 +845,79 @@ function World.__iter(world: World): () -> (number?, unknown?) end end -return table.freeze({ - World = World, +-- __nominal_type_dont_use could not be any or T as it causes a type error +-- or produces a union +export type Component = T & {__nominal_type_dont_use: never} +export type Entity = Component +export type Relationship = Component +type ctype = Component - OnAdd = ON_ADD, - OnRemove = ON_REMOVE, - OnSet = ON_SET, - Wildcard = WILDCARD, - w = WILDCARD, +export type QueryShim = typeof(setmetatable( + {} :: { + --- Excludes the given selection from the query + without: (QueryShim, U...) -> QueryShim + }, + {} :: { + __iter: (QueryShim) -> () -> (Entity, T...) + } +)) + +export type WorldShim = typeof(setmetatable( + {} :: { + + --- Creates a new entity + entity: (WorldShim) -> Entity, + --- Creates a new entity located in the first 256 ids. + --- These should be used for static components for fast access. + component: (WorldShim) -> Component, + --- Gets the target of an relationship. For example, when a user calls + --- `world:target(id, ChildOf(parent))`, you will obtain the parent entity. + target: (WorldShim, id: Entity, relation: Relationship) -> Entity?, + --- Deletes an entity and all it's related components and relationships. + delete: (WorldShim, id: Entity) -> (), + + --- Adds a component to the entity with no value + add: (WorldShim, id: Entity, component: Component) -> (), + --- Assigns a value to a component on the given entity + set: (WorldShim, id: Entity, component: Component, data: T) -> (), + --- Removes a component from the given entity + remove: (WorldShim, id: Entity, component: Component) -> (), + --- Retrieves the value of up to 4 components. These values may be nil. + get: + ((WorldShim, id: any, ctype) -> A) + & ((WorldShim, id: Entity, ctype, ctype) -> (A, B)) + & ((WorldShim, id: Entity, ctype, ctype, ctype) -> (A, B, C)) + & (WorldShim, id: Entity, ctype, ctype, ctype, ctype) -> (A, B, C, D), + + --- Searches the world for entities that match a given query + query: + ((WorldShim, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype, ctype, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype, ctype, ctype, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype) -> QueryShim) + & ((WorldShim, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ctype, ...ctype) -> QueryShim) + + }, + {} :: { + __iter: (world: WorldShim) -> () -> (number, {[unknown]: unknown?}) + } + +)) + +return table.freeze({ + World = (World :: any) :: {new: () -> WorldShim}, + + OnAdd = (ON_ADD :: any) :: Component, + OnRemove = (ON_REMOVE :: any) :: Component, + OnSet = (ON_SET :: any) :: Component, + Wildcard = (WILDCARD :: any) :: Component, + w = (WILDCARD :: any) :: Component, Rest = REST, IS_PAIR = ECS_IS_PAIR, @@ -863,6 +928,6 @@ return table.freeze({ ECS_PAIR_RELATION = ECS_PAIR_RELATION, ECS_PAIR_OBJECT = ECS_PAIR_OBJECT, - pair = ECS_PAIR, - getAlive = getAlive, + pair = (ECS_PAIR :: any) :: (pred: Entity, obj: Entity) -> Relationship, + getAlive = getAlive })