2023-05-29 22:03:29 +00:00
|
|
|
import { Behaviour, Entity, EntityOf } from "./entity";
|
|
|
|
import { forEachReverse } from "./helpers";
|
2023-05-27 13:03:29 +00:00
|
|
|
import { resourceUnloadAll } from "./resource";
|
|
|
|
|
2023-05-27 09:35:08 +00:00
|
|
|
const promiseUpdateList: (()=>boolean)[] = []
|
2023-05-29 22:03:29 +00:00
|
|
|
const entitiyList: Entity[] = []
|
2023-05-27 13:03:29 +00:00
|
|
|
|
2023-05-20 19:34:27 +00:00
|
|
|
|
2023-05-27 09:35:08 +00:00
|
|
|
const dispatchPromises = () => {
|
|
|
|
for (var i = promiseUpdateList.length - 1; i >= 0; i--) {
|
|
|
|
const finished = promiseUpdateList[i]()
|
|
|
|
if (finished) {
|
|
|
|
promiseUpdateList.splice(i, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export const makeUpdateablePromise = (updateFn: () => boolean) => {
|
|
|
|
let resFn: () => void
|
2023-05-29 22:03:29 +00:00
|
|
|
let rejFn: (reason: any) => void
|
2023-05-27 09:35:08 +00:00
|
|
|
const promise = new Promise<void>((resolve, reject) => {
|
|
|
|
resFn = resolve
|
2023-05-29 22:03:29 +00:00
|
|
|
rejFn = reject
|
2023-05-27 09:35:08 +00:00
|
|
|
});
|
|
|
|
const update = () => {
|
2023-05-29 22:03:29 +00:00
|
|
|
try {
|
|
|
|
const res = updateFn()
|
|
|
|
if(res) resFn()
|
|
|
|
return res
|
|
|
|
} catch(e: any){
|
|
|
|
traceLog(LOG_INFO, "ERROR!")
|
|
|
|
rejFn(e)
|
|
|
|
return true
|
|
|
|
}
|
2023-05-27 09:35:08 +00:00
|
|
|
}
|
|
|
|
promiseUpdateList.unshift(update)
|
|
|
|
return promise
|
|
|
|
}
|
|
|
|
|
2023-05-29 22:03:29 +00:00
|
|
|
export const entityAdd = (entity: Entity) => {
|
|
|
|
entity.behaviours.forEach(b => b.load ? b.load(entity) : undefined)
|
2023-05-27 13:03:29 +00:00
|
|
|
entitiyList.push(entity)
|
2023-05-29 22:03:29 +00:00
|
|
|
traceLog(LOG_INFO, `GAME: [ID ${entity.id}] loaded entity`)
|
|
|
|
}
|
|
|
|
|
|
|
|
export const entityUnload = (entity: Entity) => {
|
|
|
|
forEachReverse(entity.behaviours, (b, i) => b.unload ? b.unload(entity) : undefined);
|
|
|
|
traceLog(LOG_INFO, `GAME: [ID ${entity.id}] unloaded entity`)
|
2023-05-27 13:03:29 +00:00
|
|
|
}
|
2023-05-27 09:35:08 +00:00
|
|
|
|
2023-05-29 22:03:29 +00:00
|
|
|
export const entityRemove = (entity: Entity) => {
|
2023-05-27 13:03:29 +00:00
|
|
|
// TODO: Do this cached
|
|
|
|
const i = entitiyList.findIndex(x => x.id === entity.id)
|
|
|
|
if (i !== -1) {
|
2023-05-29 22:03:29 +00:00
|
|
|
entityUnload(entity)
|
2023-05-27 13:03:29 +00:00
|
|
|
entitiyList.splice(i, 1)
|
2023-05-20 19:34:27 +00:00
|
|
|
}
|
2023-05-27 13:03:29 +00:00
|
|
|
}
|
2023-05-20 19:34:27 +00:00
|
|
|
|
2023-05-29 22:03:29 +00:00
|
|
|
export const runGame = (width: number, height: number, title: string, startupCallback: (quit: () => void) => void | Promise<void>) => {
|
2023-05-27 13:03:29 +00:00
|
|
|
initWindow(width, height, title)
|
|
|
|
setTargetFPS(60)
|
2023-05-29 22:03:29 +00:00
|
|
|
let quit = false
|
|
|
|
let exception: any = null
|
|
|
|
const p = startupCallback(() => quit = true)
|
|
|
|
if(p) p.catch(e => { exception = e })
|
2023-05-27 13:03:29 +00:00
|
|
|
while(!windowShouldClose()){
|
|
|
|
dispatchPromises()
|
2023-05-29 22:03:29 +00:00
|
|
|
if(exception) throw exception
|
|
|
|
entitiyList.forEach(e => e.behaviours.forEach(b => b.update ? b.update(e) : undefined))
|
2023-05-27 13:03:29 +00:00
|
|
|
beginDrawing()
|
|
|
|
clearBackground(BLACK)
|
2023-05-29 22:03:29 +00:00
|
|
|
drawText("Active promises: "+ promiseUpdateList.length, 10,10, 8, RAYWHITE)
|
|
|
|
entitiyList.forEach(e => e.behaviours.forEach(b => b.draw ? b.draw(e) : undefined))
|
2023-05-27 13:03:29 +00:00
|
|
|
endDrawing()
|
2023-05-20 19:34:27 +00:00
|
|
|
}
|
2023-05-29 22:03:29 +00:00
|
|
|
entitiyList.forEach(x => entityUnload(x))
|
|
|
|
entitiyList.splice(0,entitiyList.length)
|
2023-05-27 13:03:29 +00:00
|
|
|
resourceUnloadAll()
|
|
|
|
closeWindow()
|
2023-05-20 19:34:27 +00:00
|
|
|
}
|