feat: LazyEntityUpdater
This commit is contained in:
@@ -1,8 +1,22 @@
|
||||
import type { ICityEntity } from "./CityEntity.js";
|
||||
import { LazyEntityUpdater } from "./LazyEntityUpdater.js";
|
||||
import type { IResourceController } from "./ResourceController.js";
|
||||
import type { CityID } from "./defs.js";
|
||||
|
||||
export class City{
|
||||
export class City extends LazyEntityUpdater<ICityEntity>{
|
||||
protected readonly _indirectNames: (keyof ICityEntity)[] = ["id", "nationID"];
|
||||
protected readonly _entityType = "City";
|
||||
protected readonly _raw: ICityEntity;
|
||||
|
||||
constructor(
|
||||
public readonly id: CityID
|
||||
raw: ICityEntity,
|
||||
protected readonly resourceController: IResourceController
|
||||
){
|
||||
super();
|
||||
this._raw = raw;
|
||||
}
|
||||
|
||||
get id(): CityID {
|
||||
return this._raw.id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { CityID, CityName, NationID } from "./defs.js";
|
||||
|
||||
export interface ICityEntity{
|
||||
id: CityID;
|
||||
name: CityName;
|
||||
nationID: NationID;
|
||||
}
|
||||
@@ -6,21 +6,22 @@ import { DiplomaticPermission, type CityID, type GeneralID, type GeneralName, ty
|
||||
import { must } from "@sammo/util";
|
||||
import { Nation } from "./Nation.js";
|
||||
import { Troop } from "./Troop.js";
|
||||
import { LazyEntityUpdater } from "./LazyEntityUpdater.js";
|
||||
|
||||
export class General {
|
||||
private _raw: IGeneralEntity;
|
||||
private _city: WeakRef<City>;
|
||||
private _troop: WeakRef<Troop> | undefined;
|
||||
private _nation: WeakRef<Nation>;
|
||||
export class General extends LazyEntityUpdater<IGeneralEntity> {
|
||||
protected readonly _indirectNames: (keyof IGeneralEntity)[] = ["id", "nationID", "troopID", "nationID"];
|
||||
protected readonly _entityType = "General";
|
||||
protected readonly _raw: IGeneralEntity;
|
||||
|
||||
public get raw(): Readonly<IGeneralEntity> {
|
||||
return this._raw;
|
||||
}
|
||||
protected _city: WeakRef<City>;
|
||||
protected _troop: WeakRef<Troop> | undefined;
|
||||
protected _nation: WeakRef<Nation>;
|
||||
|
||||
constructor(
|
||||
raw: IGeneralEntity,
|
||||
private resourceController: IResourceController
|
||||
protected readonly resourceController: IResourceController
|
||||
){
|
||||
super();
|
||||
this._raw = raw;
|
||||
this._city = new WeakRef(must(resourceController.getCity(raw.cityID)));
|
||||
this._nation = new WeakRef(must(resourceController.getNation(raw.nationID)));
|
||||
@@ -38,26 +39,16 @@ export class General {
|
||||
return this._raw.name;
|
||||
}
|
||||
|
||||
public update(callback: (oldRaw: IGeneralEntity) => void, force = false) {
|
||||
public get city(): City {
|
||||
return must(this._city.deref());
|
||||
}
|
||||
|
||||
const oldCityID = this._raw.cityID;
|
||||
const oldTroopID = this._raw.troopID;
|
||||
const oldNationID = this._raw.nationID;
|
||||
public get troop(): Troop | undefined {
|
||||
return this._troop?.deref();
|
||||
}
|
||||
|
||||
callback(this._raw);
|
||||
|
||||
if(!force){
|
||||
if(oldCityID !== this._raw.cityID){
|
||||
throw new Error("City change by update() is not allowed");
|
||||
}
|
||||
if(oldTroopID !== this._raw.troopID){
|
||||
throw new Error("Troop change by update() is not allowed");
|
||||
}
|
||||
if(oldNationID !== this._raw.nationID){
|
||||
throw new Error("Nation change by update() is not allowed");
|
||||
}
|
||||
}
|
||||
this.resourceController.setDirtyGeneral(this._raw);
|
||||
public get nation(): Nation {
|
||||
return must(this._nation.deref());
|
||||
}
|
||||
|
||||
public changeCity(city: CityID | City){
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { IResourceController, ValidEntity, ValidEntityType } from "./ResourceController.js";
|
||||
|
||||
export abstract class LazyEntityUpdater<Entity extends ValidEntity>{
|
||||
protected abstract readonly _indirectNames: (keyof Entity)[];
|
||||
protected abstract readonly _entityType: ValidEntityType<Entity>;
|
||||
|
||||
protected abstract readonly _raw: Entity;
|
||||
|
||||
protected abstract readonly resourceController: IResourceController;
|
||||
|
||||
public get raw(): Readonly<Entity> {
|
||||
return this._raw;
|
||||
}
|
||||
|
||||
public get entityType(): ValidEntityType<Entity> {
|
||||
return this._entityType;
|
||||
}
|
||||
|
||||
public update(callback: (oldRaw: Entity) => void, force = false) {
|
||||
const oldRaw = { ...this._raw };
|
||||
callback(this._raw);
|
||||
if (!force) {
|
||||
for (const indirectName of this._indirectNames) {
|
||||
if (oldRaw[indirectName] !== this._raw[indirectName]) {
|
||||
throw new Error(`${String(indirectName)} change by update() is not allowed`);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.resourceController.setDirty(this);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,26 @@
|
||||
import type { NationID, NationName, NationType } from "./defs.js";
|
||||
import { LazyEntityUpdater } from "./LazyEntityUpdater.js";
|
||||
import type { INationEntity } from "./NationEntity.js";
|
||||
import type { IResourceController } from "./ResourceController.js";
|
||||
import type { NationID, NationName } from "./defs.js";
|
||||
|
||||
export class Nation extends LazyEntityUpdater<INationEntity> {
|
||||
protected readonly _indirectNames: (keyof INationEntity)[] = ["id"];
|
||||
protected readonly _entityType = "Nation";
|
||||
protected readonly _raw: INationEntity;
|
||||
|
||||
export class Nation {
|
||||
constructor(
|
||||
public readonly id: NationID,
|
||||
public readonly name: NationName,
|
||||
public readonly type: NationType,
|
||||
) { }
|
||||
raw: INationEntity,
|
||||
protected readonly resourceController: IResourceController
|
||||
){
|
||||
super();
|
||||
this._raw = raw;
|
||||
}
|
||||
|
||||
public get id(): NationID {
|
||||
return this._raw.id;
|
||||
}
|
||||
|
||||
public get name(): NationName {
|
||||
return this._raw.name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { CityID, NationID, NationName, NationType } from "./defs.js";
|
||||
|
||||
export interface INationEntity{
|
||||
id: NationID;
|
||||
name: NationName;
|
||||
type: NationType;
|
||||
|
||||
capitalID: CityID;
|
||||
}
|
||||
@@ -6,6 +6,19 @@ import type { GameEnv } from "./GameEnv.js";
|
||||
import type { IGeneralEntity } from "./GeneralEntity.js";
|
||||
import type { Troop } from "./Troop.js";
|
||||
import type { ITroopEntity } from "./TroopEntity.js";
|
||||
import type { LazyEntityUpdater } from "./LazyEntityUpdater.js";
|
||||
import type { ICityEntity } from "./CityEntity.js";
|
||||
import type { INationEntity } from "./NationEntity.js";
|
||||
|
||||
export type ValidEntityList = {
|
||||
'General': IGeneralEntity;
|
||||
'City': ICityEntity;
|
||||
'Nation': INationEntity;
|
||||
'Troop': ITroopEntity;
|
||||
};
|
||||
|
||||
export type ValidEntity = ValidEntityList[keyof ValidEntityList];
|
||||
export type ValidEntityType<Entity> = Entity extends ValidEntityList[infer T extends keyof ValidEntityList] ? T : never;
|
||||
|
||||
export interface IResourceController{
|
||||
addCity(city: City): boolean;
|
||||
@@ -38,6 +51,8 @@ export interface IResourceController{
|
||||
setDirtyTroop(troop: Troop | TroopID): void;
|
||||
setDirtyNation(nation: Nation): void;
|
||||
|
||||
setDirty(entity: LazyEntityUpdater<any>): void;
|
||||
|
||||
createGeneral(raw: IGeneralEntity): General;
|
||||
createTroop(raw: ITroopEntity): Troop;
|
||||
//createNation
|
||||
|
||||
@@ -3,20 +3,20 @@ import type { General } from "./General.js";
|
||||
import type { IResourceController } from "./ResourceController.js";
|
||||
import type { ITroopEntity } from "./TroopEntity.js";
|
||||
import type { GeneralID } from "./defs.js";
|
||||
import { LazyEntityUpdater } from "./LazyEntityUpdater.js";
|
||||
|
||||
export class Troop {
|
||||
private _raw: ITroopEntity
|
||||
export class Troop extends LazyEntityUpdater<ITroopEntity> {
|
||||
protected readonly _indirectNames: (keyof ITroopEntity)[] = ["id"];
|
||||
protected readonly _entityType = "Troop";
|
||||
protected readonly _raw: ITroopEntity;
|
||||
private _leader: WeakRef<General>;
|
||||
private _members: Map<GeneralID, WeakRef<General>>;
|
||||
|
||||
public get raw(): Readonly<ITroopEntity> {
|
||||
return this._raw;
|
||||
}
|
||||
|
||||
constructor(
|
||||
raw: ITroopEntity,
|
||||
private resourceController: IResourceController
|
||||
protected resourceController: IResourceController
|
||||
){
|
||||
super();
|
||||
this._raw = raw;
|
||||
|
||||
const members = resourceController.findGeneralByTroop(raw.id);
|
||||
|
||||
Reference in New Issue
Block a user