All files commandLibrary.ts

100% Statements 38/38
80% Branches 12/15
100% Functions 11/11
100% Lines 38/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117                                                                                                                    1x 1x   1x   1x 1x 1x         1x 22x 1x 1x 22x 22x   1x 27x 27x     1x 9x 9x 9x   9x 9x 9x     1x 1x 1x     1x 14x 14x     1x 3x 3x     1x 5x 5x     1x 9x 9x 1x  
/**
 * Represents a voice-activated command that can trigger game actions.
 * 
 * @interface GameCommand
 * @example
 * ```typescript
 * const jumpCommand: GameCommand = {
 *   name: "jump",
 *   action: () => player.jump(),
 *   description: "Makes the player character jump",
 *   active: true
 * };
 * ```
 */
export interface GameCommand {
    /**
     * The name/trigger phrase for the command.
     * This is the word or phrase that will be recognized to trigger the action.
     * 
     * @type {string}
     * @example "jump", "move left", "fire weapon"
     */
    name: string;
 
    /**
     * The callback function to execute when this command is triggered.
     * This function contains the game logic that should run when the voice command is recognized.
     * 
     * @type {() => void}
     * @example () => player.jump()
     */
    action: () => void;
 
    /**
     * A human-readable description of what this command does.
     * Used for documentation, help menus, or accessibility features.
     * 
     * @type {string}
     * @example "Makes the player character jump into the air"
     */
    description: string;
 
    /**
     * Whether this command is currently enabled and can be triggered.
     * Inactive commands will not respond to voice input.
     * 
     * @type {boolean}
     * @default true
     */
    active: boolean;
}
 
/**
 * CommandLibrary contains a HashMap that:
 * Can be called by CommandMapper.
 * Maps a String command to the corresponding GameCommand.
*/
 
export class CommandLibrary {
    private commandMap: Map<string, GameCommand>;
 
    private static instance: CommandLibrary;
 
    constructor() {
        this.commandMap = new Map<string, GameCommand>();
    }
    
    /**
     * @returns The singleton instance of CommandLibrary.
     */
    public static getInstance(): CommandLibrary {
        if (!CommandLibrary.instance) {
            CommandLibrary.instance = new CommandLibrary();
        }
        return CommandLibrary.instance;
    }
 
    private normalize(name: string): string {
        return name.toLowerCase().trim();
    }
 
    /** Add a command (returns false if name already exists) */
    public add(command: GameCommand): boolean {
        const key = this.normalize(command.name);
        if (!key) return false;
        if (this.commandMap.has(key)) return false;
        // store normalized name internally
        this.commandMap.set(key, { ...command, name: key, active: command.active ?? true });
        return true;
    }
 
    /** Remove a command by name */
    public remove(name: string): boolean {
        return this.commandMap.delete(this.normalize(name));
    }
 
    /** Check if a command exists */
    public has(name: string): boolean {
        return this.commandMap.has(this.normalize(name));
    }
 
    /** Get a command by name */
    public get(name: string): GameCommand | undefined {
        return this.commandMap.get(this.normalize(name));
    }
 
    /** List all commands */
    public list(): GameCommand[] {
        return Array.from(this.commandMap.values());
    }
 
    /** Clear all commands */
    public clear(): void {
        this.commandMap.clear();
    }
}