import { AbilityType, Actor, isAbilityFactory } from './actor'; /** * Type definition for question interactions. */ export interface QuestionInteraction
{ invoke(param: P, assert: (answer: R) => void): void; } /** * Type definition for questions. * * An question is a list of interactions that accept a parameter of type P and * and accept an assertion callback of type R. */ type QuestionType
= { new (actor: Actor): QuestionInteraction
}; export type Question
= QuestionType
| QuestionType
[];
export type QuestionProcedure = (
ability: AbilityType,
param: P,
assert: (answer: R) => void,
) => void;
/**
* Shorthand for creating questions using a specific ability.
*
* @param ability
* A constructor for an ability service.
* @param procedure
* The procedure to answer this question.
*/
export function createQuestion(
ability: { new (): A },
procedure: QuestionProcedure,
) {
return class implements QuestionInteraction {
/**
* A ability service object to invoke commands on.
*/
public ability?: A;
/**
* An actor to perform sub-tasks.
*/
public actor?: Actor;
constructor(actor: Actor) {
this.actor = actor;
this.ability = actor.ability(ability);
}
invoke(param: P, assert: (answer: R) => void): void {
if (this.ability) {
procedure(
isAbilityFactory(this.ability) ? this.ability.create() : this.ability,
param,
assert,
);
}
}
};
}