import type { IResourceController } from "@sammo/game_logic"; import { City } from "@sammo/game_logic/src/City.js"; import type { CityID, GeneralID, NationID, SquadID } from "@sammo/game_logic/src/defs.js"; import type { IGeneralEntity } from "@sammo/game_logic/src/Entity/GeneralEntity.js"; import type { ICityEntity, ValidEntityType } from "@sammo/game_logic/src/Entity/index.js"; import type { INationEntity } from "@sammo/game_logic/src/Entity/NationEntity.js"; import type { ReservedTurn } from "@sammo/game_logic/src/defs.js"; import type { ISquadEntity } from "@sammo/game_logic/src/Entity/SquadEntity.js"; import { GameEnv } from "@sammo/game_logic/src/GameEnv.js"; import { General } from "@sammo/game_logic/src/General.js"; import type { LazyEntityUpdater } from "@sammo/game_logic/src/LazyEntityUpdater.js"; import { Nation } from "@sammo/game_logic/src/Nation.js"; import { Squad } from "@sammo/game_logic/src/Squad.js"; import { insertItemAtArrayLike, must, NotYetImplemented } from "@sammo/util"; import Denque from "denque"; import type { Mongoose } from "mongoose"; import type { IGameEnvEntity } from "@sammo/game_logic/src/Entity/GameEnvEntity.js"; type ChangeType = "insert" | "update" | "delete"; //TODO: Implement! export class ResourceController implements IResourceController { constructor( private readonly db: Mongoose ) { } private _gameEnv: GameEnv = new GameEnv({} as IGameEnvEntity, this); public get gameEnv(): GameEnv { return this._gameEnv; } public readonly nationList: Map = new Map(); public readonly cityList: Map = new Map(); public readonly squadList: Map = new Map(); public readonly generalList: Map = new Map(); //내부적으로 turnTime asc, id asc로 동작하는 PriorityQueue private _generalByTurnTime = new Denque(); private changes = { Nation: new Map(), City: new Map(), Squad: new Map(), General: new Map(), GameEnv: new Map(), } as const satisfies Record]>>; nation(id: NationID): Nation | undefined { return this.nationList.get(id); } city(id: CityID): City | undefined { return this.cityList.get(id); } squad(id: SquadID, nation: NationID): Squad | undefined { const squad = this.squadList.get(id); if (!squad) { return undefined; } if (squad.raw.nationID !== nation) { return undefined; } return squad; } general(id: GeneralID): General | undefined { return this.generalList.get(id); } peekGeneralTurnTimeQueue(): General | undefined { return this._generalByTurnTime.peekFront(); } popGeneralTurnTimeQueue(): General | undefined { return this._generalByTurnTime.shift(); } insertGeneralTurnTimeQueue(general: General, maybeTail: boolean): void { insertItemAtArrayLike(this._generalByTurnTime, general, (a, b) => a.compareTurnTime(b), maybeTail); } allNations(): Map { throw new NotYetImplemented(); } allCities(): Map { throw new NotYetImplemented(); } allCitiesByNation(): Map> { throw new NotYetImplemented(); } allSquads(): Map> { throw new NotYetImplemented(); } allGenerals(): Map { throw new NotYetImplemented(); } generalByNation(id: NationID): Map { throw new NotYetImplemented(); } generalByCity(id: CityID, nationID?: NationID): Map { throw new NotYetImplemented(); } generalBySquad(id: SquadID): Map { throw new NotYetImplemented(); } cityByNation(id: NationID): Map { throw new NotYetImplemented(); } squadByNation(id: NationID): Map { throw new NotYetImplemented(); } //----Insert, Update, Delete reserveUpdate(entity: LazyEntityUpdater): void { throw new NotYetImplemented(); } reserveDelete(entity: LazyEntityUpdater): void { throw new NotYetImplemented(); } reserveInsert(entity: LazyEntityUpdater): void { throw new NotYetImplemented(); } createGeneral(raw: IGeneralEntity): General { throw new NotYetImplemented(); } createNation(raw: INationEntity): Nation { throw new NotYetImplemented(); } createSquad(raw: ISquadEntity): Squad { throw new NotYetImplemented(); } _getAllChanges(): Record]>> { return this.changes; } //---- DB 접근 --- getReservedTurn(general: General): Promise { throw new NotYetImplemented(); } nationReservedTurn(general: General): Promise { throw new NotYetImplemented(); } resetAndFill(): Promise { this.nationList.clear(); this.cityList.clear(); this.squadList.clear(); this.generalList.clear(); //MongoDB로부터 데이터를 가져와서 채워넣는다. const rawGameEnv = {} as IGameEnvEntity; //TODO: Implement! const rawNationList = new Map(); const rawCityList = new Map(); const rawSquadList = new Map(); const rawGeneralList = new Map(); const generalIDByNation = new Map(); const generalIDByCity = new Map(); const generalIDListBySquad = new Map(); for (const rawSquad of rawSquadList.values()) { generalIDListBySquad.set(rawSquad.id, []); } for (const rawGeneral of rawGeneralList.values()) { if (rawGeneral.squadID) { let list = generalIDListBySquad.get(rawGeneral.squadID); if (!list) { list = []; generalIDListBySquad.set(rawGeneral.squadID, list); } list.push(rawGeneral.id); } { let list = generalIDByNation.get(rawGeneral.nationID); if (!list) { list = []; generalIDByNation.set(rawGeneral.nationID, list); } list.push(rawGeneral.id); } { let list = generalIDByCity.get(rawGeneral.cityID); if (!list) { list = []; generalIDByCity.set(rawGeneral.cityID, list); } list.push(rawGeneral.id); } } const cityIDByNation = new Map(); for (const rawCity of rawCityList.values()) { const list = must(cityIDByNation.get(rawCity.nationID)); list.push(rawCity.id); } const squadIDByNation = new Map(); for (const rawSquad of rawSquadList.values()) { const list = must(squadIDByNation.get(rawSquad.nationID)); list.push(rawSquad.id); } this._gameEnv = new GameEnv(rawGameEnv, this); this._gameEnv.bootstrap(); for (const rawNation of rawNationList.values()) { const nation = new Nation(rawNation, this, { general: must(generalIDByNation.get(rawNation.id)), squad: squadIDByNation.get(rawNation.id) ?? [], city: cityIDByNation.get(rawNation.id) ?? [], } ); this.nationList.set(nation.id, nation); } for (const rawCity of rawCityList.values()) { const city = new City(rawCity, this, { general: generalIDByCity.get(rawCity.id) ?? [] }); this.cityList.set(city.id, city); } for (const rawSquad of rawSquadList.values()) { const squad = new Squad(rawSquad, this, { general: generalIDListBySquad.get(rawSquad.id) ?? [] }); this.squadList.set(squad.id, squad); } for (const rawGeneral of rawGeneralList.values()) { const general = new General(rawGeneral, this); this.generalList.set(general.id, general); } //lazyInit()을 호출한다. this.nationList.forEach(nation => nation.bootstrap()); this.cityList.forEach(city => city.bootstrap()); this.squadList.forEach(squad => squad.bootstrap()); //iAction때문에 general의 lazyInit이 가장 마지막 this.generalList.forEach(general => general.bootstrap()); //턴순서 정렬! const generalList = Array.from(this.generalList.values()); generalList.sort((a, b) => a.compareTurnTime(b)); this._generalByTurnTime = new Denque(generalList); throw new NotYetImplemented(); } saveAll(): Promise { throw new NotYetImplemented(); } }