Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ jobs:
run: pnpm test:unit

- name: "Run linter"
run: pnpm lint
run: pnpm clean && pnpm lint
3 changes: 1 addition & 2 deletions packages/asset-manager/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
"outDir": ".",
"rootDir": ".",
"paths": {
"@nanoforge/common": ["../common"],
"@nanoforge/common/*": ["../common/*"]
"@nanoforge/common": ["../common"]
}
},
"exclude": ["node_modules", "dist", "test/**/*", "*.spec.ts"],
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/application/nanoforge-application.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
ApplicationContext,
type IAssetManagerLibrary,
type IComponentSystemLibrary,
type ILibrary,
type INetworkLibrary,
type IRunOptions,
} from "@nanoforge/common";
import { ApplicationContext } from "@nanoforge/common/src/context/contexts/application.context";

import { Core } from "../core/core";
import { ApplicationConfig } from "./application-config";
Expand Down
3 changes: 1 addition & 2 deletions packages/core/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
"outDir": ".",
"rootDir": ".",
"paths": {
"@nanoforge/common": ["../common"],
"@nanoforge/common/*": ["../common/*"]
"@nanoforge/common": ["../common"]
}
},
"exclude": ["node_modules", "dist", "test/**/*", "*.spec.ts"],
Expand Down
4 changes: 3 additions & 1 deletion packages/ecs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ src/**/*.js
src/**/*.d.ts

# pubilc directory
public/
lib/libecs.wasm
lib/index.d.ts
lib/index.js
compile_commands.json
emsdk/
9 changes: 4 additions & 5 deletions packages/ecs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ SRC = wasm/SparseArray.cpp\

NAME := libecs

OUT_DIR = public
OUT_DIR = lib
JS_NAME = $(OUT_DIR)/$(NAME).js
HTML_NAME = $(OUT_DIR)/$(NAME).html
WASM_NAME = $(OUT_DIR)/$(NAME).wasm
Expand All @@ -23,7 +23,7 @@ OBJ = $(SRC:.cpp=.o)
%.o: %.cpp
$(CC) -c $< -o $@ $(CFLAGS)

all: $(WASM_NAME)
all: $(TS_NAME)

js: $(JS_NAME)

Expand Down Expand Up @@ -52,15 +52,14 @@ $(TS_NAME): $(OBJ)

clean:
$(RM) $(OBJ)
$(RM) -r $(OUT_DIR)
$(RM) $(JS_NAME) $(WASM_NAME) $(HTML_NAME) $(TS_NAME)

fclean: clean

tests: LDFLAGS += -s MODULARIZE=1 -s STANDALONE_WASM=1
tests: LDFLAGS += -s MODULARIZE=1
tests: $(OBJ)
@mkdir -p $(OUT_DIR)
$(CC) $(OBJ) $(LDFLAGS) -o $(JS_NAME)
$(CC) $(OBJ) $(LDFLAGS) --emit-tsd $(TS_NAME) -o $(JS_NAME)

re: fclean all

Expand Down
2 changes: 2 additions & 0 deletions packages/ecs/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./libecs";
export { default as Module } from "./libecs";
128 changes: 128 additions & 0 deletions packages/ecs/lib/libecs.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// TypeScript bindings for emscripten-generated code. Automatically generated at compile time.
declare namespace RuntimeExports {
let HEAPF32: any;
let HEAPF64: any;
let HEAP_DATA_VIEW: any;
let HEAP8: any;
let HEAPU8: any;
let HEAP16: any;
let HEAPU16: any;
let HEAP32: any;
let HEAPU32: any;
let HEAP64: any;
let HEAPU64: any;
}
interface WasmModule {
}

type EmbindString = ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string;
export interface ClassHandle {
isAliasOf(other: ClassHandle): boolean;
delete(): void;
deleteLater(): this;
isDeleted(): boolean;
clone(): this;
}
export interface container extends ClassHandle {
size(): number;
get(_0: number): any | undefined | undefined;
push_back(_0?: any): void;
resize(_0: number, _1?: any): void;
set(_0: number, _1?: any): boolean;
}

export interface SparseArray extends ClassHandle {
setByCopy(_0: SparseArray): SparseArray;
setByMove(_0: SparseArray): SparseArray;
clear(): void;
empty(): boolean;
erase(_0: number): void;
size(): number;
resize(_0: number): void;
getIndex(_0?: any): number;
getConst(_0: number): any | undefined;
get(_0: number): any | undefined;
insertAt(_0: number, _1?: any): any | undefined;
insertAt(_0: number, _1?: any): any | undefined;
set(_0: number, _1?: any): void;
}

export interface Entity extends ClassHandle {
getId(): number;
}

export interface MapStringSparseArray extends ClassHandle {
keys(): VectorString;
size(): number;
get(_0: EmbindString): SparseArray | undefined;
set(_0: EmbindString, _1: SparseArray | null): void;
}

export interface VectorString extends ClassHandle {
size(): number;
get(_0: number): EmbindString | undefined;
push_back(_0: EmbindString): void;
resize(_0: number, _1: EmbindString): void;
set(_0: number, _1: EmbindString): boolean;
}

export interface Zipper extends ClassHandle {
next(): any;
getValue(): any;
}

export interface IndexedZipper extends ClassHandle {
next(): any;
getValue(): any;
}

export interface Registry extends ClassHandle {
spawnEntity(): Entity;
killEntity(_0: Entity): void;
clearEntities(): void;
runSystems(): void;
clearSystems(): void;
entityFromIndex(_0: number): Entity;
removeSystem(_0: number): void;
maxEntities(): number;
registerComponent(_0: any): SparseArray;
getComponentsConst(_0: any): SparseArray;
getComponents(_0: any): SparseArray;
getEntityComponentConst(_0: Entity, _1: any): any | undefined;
getEntityComponent(_0: Entity, _1: any): any | undefined;
addComponent(_0: Entity, _1: any): any | undefined;
removeComponent(_0: Entity, _1: any): void;
addSystem(_0: any): void;
getZipper(_0: any): Zipper;
getIndexedZipper(_0: any): IndexedZipper;
}

interface EmbindModule {
container: {
new(): container;
};
SparseArray: {
new(): SparseArray;
};
Entity: {
new(_0: number): Entity;
};
MapStringSparseArray: {
new(): MapStringSparseArray;
};
VectorString: {
new(): VectorString;
};
Zipper: {
new(_0: MapStringSparseArray): Zipper;
};
IndexedZipper: {
new(_0: MapStringSparseArray): IndexedZipper;
};
Registry: {
new(): Registry;
};
}

export type MainModule = WasmModule & typeof RuntimeExports & EmbindModule;
export default function MainModuleFactory (options?: unknown): Promise<MainModule>;
15 changes: 15 additions & 0 deletions packages/ecs/lib/libecs.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/ecs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"fix": "eslint . --fix && prettier --write .",
"taze": "taze major -w",
"lint-staged": "lint-staged",
"test:unit": "make fclean && make tests -j 16 && jest --config ./jest.config.json"
"test:unit": "make fclean && make tests -j 16 && pnpm clean:script && pnpm build:script && jest --config ./jest.config.json"
},
"dependencies": {
"@nanoforge/common": "workspace:^"
Expand Down
100 changes: 98 additions & 2 deletions packages/ecs/src/ecs-library.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,99 @@
import { type ILibrary } from "@nanoforge/common";
import { type AssetManagerLibrary } from "@nanoforge/asset-manager";
import { BaseComponentSystemLibrary, type InitContext } from "@nanoforge/common";

export class ECSLibrary implements ILibrary {}
import type { Entity, MainModule, Registry, SparseArray, Zipper } from "../lib";
import { Module } from "../lib";

export class ECSLibrary extends BaseComponentSystemLibrary {
private module: MainModule;
private registry: Registry;
private readonly path: string = "libecs.wasm";

get name(): string {
return "ECSLibrary";
}

async init(context: InitContext): Promise<void> {
const wasmFile = await context.libraries
.getAssetManager<AssetManagerLibrary>()
.library.getWasm(this.path);
this.module = await Module({ locateFile: () => wasmFile.path });
this.registry = new this.module.Registry();
}

async run(): Promise<void> {
this.runSystems();
}

clear(): Promise<void> {
return Promise.resolve();
}

addComponent(entity: Entity, component: any): void {
this.registry.addComponent(entity, component);
}

createEntity(): Entity {
return this.registry.spawnEntity();
}

getComponents(component: any): SparseArray {
return this.registry.getComponents(component);
}

removeComponent(entity: Entity, component: any): void {
this.registry.removeComponent(entity, component);
}

getEntityComponent(entity: Entity, component: any): any | undefined {
return this.registry.getEntityComponent(entity, component);
}

getEntityComponentConst(entity: Entity, component: any): any | undefined {
return this.registry.getEntityComponentConst(entity, component);
}

clearEntities(): void {
this.registry.clearEntities();
}

runSystems(): void {
this.registry.runSystems();
}

clearSystems(): void {
this.registry.clearSystems();
}

removeSystem(system: any): void {
this.registry.removeSystem(system);
}

registerComponent(component: any): SparseArray {
return this.registry.registerComponent(component);
}

entityFromIndex(index: number): Entity {
return this.registry.entityFromIndex(index);
}

killEntity(entity: Entity): void {
this.registry.killEntity(entity);
}

maxEntities(): number {
return this.registry.maxEntities();
}

addSystem(system: any): void {
this.registry.addSystem(system);
}

getZipper(types: [any]): Zipper {
return this.registry.getZipper(types);
}

getIndexedZipper(types: [any]): Zipper {
return this.registry.getIndexedZipper(types);
}
}
3 changes: 3 additions & 0 deletions packages/ecs/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import "../lib/libecs.wasm";

export * from "./ecs-library";
59 changes: 59 additions & 0 deletions packages/ecs/test/ecs-library.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { AssetManagerLibrary } from "@nanoforge/asset-manager";
import { ApplicationContext, InitContext } from "@nanoforge/common";
import { EditableLibraryManager } from "@nanoforge/core/src/common/library/manager/library.manager";
import { ECSLibrary } from "@nanoforge/ecs/src/ecs-library";

class Position {
constructor(
public x: number,
public y: number,
) {
this.x = x;
this.y = y;
}
}

describe("ECSLibrary", () => {
let ecs: ECSLibrary;
const assetManager = new AssetManagerLibrary();
const appContext = new ApplicationContext();
const libraryManager = new EditableLibraryManager();
const context = new InitContext(appContext, libraryManager, {
// @ts-ignore
canvas: null,
files: {
assets: new Map(),
wasm: new Map([["/libecs.wasm", "./lib/libecs.wasm"]]),
wgsl: new Map(),
},
});
libraryManager.setAssetManager(assetManager);

beforeAll(async () => {
await assetManager.init(context);
});

beforeEach(async () => {
ecs = new ECSLibrary();
await ecs.init(context);
});

test("init and spawn entity", async () => {
const entity = ecs.createEntity();
expect(entity).toBeDefined();
expect(entity.getId()).toBe(0);
});

test("add component to entity", async () => {
const entity = ecs.createEntity();
const pos = new Position(1, 2);
ecs.addComponent(entity, pos);
const components = ecs.getComponents(Position);
expect(components.get(entity.getId())).toStrictEqual(new Position(1, 2));
expect(components.size()).toBe(1);
});

test("clear", async () => {
await ecs.clear();
});
});
Loading