#ECS system type modeling

4 messages · Page 1 of 1 (latest)

craggy cedar
#

Hey guys. I am needing something similar to an ECS system as part of an editor I am working on. I have been thinking about modeling components. This is a rough sketch of how I have it so far:

type AnyClass<T extends object = object> = new (...args: never) => T

class Greeter {
    greet(name: string) {return `Hi ${name}!`}
}

class Counter {
    #count: number
    constructor(initial: number) {
        this.#count = initial
    }
    get count() {
        return this.#count
    }
    increment() {
        this.#count++
    }
    decrement() {
        this.#count--
    }
}


class ComponentManager {
    #components: object[]
    constructor() {
        this.#components = []
    }
    add(c: object) {
        this.#components.push(c)
    }
    get<C extends object>(c: AnyClass<C>): C {
        for (const component of this.#components) {
            if (component.constructor === c) {
                return component as C
            }
        }

        throw new Error(`No such component ${c.name}`)
    }
}

const manager = new ComponentManager()
manager.add(new Greeter())
manager.add(new Counter(5))

// Notice I'm able to access typed counter data
const counter = manager.get(Counter)
counter.increment()
console.log(counter.count)

I was wondering if you guys have any thoughts on the type modeling of this. This feels right, but I guess I've never actually used never (pun intended) to do this before so I feel slightly out of my depth

valid gulchBOT
#

@gray ocean Here's a shortened URL of your playground link! You can remove the full link from your message.

kingoberon.#0

Preview:```ts
type AnyClass<T extends object = object> = new (
...args: never
) => T

class Greeter {
greet(name: string) {
return Hi ${name}!
}
}

class Counter {
#count: number
constructor(initial: number) {
this.#count = initi
...```

gray ocean
#

I ran it in node.js but wondered if it's possible to do directly in the ts playground