Add ability to postpone all building tasks when queue is full
This commit is contained in:
		| @@ -1,7 +1,7 @@ | |||||||
| import ActionController from './ActionController'; | import ActionController from './ActionController'; | ||||||
| import { Args } from '../Common'; | import { Args } from '../Common'; | ||||||
| import { Task } from '../Storage/TaskQueue'; | import { Task } from '../Storage/TaskQueue'; | ||||||
| import { TryLaterError } from '../Errors'; | import { BuildingQueueFullError } from '../Errors'; | ||||||
|  |  | ||||||
| export default class CheckBuildingRemainingTimeAction extends ActionController { | export default class CheckBuildingRemainingTimeAction extends ActionController { | ||||||
|     static NAME = 'check_building_remaining_time'; |     static NAME = 'check_building_remaining_time'; | ||||||
| @@ -11,7 +11,7 @@ export default class CheckBuildingRemainingTimeAction extends ActionController { | |||||||
|         if (timer.length === 1) { |         if (timer.length === 1) { | ||||||
|             const remainingSeconds = Number(timer.attr('value')); |             const remainingSeconds = Number(timer.attr('value')); | ||||||
|             if (remainingSeconds > 0) { |             if (remainingSeconds > 0) { | ||||||
|                 throw new TryLaterError( |                 throw new BuildingQueueFullError( | ||||||
|                     remainingSeconds + 1, |                     remainingSeconds + 1, | ||||||
|                     'Building queue is full' |                     'Building queue is full' | ||||||
|                 ); |                 ); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| import * as URLParse from 'url-parse'; | import * as URLParse from 'url-parse'; | ||||||
| import { markPage, sleepShort, uniqId } from './utils'; | import { markPage, uniqId, waitForLoad } from './utils'; | ||||||
| import Scheduler from './Scheduler'; | import Scheduler from './Scheduler'; | ||||||
| import UpgradeBuildingTask from './Task/UpgradeBuildingTask'; | import UpgradeBuildingTask from './Task/UpgradeBuildingTask'; | ||||||
| import { Command } from './Common'; | import { Command } from './Common'; | ||||||
| @@ -15,8 +15,7 @@ export default class Dashboard { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async run() { |     async run() { | ||||||
|         await this.load(); |         await waitForLoad(); | ||||||
|         await sleepShort(); |  | ||||||
|  |  | ||||||
|         const p = new URLParse(window.location.href, true); |         const p = new URLParse(window.location.href, true); | ||||||
|         this.log('PARSED LOCATION', p); |         this.log('PARSED LOCATION', p); | ||||||
| @@ -77,10 +76,6 @@ export default class Dashboard { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private async load() { |  | ||||||
|         return new Promise(resolve => jQuery(resolve)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private log(...args) { |     private log(...args) { | ||||||
|         console.log('SCHEDULER:', ...args); |         console.log('SCHEDULER:', ...args); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -10,3 +10,14 @@ export class TryLaterError extends Error { | |||||||
|         Object.setPrototypeOf(this, TryLaterError.prototype); |         Object.setPrototypeOf(this, TryLaterError.prototype); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export class BuildingQueueFullError extends Error { | ||||||
|  |     readonly seconds: number; | ||||||
|  |     readonly id: TaskId; | ||||||
|  |     constructor(seconds: number, id: TaskId, msg: string = '') { | ||||||
|  |         super(msg); | ||||||
|  |         this.id = id; | ||||||
|  |         this.seconds = seconds; | ||||||
|  |         Object.setPrototypeOf(this, TryLaterError.prototype); | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { markPage, sleepShort, timestamp } from './utils'; | import { markPage, sleepShort, timestamp } from './utils'; | ||||||
| import UpgradeBuildingTask from './Task/UpgradeBuildingTask'; | import UpgradeBuildingTask from './Task/UpgradeBuildingTask'; | ||||||
| import UpgradeBuildingAction from './Action/UpgradeBuildingAction'; | import UpgradeBuildingAction from './Action/UpgradeBuildingAction'; | ||||||
| import { TryLaterError } from './Errors'; | import { BuildingQueueFullError, TryLaterError } from './Errors'; | ||||||
| import { TaskQueue, TaskList, Task, TaskId } from './Storage/TaskQueue'; | import { TaskQueue, TaskList, Task, TaskId } from './Storage/TaskQueue'; | ||||||
| import ActionQueue from './Storage/ActionQueue'; | import ActionQueue from './Storage/ActionQueue'; | ||||||
| import { Args, Command } from './Common'; | import { Args, Command } from './Common'; | ||||||
| @@ -143,6 +143,14 @@ export default class Scheduler { | |||||||
|                 this.actionQueue.clear(); |                 this.actionQueue.clear(); | ||||||
|                 this.taskQueue.postpone(task.id, timestamp() + e.seconds); |                 this.taskQueue.postpone(task.id, timestamp() + e.seconds); | ||||||
|             } |             } | ||||||
|  |             if (e instanceof BuildingQueueFullError) { | ||||||
|  |                 console.warn('BUILDING QUEUE FULL, TRY ALL AFTER', e.seconds); | ||||||
|  |                 this.actionQueue.clear(); | ||||||
|  |                 this.taskQueue.modify( | ||||||
|  |                     t => t.cmd.name === UpgradeBuildingTask.NAME, | ||||||
|  |                     t => t.withTime(timestamp() + e.seconds) | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -49,6 +49,12 @@ export class TaskQueue { | |||||||
|         return readyItems[0]; |         return readyItems[0]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     modify(predicate: (t: Task) => boolean, modifier: (t: Task) => Task) { | ||||||
|  |         const [matched, other] = this.split(predicate); | ||||||
|  |         const modified = matched.map(modifier); | ||||||
|  |         this.flushItems(modified.concat(other)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     complete(id: TaskId) { |     complete(id: TaskId) { | ||||||
|         const [_, items] = this.shiftTask(id); |         const [_, items] = this.shiftTask(id); | ||||||
|         this.flushItems(items); |         this.flushItems(items); | ||||||
| @@ -68,10 +74,21 @@ export class TaskQueue { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private shiftTask(id: TaskId): [Task | undefined, TaskList] { |     private shiftTask(id: TaskId): [Task | undefined, TaskList] { | ||||||
|         const items = this.getItems(); |         const [a, b] = this.split(t => t.id === id); | ||||||
|         const task = items.find(t => t.id === id); |         return [a.shift(), b]; | ||||||
|         const tail = items.filter(t => t.id !== id); |     } | ||||||
|         return [task, tail]; |  | ||||||
|  |     private split(predicate: (t: Task) => boolean): [TaskList, TaskList] { | ||||||
|  |         const matched: TaskList = []; | ||||||
|  |         const other: TaskList = []; | ||||||
|  |         this.getItems().forEach(t => { | ||||||
|  |             if (predicate(t)) { | ||||||
|  |                 matched.push(t); | ||||||
|  |             } else { | ||||||
|  |                 other.push(t); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         return [matched, other]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private getItems(): TaskList { |     private getItems(): TaskList { | ||||||
|   | |||||||
| @@ -18,6 +18,10 @@ export async function sleepLong() { | |||||||
|     return await sleep(ms); |     return await sleep(ms); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | export async function waitForLoad() { | ||||||
|  |     return new Promise(resolve => jQuery(resolve)); | ||||||
|  | } | ||||||
|  |  | ||||||
| export function uniqId(): string { | export function uniqId(): string { | ||||||
|     return 'id' + smallIdGenerator(); |     return 'id' + smallIdGenerator(); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user