Automatic action resolving with decorators and magic

This commit is contained in:
2020-04-03 11:54:13 +03:00
parent 54fca1f4f4
commit 29485d233d
13 changed files with 92 additions and 111 deletions

View File

@ -1,6 +1,35 @@
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { GameState } from '../Storage/GameState';
import Scheduler from '../Scheduler';
export default abstract class ActionController {
abstract async run(args: Args, task: Task);
const actionMap: { [name: string]: Function | undefined } = {};
export function registerAction(constructor: Function) {
console.log('REGISTER ACTION', constructor.name);
actionMap[constructor.name] = constructor;
}
export function createAction(
name: string,
state: GameState,
scheduler: Scheduler
): ActionController | undefined {
const storedFunction = actionMap[name];
if (storedFunction === undefined) {
return undefined;
}
const constructor = (storedFunction as unknown) as typeof ActionController;
return new constructor(state, scheduler);
}
export class ActionController {
protected state: GameState;
protected scheduler: Scheduler;
constructor(state: GameState, scheduler: Scheduler) {
this.state = state;
this.scheduler = scheduler;
}
async run(args: Args, task: Task) {}
}

View File

@ -1,11 +1,10 @@
import ActionController from './ActionController';
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { BuildingQueueFullError } from '../Errors';
export default class CheckBuildingRemainingTimeAction extends ActionController {
static NAME = 'check_building_remaining_time';
@registerAction
export class CheckBuildingRemainingTimeAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
const timer = jQuery('.buildDuration .timer');
if (timer.length === 1) {

View File

@ -1,9 +1,9 @@
import ActionController from './ActionController';
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
export default class ClickButtonAction extends ActionController {
static NAME = 'click_button';
@registerAction
export class ClickButtonAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
const el = jQuery(args.selector);
if (el.length === 1) {

View File

@ -1,16 +1,9 @@
import ActionController from './ActionController';
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import Scheduler from '../Scheduler';
export default class CompleteTaskAction extends ActionController {
static NAME = 'complete_task';
private scheduler: Scheduler;
constructor(scheduler: Scheduler) {
super();
this.scheduler = scheduler;
}
@registerAction
export class CompleteTaskAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
this.scheduler.completeTask(task.id);
}

View File

@ -1,9 +1,9 @@
import ActionController from './ActionController';
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
export default class GoToPageAction extends ActionController {
static NAME = 'go_to_page';
@registerAction
export class GoToPageAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
window.location.assign(args.path);
}

View File

@ -1,18 +1,10 @@
import ActionController from './ActionController';
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { ActionError } from '../Errors';
import { GameState } from '../Storage/GameState';
export default class GrabHeroAttributesAction extends ActionController {
static NAME = 'grab_hero_attributes';
private state: GameState;
constructor(state: GameState) {
super();
this.state = state;
}
@registerAction
export class GrabHeroAttributesAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
const healthElement = jQuery(
'#attributes .attribute.health .powervalue .value'

View File

@ -1,7 +1,6 @@
import ActionController from './ActionController';
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { Task } from '../Storage/TaskQueue';
import { GameState } from '../Storage/GameState';
import { trimPrefix } from '../utils';
import { AbortTaskError } from '../Errors';
@ -13,15 +12,8 @@ interface Adventure {
level: number;
}
export default class SendOnAdventureAction extends ActionController {
static NAME = 'send_on_adventure';
private state: GameState;
constructor(state: GameState) {
super();
this.state = state;
}
@registerAction
export class SendOnAdventureAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
const adventures = this.findAdventures();

View File

@ -1,11 +1,10 @@
import ActionController from './ActionController';
import { ActionController, registerAction } from './ActionController';
import { Args } from '../Common';
import { TryLaterError } from '../Errors';
import Scheduler from '../Scheduler';
import { Task } from '../Storage/TaskQueue';
export default class UpgradeBuildingAction extends ActionController {
static NAME = 'upgrade_building';
@registerAction
export class UpgradeBuildingAction extends ActionController {
async run(args: Args, task: Task): Promise<any> {
const btn = jQuery(
'.upgradeButtonsContainer .section1 button.green.build'