mreinstein / ecs

data oriented, functional entity component system
MIT License
86 stars 8 forks source link

Add typescript definitions #34

Closed kozak-codes closed 2 years ago

kozak-codes commented 2 years ago

Closes #33

Adds typescript definitions as js docs

Types work in the following way:

import { default as ECS, SystemFunction, SystemUpdateFunction } from 'ecs';
const world = ECS.createWorld();

const PLAYER = ECS.createEntity(world);
ECS.addComponentToEntity(world, PLAYER, 'position', { x: 15, y: 23 })
ECS.addComponentToEntity(world, PLAYER, 'moveable', { dx: 0, dy: 0 });

const movementSystem: SystemFunction = function (world) {
    const onUpdate: SystemUpdateFunction = function (dt) {
        for (const entity of ECS.getEntities(world, ['position', 'moveable'])) {
            entity.position.x += entity.moveable.dx
            entity.position.y += entity.moveable.dy
        }
    }

    return { onUpdate }
}

ECS.addSystem(world, movementSystem);

let currentTime = performance.now();

function gameLoop() {
    const newTime = performance.now()
    const frameTime = newTime - currentTime  // in milliseconds, e.g. 16.64356
    currentTime = newTime

    // run onUpdate for all added systems
    ECS.update(world, frameTime)

    // necessary cleanup step at the end of each frame loop
    ECS.cleanup(world)

    requestAnimationFrame(gameLoop);
}

// finally start the game loop
gameLoop();

I'm not sure how you want to do versioning or if you want to update the docs in any way.

I also think it would be a good idea to export each function individually as well as a default export. That way you can get nicer type completion. eg import { addComponentToEntity } from 'ecs' - I added it to this PR because it enhances the typescript experience, let me know if you want me to remove it.

mreinstein commented 2 years ago

Thanks for the PR!

Mostly looks good, but I'm wondering why you switched to named exports?

kozak-codes commented 2 years ago

Thanks! Mainly to give the user some flexibility and allow the user to decide if they would like to use default exports or named exports. When writing with typescript it is very helpful to simply write addSystem and allow your IDE to import addSystem from ECS; I find VSCode usually has a hard time finding default exports.

Otherwise with typescript and ESM you would have to do: import { default as ECS } from 'ecs' at the top of every file. IMO named exports offer a bit more consistency. See this stack overflow answer. I can revert it if you think it is out of scope, but the default export should still work in all other contexts.

mreinstein commented 2 years ago

I can revert it if you think it is out of scope

No, I don't have that strong of an opinion about it. Though I will say this is one of several reasons why I'm not a huge fan of typescript. That said I know it's quite en vogue at the moment, so that's fine. :)

If you can make a few more tweaks, I'll merge:

thanks again!

mreinstein commented 2 years ago

oh, also please make sure all the existing tests still pass with these changes :)

kozak-codes commented 2 years ago

Changed version and updated readme, tests ok!