Fix task scheduling

This commit is contained in:
Anton Vakhrushev 2020-05-26 11:54:50 +03:00
parent 09e989a8a1
commit a358fe743e
3 changed files with 22 additions and 11 deletions

View File

@ -1,6 +1,8 @@
import { Args } from './Args'; import { Args } from './Args';
import { uniqId } from '../utils'; import { uniqId } from '../utils';
import { ResourcesInterface } from '../Core/Resources'; import { ResourcesInterface } from '../Core/Resources';
import { ProductionQueue } from '../Core/ProductionQueue';
import { getProductionQueue } from '../Task/TaskMap';
export type TaskId = string; export type TaskId = string;
@ -40,10 +42,18 @@ export interface TaskProvider {
setTasks(tasks: TaskList): void; setTasks(tasks: TaskList): void;
} }
export interface TaskMatcher {
(task: Task): boolean;
}
export interface TaskTransformer { export interface TaskTransformer {
(task: Task): Task; (task: Task): Task;
} }
export function isInQueue(queue: ProductionQueue): TaskMatcher {
return (task: Task) => getProductionQueue(task.name) === queue;
}
export function withTime(ts: number): TaskTransformer { export function withTime(ts: number): TaskTransformer {
return (task: Task) => new Task(task.id, ts, task.name, task.args); return (task: Task) => new Task(task.id, ts, task.name, task.args);
} }

View File

@ -22,7 +22,7 @@ export class VillageController {
} }
getReadyProductionTask(): Task | undefined { getReadyProductionTask(): Task | undefined {
return this.taskCollection.getReadyProductionTask(); return this.taskCollection.getReadyForProductionTask();
} }
addTask(name: string, args: Args) { addTask(name: string, args: Args) {

View File

@ -1,13 +1,13 @@
import { VillageStorage } from './Storage/VillageStorage'; import { VillageStorage } from './Storage/VillageStorage';
import { Task, TaskId, uniqTaskId, withResources, withTime } from './Queue/TaskProvider'; import { isInQueue, Task, TaskId, uniqTaskId, withResources, withTime } from './Queue/TaskProvider';
import { Args } from './Queue/Args'; import { Args } from './Queue/Args';
import { isProductionTask, ProductionQueue, OrderedProductionQueues } from './Core/ProductionQueue'; import { isProductionTask, OrderedProductionQueues, ProductionQueue } from './Core/ProductionQueue';
import { getProductionQueue } from './Task/TaskMap';
import { timestamp } from './utils'; import { timestamp } from './utils';
import { Resources } from './Core/Resources'; import { Resources } from './Core/Resources';
import { ContractAttributes, ContractType } from './Core/Contract'; import { ContractAttributes, ContractType } from './Core/Contract';
import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask'; import { UpgradeBuildingTask } from './Task/UpgradeBuildingTask';
import { ForgeImprovementTask } from './Task/ForgeImprovementTask'; import { ForgeImprovementTask } from './Task/ForgeImprovementTask';
import * as _ from 'underscore';
interface QueueTasks { interface QueueTasks {
queue: ProductionQueue; queue: ProductionQueue;
@ -62,10 +62,9 @@ export class VillageTaskCollection {
const tasks = this.storage.getTasks(); const tasks = this.storage.getTasks();
const result: Array<QueueTasks> = []; const result: Array<QueueTasks> = [];
for (let queue of OrderedProductionQueues) { for (let queue of OrderedProductionQueues) {
const queueTasks = tasks.filter(task => getProductionQueue(task.name) === queue);
result.push({ result.push({
queue, queue,
tasks: queueTasks, tasks: tasks.filter(isInQueue(queue)),
finishTs: this.storage.getQueueTaskEnding(queue), finishTs: this.storage.getQueueTaskEnding(queue),
}); });
} }
@ -73,16 +72,18 @@ export class VillageTaskCollection {
} }
getTasksInProductionQueue(queue: ProductionQueue): Array<Task> { getTasksInProductionQueue(queue: ProductionQueue): Array<Task> {
return this.storage.getTasks().filter(task => getProductionQueue(task.name) === queue); return this.storage.getTasks().filter(isInQueue(queue));
} }
getReadyProductionTask(): Task | undefined { getReadyForProductionTask(): Task | undefined {
const groups = this.getQueueGroupedTasks(); const groups = this.getQueueGroupedTasks();
const firstReadyGroup = groups.filter(g => g.finishTs <= timestamp()).shift(); const nowTs = timestamp();
const firstReadyGroup = groups.find(g => g.finishTs <= nowTs && g.tasks.length !== 0);
if (!firstReadyGroup) { if (!firstReadyGroup) {
return undefined; return undefined;
} }
return firstReadyGroup.tasks.shift();
return _.first(firstReadyGroup.tasks);
} }
postponeTask(taskId: TaskId, seconds: number) { postponeTask(taskId: TaskId, seconds: number) {
@ -105,7 +106,7 @@ export class VillageTaskCollection {
} }
getVillageRequiredResources(): Resources { getVillageRequiredResources(): Resources {
const first = this.getReadyProductionTask(); const first = this.getReadyForProductionTask();
if (first && first.args.resources) { if (first && first.args.resources) {
return Resources.fromObject(first.args.resources); return Resources.fromObject(first.args.resources);
} }