-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
getTableKeys
/getTableValuesAsSet
utils. Removed unused data f…
…rom level configs. Corrected level configs schema / added typing in ltx. Add new `simulation_group_id` field for levels. Add `initializeLevelSimulationGroupIds` util. Removed hardcoded `GROUP_ID_BY_LEVEL_NAME` and `VALID_SMART_TERRAINS_SIMULATION_ROLES` constants. Smart terrain role validation test. More ltx mocks added. Signed-off-by: Neloreck <[email protected]>
- Loading branch information
Showing
18 changed files
with
420 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
src/engine/core/managers/simulation/utils/simulation_ini.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
import { beforeEach, describe, expect, it } from "@jest/globals"; | ||
|
||
import { registerSimulator } from "@/engine/core/database"; | ||
import { GAME_MAPS_SINGLE_LTX } from "@/engine/core/managers/simulation/SimulationConfig"; | ||
import { initializeLevelSimulationGroupIds } from "@/engine/core/managers/simulation/utils/simulation_ini"; | ||
import { destroySimulationData } from "@/engine/core/managers/simulation/utils/simulation_initialization"; | ||
import { resetRegistry } from "@/fixtures/engine"; | ||
import { MockIniFile } from "@/fixtures/xray"; | ||
|
||
describe("initializeLevelSimulationGroupIds util", () => { | ||
beforeEach(() => { | ||
resetRegistry(); | ||
registerSimulator(); | ||
destroySimulationData(); | ||
}); | ||
|
||
it("should correctly initialize with default maps ltx", async () => { | ||
expect( | ||
initializeLevelSimulationGroupIds( | ||
MockIniFile.mock("test.ltx", { | ||
agroprom: 128, | ||
agroprom_underground: 129, | ||
darkvalley: 130, | ||
escape: 131, | ||
garbage: 132, | ||
hospital: 133, | ||
jupiter: 134, | ||
jupiter_underground: 135, | ||
labx8: 136, | ||
limansk: 137, | ||
marsh: 138, | ||
military: 139, | ||
pripyat: 140, | ||
red_forest: 141, | ||
stancia_2: 142, | ||
yantar: 143, | ||
zaton: 144, | ||
}) | ||
) | ||
).toEqualLuaTables({ | ||
agroprom: 128, | ||
agroprom_underground: 129, | ||
darkvalley: 130, | ||
escape: 131, | ||
garbage: 132, | ||
hospital: 133, | ||
jupiter: 134, | ||
jupiter_underground: 135, | ||
labx8: 136, | ||
limansk: 137, | ||
marsh: 138, | ||
military: 139, | ||
pripyat: 140, | ||
red_forest: 141, | ||
stancia_2: 142, | ||
yantar: 143, | ||
zaton: 144, | ||
}); | ||
|
||
expect(initializeLevelSimulationGroupIds(GAME_MAPS_SINGLE_LTX)).toEqualLuaTables({ | ||
agroprom: 128, | ||
agroprom_underground: 129, | ||
darkvalley: 130, | ||
escape: 131, | ||
garbage: 132, | ||
hospital: 133, | ||
jupiter: 3, | ||
jupiter_underground: 5, | ||
labx8: 4, | ||
limansk: 134, | ||
marsh: 135, | ||
military: 136, | ||
pripyat: 2, | ||
red_forest: 137, | ||
stancia_2: 138, | ||
yantar: 139, | ||
zaton: 1, | ||
}); | ||
}); | ||
|
||
it("should throw exception on IDs out of 1-255 range", () => { | ||
expect(() => { | ||
initializeLevelSimulationGroupIds( | ||
MockIniFile.mock("test.ltx", { | ||
agroprom: { | ||
simulation_group_id: -100, | ||
}, | ||
}) | ||
); | ||
}).toThrow("[JEST_TEST] Failed to assign level 'agroprom' group id '-100', it is not in range [1:255]."); | ||
|
||
expect(() => { | ||
initializeLevelSimulationGroupIds( | ||
MockIniFile.mock("test.ltx", { | ||
agroprom: { | ||
simulation_group_id: -1, | ||
}, | ||
}) | ||
); | ||
}).toThrow("[JEST_TEST] Failed to assign level 'agroprom' group id '-1', it is not in range [1:255]."); | ||
|
||
expect(() => { | ||
initializeLevelSimulationGroupIds( | ||
MockIniFile.mock("test.ltx", { | ||
agroprom: { | ||
simulation_group_id: 0, | ||
}, | ||
}) | ||
); | ||
}).toThrow("[JEST_TEST] Failed to assign level 'agroprom' group id '0', it is not in range [1:255]."); | ||
|
||
expect(() => { | ||
initializeLevelSimulationGroupIds( | ||
MockIniFile.mock("test.ltx", { | ||
agroprom: { | ||
simulation_group_id: 255, | ||
}, | ||
}) | ||
); | ||
}).toThrow("[JEST_TEST] Failed to assign level 'agroprom' group id '255', it is not in range [1:255]."); | ||
|
||
expect(() => { | ||
initializeLevelSimulationGroupIds( | ||
MockIniFile.mock("test.ltx", { | ||
agroprom: { | ||
simulation_group_id: 1_000, | ||
}, | ||
}) | ||
); | ||
}).toThrow("[JEST_TEST] Failed to assign level 'agroprom' group id '1000', it is not in range [1:255]."); | ||
}); | ||
|
||
it("should throw exception on duplicate IDs", () => { | ||
expect(() => { | ||
initializeLevelSimulationGroupIds( | ||
MockIniFile.mock("test.ltx", { | ||
agroprom: { | ||
simulation_group_id: 10, | ||
}, | ||
agroprom_underground: { | ||
simulation_group_id: 10, | ||
}, | ||
}) | ||
); | ||
}).toThrow( | ||
"[JEST_TEST] Found duplicate group id '10' usage for level 'agroprom_underground', 'agroprom' already using it" | ||
); | ||
}); | ||
}); |
59 changes: 59 additions & 0 deletions
59
src/engine/core/managers/simulation/utils/simulation_ini.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { assert } from "@/engine/core/utils/assertion"; | ||
import { readIniNumber } from "@/engine/core/utils/ini"; | ||
import { LuaLogger } from "@/engine/core/utils/logging"; | ||
import { getTableKeys } from "@/engine/core/utils/table"; | ||
import { levels, TLevel } from "@/engine/lib/constants/levels"; | ||
import { MAX_U8 } from "@/engine/lib/constants/memory"; | ||
import { IniFile, LuaArray, Optional, TName, TNumberId } from "@/engine/lib/types"; | ||
|
||
const log: LuaLogger = new LuaLogger($filename); | ||
|
||
/** | ||
* Assign simulation group IDs for levels based on data from ini file. | ||
* Try to assign placeholder IDs if group is not defined in ini file. | ||
* | ||
* @param ini - target ini file to read data from | ||
* @returns map of simulation group IDs by level name | ||
*/ | ||
export function initializeLevelSimulationGroupIds(ini: IniFile): LuaTable<TName, TNumberId> { | ||
log.info("Initialize level simulation group IDs from: '%s', '%s' levels", ini.fname(), table.size(levels)); | ||
|
||
const availableLevels: LuaArray<TLevel> = getTableKeys($fromObject(levels)); | ||
const usedGroupIds: LuaTable<TNumberId, TName> = new LuaTable(); | ||
const groupIdsByLevels: LuaTable<TName, TNumberId> = new LuaTable(); | ||
|
||
let freeGroupId: TNumberId = 127; | ||
|
||
// Sort to make things more deterministic in terms of keys iteration / assigning ordered IDs. | ||
table.sort(availableLevels, (left, right) => left < right); | ||
|
||
for (const [, level] of availableLevels) { | ||
const simulationGroupId: Optional<TNumberId> = readIniNumber(ini, level, "simulation_group_id"); | ||
const nextId: TNumberId = typeof simulationGroupId === "number" ? simulationGroupId : ++freeGroupId; | ||
|
||
// Maintain u8 boundaries / overflow. | ||
assert( | ||
nextId > 0 && nextId < MAX_U8, | ||
"[%s] Failed to assign level '%s' group id '%s', it is not in range [1:%s].", | ||
$filename, | ||
level, | ||
simulationGroupId, | ||
MAX_U8 | ||
); | ||
|
||
// Avoid duplicates of simulation IDs. | ||
assert( | ||
!usedGroupIds.has(nextId), | ||
"[%s] Found duplicate group id '%s' usage for level '%s', '%s' already using it", | ||
$filename, | ||
nextId, | ||
level, | ||
usedGroupIds.get(nextId) | ||
); | ||
|
||
usedGroupIds.set(nextId, level); | ||
groupIdsByLevels.set(level, nextId); | ||
} | ||
|
||
return groupIdsByLevels; | ||
} |
Oops, something went wrong.