This repository has been archived by the owner on Feb 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1e56922
commit 8712076
Showing
14 changed files
with
310 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { Ecs } from './Ecs' | ||
import { | ||
ComponentManagerBuilderMap, | ||
ComponentManagerBuilder, | ||
ExtractComponentManagerType | ||
} from '../types/EcsHelpers' | ||
import { GroupComponentManager } from './GroupComponentManager' | ||
|
||
class EcsSafeBuilder<T extends object = {}> { | ||
public constructor(private managers: ComponentManagerBuilderMap<T>) {} | ||
|
||
public addManager<K extends string, L>( | ||
name: K, | ||
manager: ComponentManagerBuilder<L> | ||
) { | ||
return new EcsSafeBuilder<T & Record<K, L>>({ | ||
...this.managers, | ||
[name]: manager | ||
} as any) | ||
} | ||
|
||
public group<K extends string, L extends keyof T>( | ||
name: K, | ||
components: Exclude<L, K>[] | ||
) { | ||
const group = (ecs: Ecs<T>) => | ||
new GroupComponentManager(ecs.capacity, ecs, components) | ||
|
||
return new EcsSafeBuilder< | ||
T & Record<K, ExtractComponentManagerType<ReturnType<typeof group>>> | ||
>({ | ||
...this.managers, | ||
[name]: group | ||
} as any) | ||
} | ||
|
||
public build(capacity = 10000) { | ||
return new Ecs(this.managers, capacity) | ||
} | ||
} | ||
|
||
export class EcsBuilder { | ||
public addManager<K extends string, L>( | ||
name: K, | ||
manager: ComponentManagerBuilder<L> | ||
) { | ||
return new EcsSafeBuilder<Record<K, L>>({ | ||
[name]: manager | ||
} as any) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { Ecs } from './Ecs' | ||
import { ComponentManager } from '../types/ComponentManager' | ||
import { typesafeKeys } from '../helpers/typesafeIterable' | ||
|
||
export class GroupComponentManager<T extends object, K extends keyof T> | ||
implements ComponentManager<Pick<T, K>> { | ||
private eids = new Set<number>() | ||
|
||
public constructor( | ||
public capacity: number, | ||
private ecs: Ecs<T>, | ||
private components: K[] | ||
) {} | ||
|
||
private get managers() { | ||
return this.components.map( | ||
name => [this.ecs.components[name], name] as const | ||
) | ||
} | ||
|
||
public register(eid: number, components: Pick<T, K>) { | ||
for (const [manager, name] of this.managers) { | ||
manager.register(eid, components[name], false) | ||
} | ||
|
||
this.eids.add(eid) | ||
} | ||
|
||
public unregister(eid: number) { | ||
for (const [manager] of this.managers) { | ||
manager.unregister(eid, false) | ||
} | ||
|
||
this.eids.delete(eid) | ||
} | ||
|
||
public getComponentByEid(eid: number) { | ||
if (!this.eids.has(eid)) { | ||
throw new Error(`Cannot find component with eid ${eid}`) | ||
} | ||
|
||
const result = {} as Pick<T, K> | ||
|
||
for (const [manager, name] of this.managers) { | ||
result[name] = manager.getComponentByEid(eid) | ||
} | ||
|
||
return result | ||
} | ||
|
||
public setComponentByEid(eid: number, value: Pick<T, K>) { | ||
if (!this.eids.has(eid)) { | ||
throw new Error(`Cannot find component with eid ${eid}`) | ||
} | ||
|
||
for (const [manager, name] of this.managers) { | ||
manager.setComponentByEid(eid, value[name]) | ||
} | ||
} | ||
|
||
public mutateAll(callback: (v: Pick<T, K>) => Pick<T, K>) { | ||
for (const eid of this.eids) { | ||
const original = this.getComponentByEid(eid) | ||
const changed = callback(original) | ||
|
||
this.setComponentByEid(eid, changed) | ||
} | ||
} | ||
|
||
public *[Symbol.iterator]() { | ||
for (const eid of this.eids) { | ||
yield this.getComponentByEid(eid) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.