mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-08 11:30:12 +08:00
refactor: Create a new super class Event and prevent duplicate logic
This commit is contained in:
1 parent
2dc40a2254
commit
0f0f43b838
6 files changed
+109
-49
No files matched your search
@@ -0,0 +1,48 @@
|
|||||||
|
import { Condition } from './condition/Condition'
|
||||||
|
import {
|
||||||
|
ICommand,
|
||||||
|
ICondition,
|
||||||
|
IFileExistenceChecker,
|
||||||
|
IRequirements,
|
||||||
|
IResponse,
|
||||||
|
} from './schema'
|
||||||
|
|
||||||
|
export class Event {
|
||||||
|
id: string
|
||||||
|
private condition: Condition
|
||||||
|
private requirements: string[]
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
id: string,
|
||||||
|
condition: ICondition,
|
||||||
|
private response: IResponse,
|
||||||
|
requirements?: IRequirements
|
||||||
|
) {
|
||||||
|
this.id = id
|
||||||
|
this.condition = new Condition(condition)
|
||||||
|
this.requirements = requirements || []
|
||||||
|
}
|
||||||
|
|
||||||
|
async satisfies(
|
||||||
|
command: ICommand,
|
||||||
|
checker: IFileExistenceChecker
|
||||||
|
): Promise<boolean> {
|
||||||
|
return this.condition.satisfies(command, checker)
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkRequirements(completed: string[]): boolean {
|
||||||
|
return this.requirements.every((req) => completed.includes(req))
|
||||||
|
}
|
||||||
|
|
||||||
|
private finished(completed: string[]): boolean {
|
||||||
|
return completed.includes(this.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
active(completed: string[]): boolean {
|
||||||
|
return !this.finished(completed) && this.checkRequirements(completed)
|
||||||
|
}
|
||||||
|
|
||||||
|
getResponse(): IResponse {
|
||||||
|
return this.response
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/* eslint-disable max-classes-per-file */
|
||||||
|
import { Event } from './Event'
|
||||||
|
import { IStageException, IGlobalException } from './schema/exception'
|
||||||
|
|
||||||
|
export class StageException extends Event {
|
||||||
|
readonly catchAll: boolean
|
||||||
|
|
||||||
|
constructor({ id, condition, response, catchAll }: IStageException) {
|
||||||
|
super(id, condition, response)
|
||||||
|
this.catchAll = catchAll
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GlobalException extends Event {
|
||||||
|
constructor({ id, condition, response, requirements }: IGlobalException) {
|
||||||
|
super(id, condition, response, requirements)
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
-16
@@ -1,5 +1,7 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
import { Condition } from './condition/Condition'
|
import { Condition } from './condition/Condition'
|
||||||
|
import { Event } from './Event'
|
||||||
|
import { GlobalException, StageException } from './Exception'
|
||||||
import {
|
import {
|
||||||
IQuest,
|
IQuest,
|
||||||
IStage,
|
IStage,
|
||||||
@@ -10,15 +12,28 @@ import {
|
|||||||
import { Stage } from './Stage'
|
import { Stage } from './Stage'
|
||||||
|
|
||||||
export class Quest {
|
export class Quest {
|
||||||
private stages: Stage[]
|
|
||||||
private quest: IQuest
|
private quest: IQuest
|
||||||
|
private stages: Stage[]
|
||||||
|
private exceptions: GlobalException[] = []
|
||||||
|
private events: Map<string, Event> = new Map()
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
quest: IQuest,
|
quest: IQuest,
|
||||||
private checker: IFileExistenceChecker
|
private checker: IFileExistenceChecker
|
||||||
) {
|
) {
|
||||||
this.quest = quest
|
this.quest = quest
|
||||||
this.stages = quest.stages.map((stage: IStage) => new Stage(stage))
|
this.stages = quest.stages.map((stage) => new Stage(stage))
|
||||||
|
for (const stage of this.stages) {
|
||||||
|
this.events.set(stage.id, stage)
|
||||||
|
for (const exception of stage.getExceptions()) {
|
||||||
|
this.events.set(exception.id, exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const exception of quest.exceptions ?? []) {
|
||||||
|
const globalException = new GlobalException(exception)
|
||||||
|
this.exceptions.push(globalException)
|
||||||
|
this.events.set(globalException.id, globalException)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getActiveStages(completed: string[]) {
|
getActiveStages(completed: string[]) {
|
||||||
@@ -26,15 +41,7 @@ export class Quest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getActiveExceptions(completed: string[]) {
|
private getActiveExceptions(completed: string[]) {
|
||||||
return (
|
return this.exceptions.filter((exception) => exception.active(completed))
|
||||||
this.quest.exceptions?.filter(
|
|
||||||
(exception) =>
|
|
||||||
!completed.includes(exception.id) &&
|
|
||||||
exception.requirements.every((requirement) =>
|
|
||||||
completed.includes(requirement)
|
|
||||||
)
|
|
||||||
) ?? []
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async findSatisfiedEvent(
|
async findSatisfiedEvent(
|
||||||
@@ -49,17 +56,15 @@ export class Quest {
|
|||||||
return stage.id
|
return stage.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const exception of stages.flatMap((stage) => stage.exceptions)) {
|
for (const exception of stages.flatMap((stage) => stage.getExceptions())) {
|
||||||
const condition = new Condition(exception.condition)
|
|
||||||
if (exception.catchAll && !catchAllException) {
|
if (exception.catchAll && !catchAllException) {
|
||||||
catchAllException = exception.id
|
catchAllException = exception.id
|
||||||
} else if (await condition.satisfies(command, this.checker)) {
|
} else if (await exception.satisfies(command, this.checker)) {
|
||||||
return exception.id
|
return exception.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const exception of this.getActiveExceptions(completed)) {
|
for (const exception of this.getActiveExceptions(completed)) {
|
||||||
const condition = new Condition(exception.condition)
|
if (await exception.satisfies(command, this.checker)) {
|
||||||
if (await condition.satisfies(command, this.checker)) {
|
|
||||||
return exception.id
|
return exception.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-30
@@ -1,38 +1,26 @@
|
|||||||
import { IStage, ICommand, IFileExistenceChecker } from './schema'
|
import { IStage } from './schema'
|
||||||
import { Condition } from './condition/Condition'
|
import { StageException } from './Exception'
|
||||||
import { StageException } from './schema/exception'
|
import { Event } from './Event'
|
||||||
|
|
||||||
export class Stage {
|
export class Stage extends Event {
|
||||||
id: string
|
|
||||||
name: string
|
name: string
|
||||||
public readonly condition: Condition
|
private exceptions: StageException[]
|
||||||
private requirements: string[]
|
|
||||||
public readonly exceptions: StageException[]
|
|
||||||
|
|
||||||
constructor({ id, name, condition, requirements, exceptions }: IStage) {
|
constructor({
|
||||||
this.id = id
|
id,
|
||||||
|
name,
|
||||||
|
condition,
|
||||||
|
requirements,
|
||||||
|
exceptions,
|
||||||
|
response,
|
||||||
|
}: IStage) {
|
||||||
|
super(id, condition, response, requirements)
|
||||||
this.name = name || ''
|
this.name = name || ''
|
||||||
this.condition = new Condition(condition)
|
this.exceptions =
|
||||||
this.requirements = requirements || []
|
exceptions?.map((exception) => new StageException(exception)) || []
|
||||||
this.exceptions = exceptions || []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async satisfies(
|
getExceptions(): StageException[] {
|
||||||
command: ICommand,
|
return this.exceptions
|
||||||
checker: IFileExistenceChecker
|
|
||||||
): Promise<boolean> {
|
|
||||||
return this.condition.satisfies(command, checker)
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkRequirements(completed: string[]): boolean {
|
|
||||||
return this.requirements.every((req) => completed.includes(req))
|
|
||||||
}
|
|
||||||
|
|
||||||
private finished(completed: string[]): boolean {
|
|
||||||
return completed.includes(this.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
active(completed: string[]): boolean {
|
|
||||||
return !this.finished(completed) && this.checkRequirements(completed)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,16 +9,16 @@ export const exceptionSchema = z.object({
|
|||||||
response: responseSchema,
|
response: responseSchema,
|
||||||
})
|
})
|
||||||
|
|
||||||
export type Exception = z.infer<typeof exceptionSchema>
|
export type IException = z.infer<typeof exceptionSchema>
|
||||||
|
|
||||||
export const stageExceptionSchema = exceptionSchema.extend({
|
export const stageExceptionSchema = exceptionSchema.extend({
|
||||||
catchAll: z.boolean().default(false),
|
catchAll: z.boolean().default(false),
|
||||||
})
|
})
|
||||||
|
|
||||||
export type StageException = z.infer<typeof stageExceptionSchema>
|
export type IStageException = z.infer<typeof stageExceptionSchema>
|
||||||
|
|
||||||
export const globalExceptionSchema = exceptionSchema.extend({
|
export const globalExceptionSchema = exceptionSchema.extend({
|
||||||
requirements: requirementsSchema.default([]),
|
requirements: requirementsSchema.default([]),
|
||||||
})
|
})
|
||||||
|
|
||||||
export type GlobalException = z.infer<typeof globalExceptionSchema>
|
export type IGlobalException = z.infer<typeof globalExceptionSchema>
|
||||||
@@ -3,6 +3,7 @@ export { stageSchema, IStage } from './stage.js'
|
|||||||
export { requirementsSchema, IRequirements } from './requirements.js'
|
export { requirementsSchema, IRequirements } from './requirements.js'
|
||||||
export { responseSchema, IResponse } from './response.js'
|
export { responseSchema, IResponse } from './response.js'
|
||||||
export { questSchema, IQuest } from './quest.js'
|
export { questSchema, IQuest } from './quest.js'
|
||||||
|
export { exceptionSchema, IException } from './exception.js'
|
||||||
|
|
||||||
export interface ICommand {
|
export interface ICommand {
|
||||||
command?: string
|
command?: string
|
||||||
|
|||||||
Reference in new issue
Block a user