refac: boostrap

This commit is contained in:
2024-03-14 17:24:14 +00:00
parent 39e8eab6cb
commit 6a6bdba08b
5 changed files with 156 additions and 111 deletions
+49 -3
View File
@@ -1,26 +1,72 @@
import type { ICityEntity } from "./Entity/CityEntity.js";
import { LazyEntityUpdater } from "./LazyEntityUpdater.js";
import type { IResourceController } from "./IResourceController.js";
import type { CityID } from "./defs.js";
import type { CityID, GeneralID, NationID } from "./defs.js";
import type { General } from "./General.js";
import { must } from "@sammo/util";
export class City extends LazyEntityUpdater<ICityEntity>{
protected readonly _indirectNames: (keyof ICityEntity)[] = ["id", "nationID"];
protected readonly _entityType = "City";
protected readonly _raw: ICityEntity;
protected _members = new Map<GeneralID, WeakRef<General>>;
protected _otherMembers = new Map<NationID, Map<GeneralID, WeakRef<General>>>;
constructor(
raw: ICityEntity,
protected readonly rsc: IResourceController
protected readonly rsc: IResourceController,
bootstrapInfo: {
general: GeneralID[];
}
){
super();
this._raw = raw;
this._bootstrapInfo = bootstrapInfo;
}
private _bootstrapInfo?: ConstructorParameters<typeof City>[2];
public bootstrap(){
//do nothing;
const rsc = this.rsc;
const bootstrapInfo = must(this._bootstrapInfo);
delete this._bootstrapInfo;
const nationID = this._raw.nationID;
for(const id of bootstrapInfo.general){
const general = must(rsc.general(id));
this.notifyJoinGeneral(general);
}
}
get id(): CityID {
return this._raw.id;
}
notifyJoinGeneral(general: General){
const nationID = general.raw.nationID;
if(nationID === this._raw.nationID){
this._members.set(general.id, new WeakRef(general));
return;
}
let otherMembers = this._otherMembers.get(nationID);
if(!otherMembers){
otherMembers = new Map();
this._otherMembers.set(nationID, otherMembers);
}
otherMembers.set(general.id, new WeakRef(general));
}
notifyQuitGeneral(general: General){
const nationID = general.raw.nationID;
if(nationID === this._raw.nationID){
this._members.delete(general.id);
return;
}
const otherMembers = must(this._otherMembers.get(nationID));
otherMembers.delete(general.id);
}
}
+26 -48
View File
@@ -1,4 +1,4 @@
import { InvalidArgument } from "@sammo/util";
import { InvalidArgument, NotYetImplemented } from "@sammo/util";
import { City } from "./City.js";
import type { IGeneralEntity } from "./Entity/GeneralEntity.js";
import type { IResourceController } from "./IResourceController.js";
@@ -41,7 +41,7 @@ export class General extends LazyEntityUpdater<IGeneralEntity> {
this._squad = new WeakRef(must(rsc.squad(raw.squadID, raw.nationID)));
}
//TODO: iActionHandlers 초기화
this.reconfigureIActionHandlers();
}
public get id(): GeneralID {
@@ -86,23 +86,16 @@ export class General extends LazyEntityUpdater<IGeneralEntity> {
return this._raw.officerLevel as number as CityOfficerLevel;
}
public changeCity(city: CityID | City){
const cityObj: City = (()=>{
if(city instanceof City){
return city;
}
const cityObj = this.rsc.city(city);
if(!cityObj){
throw new InvalidArgument(`City not found: ${city}`);
}
return cityObj;
})();
this._city = new WeakRef(cityObj);
public changeCity(city: City){
this.city.notifyQuitGeneral(this);
//TODO: ResourceController에게 알려야 하는가?
this._city = new WeakRef(city);
this.forceUpdate((raw) => {
raw.cityID = cityObj.id;
raw.cityID = city.id;
});
city.notifyJoinGeneral(this);
this.reconfigureIActionHandlers();
}
public quitSquad(){
@@ -115,7 +108,7 @@ export class General extends LazyEntityUpdater<IGeneralEntity> {
squad.destroySquad(false);
}
else{
squad.members.delete(this._raw.id);
squad.notifyQuitGeneral(this);
}
this._squad = undefined;
@@ -124,45 +117,25 @@ export class General extends LazyEntityUpdater<IGeneralEntity> {
});
}
public changeSquad(squad: SquadID | Squad){
public changeSquad(squad: Squad){
this.quitSquad();
const squadObj: Squad = (()=>{
if(squad instanceof Squad){
return squad;
}
const squadObj = this.rsc.squad(squad, this._raw.nationID);
if(!squadObj){
throw new InvalidArgument(`Squad not found: ${squad}`);
}
return squadObj;
})();
squadObj.members.set(this._raw.id, new WeakRef(this));
this._squad = new WeakRef(squadObj);
this._squad = new WeakRef(squad);
this.forceUpdate((raw) => {
raw.squadID = squadObj.id;
raw.squadID = squad.id;
});
squad.notifyJoinGeneral(this);
}
public changeNation(nation: NationID | Nation){
const nationObj: Nation = (()=>{
if(nation instanceof Nation){
return nation;
}
const nationObj = this.rsc.nation(nation);
if(!nationObj){
throw new InvalidArgument(`Nation not found: ${nation}`);
}
return nationObj;
})();
this._nation = new WeakRef(nationObj);
public changeNation(nation: Nation){
this.quitSquad();
this.nation.notifyQuitGeneral(this);
this._nation = new WeakRef(nation);
this.forceUpdate((raw) => {
raw.nationID = nationObj.id;
raw.nationID = nation.id;
raw.diplomaticPermission = DiplomaticPermission.none;
if(nationObj.id == 0){
if(nation.id == 0){
raw.officerLevel = OfficerLevel.none;
}
else{
@@ -170,6 +143,13 @@ export class General extends LazyEntityUpdater<IGeneralEntity> {
}
raw.nationJoinedYearMonth = this.rsc.gameEnv.raw.yearMonth;
});
nation.notifyJoinGeneral(this);
this.reconfigureIActionHandlers();
}
private reconfigureIActionHandlers(){
throw new NotYetImplemented();
}
public updateTurnTime(){
@@ -178,7 +158,6 @@ export class General extends LazyEntityUpdater<IGeneralEntity> {
this.forceUpdate((raw) => {
raw.turnTime = addSeconds(raw.turnTime, secondsPerTurn);
});
}
public compareTurnTime(other: General): number {
@@ -197,5 +176,4 @@ export class General extends LazyEntityUpdater<IGeneralEntity> {
}
return 0;
}
}
+36 -49
View File
@@ -26,8 +26,8 @@ export class Nation extends LazyEntityUpdater<INationEntity> {
protected readonly cityList = new Map<CityID, WeakRef<City>>;
protected readonly generalList = new Map<GeneralID, WeakRef<General>>;
protected readonly squadList = new Map<SquadID, WeakRef<Squad>>;
protected readonly generalList = new Map<GeneralID, WeakRef<General>>;
protected readonly npcGeneralList = new Map<GeneralID, WeakRef<General>>();
protected readonly userGeneralList = new Map<GeneralID, WeakRef<General>>();
@@ -60,47 +60,19 @@ export class Nation extends LazyEntityUpdater<INationEntity> {
const bootstrapInfo = must(this._bootstrapInfo);
delete this._bootstrapInfo;
const nationID = this._raw.id;
const bootstrapCityID = bootstrapInfo.city;
for (const city of bootstrapCityID.map((id) => must(rsc.cityList.get(id)))) {
this.cityList.set(city.id, new WeakRef(city));
this.notifyJoinCity(city);
}
const bootstrapSquadID = bootstrapInfo.squad;
for (const squad of rsc.squadList.values()) {
if (squad.raw.nationID !== nationID) {
continue;
}
this.squadList.set(squad.id, new WeakRef(squad));
for(const squad of bootstrapSquadID.map((id) => must(rsc.squadList.get(id)))){
this.notifyAddSquad(squad);
}
const bootstrapGeneralID = bootstrapInfo.general;
for (const general of bootstrapGeneralID.map((id) => must(rsc.generalList.get(id)))) {
this.generalList.set(general.id, new WeakRef(general));
if (general.isUser) {
this.userGeneralList.set(general.id, new WeakRef(general));
if (categorizeGeneral(general) === "war") {
this.warUserGeneralList.set(general.id, new WeakRef(general));
}
else {
this.domesticUserGeneralList.set(general.id, new WeakRef(general));
}
} else {
this.npcGeneralList.set(general.id, new WeakRef(general));
if (categorizeGeneral(general) === "war") {
this.warNPCGeneralList.set(general.id, new WeakRef(general));
}
else {
this.domesticNPCGeneralList.set(general.id, new WeakRef(general));
}
}
const staffLevel = general.staffLevel;
if (staffLevel !== undefined) {
this.staffList.set(staffLevel, new WeakRef(general));
}
this.notifyJoinGeneral(general);
}
}
@@ -112,12 +84,23 @@ export class Nation extends LazyEntityUpdater<INationEntity> {
return this._raw.name;
}
public _kickGeneral(general: General | GeneralID) {
//국가에서 장수가 빠져나가는 경우, class내 변수에 대한 처리.
if (!(general instanceof General)) {
general = must(this.generalList.get(general)?.deref());
}
public notifyAddSquad(squad: Squad) {
this.squadList.set(squad.id, new WeakRef(squad));
}
public notifyDestroySquad(squad: Squad) {
this.squadList.delete(squad.id);
}
public notifyJoinCity(city: City) {
this.cityList.set(city.id, new WeakRef(city));
}
public notifyQuitCity(city: City) {
this.cityList.delete(city.id);
}
public notifyQuitGeneral(general: General) {
const generalID = general.id;
this.generalList.delete(generalID);
@@ -133,7 +116,6 @@ export class Nation extends LazyEntityUpdater<INationEntity> {
}
const staffLevel = general.staffLevel;
if (staffLevel !== undefined) {
this.staffList.delete(staffLevel);
@@ -147,26 +129,31 @@ export class Nation extends LazyEntityUpdater<INationEntity> {
}
}
public notifyDestroySquad(squad: Squad) {
this.squadList.delete(squad.id);
}
public _joinGeneral(general: General | GeneralID) {
public notifyJoinGeneral(general: General) {
//국가에 장수가 들어오는 경우, class내 변수에 대한 처리.
if (!(general instanceof General)) {
general = must(this.rsc.general(general));
}
const generalID = general.id;
this.generalList.set(generalID, new WeakRef(general));
if (general.isUser) {
this.userGeneralList.set(generalID, new WeakRef(general));
if (categorizeGeneral(general) === "war") {
this.warUserGeneralList.set(generalID, new WeakRef(general));
}
else {
this.domesticUserGeneralList.set(generalID, new WeakRef(general));
}
} else {
this.npcGeneralList.set(generalID, new WeakRef(general));
if (categorizeGeneral(general) === "war") {
this.warNPCGeneralList.set(generalID, new WeakRef(general));
}
else {
this.domesticNPCGeneralList.set(generalID, new WeakRef(general));
}
}
const staffLevel = general.staffLevel;
if (staffLevel !== undefined) {
this.staffList.set(staffLevel, new WeakRef(general));
}
+10 -2
View File
@@ -73,6 +73,14 @@ export class Squad extends LazyEntityUpdater<ISquadEntity> {
});
}
//joinSquad은 General에서 처리
//quitSquad은 General에서 처리
public notifyQuitGeneral(general: General) {
if(general.id === this._leader.deref()?.id){
throw new Error("Leader cannot quit");
}
this._members.delete(general.id);
}
public notifyJoinGeneral(general: General) {
this._members.set(general.id, new WeakRef(general));
}
}