Description

Manages all superpowers for a single map instance. Provided in the map component's injector to allow a clean state for each initialized map component.

This service communicates with SuperpowersChargerService through the Superpowers token. SuperpowersChargerService registeres power types globally, and SuperpowersService instantiates them for the map it was created for.

Index

core/modules/map/superpowers/superpowers.service.ts

Methods
Accessors

Constructor

constructor(chargedPowers: ChargedSuperpowers, injector: Injector)

Creates an instance of SuperpowersService.

Parameters:
Name Type Optional Description
chargedPowers ChargedSuperpowers No

All the superpower types currently charged and known to the system.

injector Injector No

The instance of the injector service.

Methods

Public attachToMap
attachToMap(map: IGoogleMap)

Attaches all superpowers to the given map. Any lazy loaded superpowers registered after the call to attachToMap() will automatically attach to it as well.

Parameters:
Name Type Optional Description
map IGoogleMap No

The map to attach the superpowers to.

Returns: void
Public use
use(type: Type)
Type parameters:
  • T

Extracts a superpower by its type. The superpower must be previously registered using SuperpowersChargerService.charge(). Attempting to use unregistered superpowers will fail with an error.

Parameters:
Name Type Optional Description
type Type<T> No

The type of superpower being extracted.

Returns: T

The extracted superpower instance.

Accessors

count
getcount()

Counts the number of powers instantiated.

Returns: number
import { Injectable, Inject, Type, Injector } from '@angular/core';
import { Destroyable                        } from '@bespunky/angular-zen/core';

import { IGoogleMap                      } from '../i-google-map';
import { Superpowers, ChargedSuperpowers } from './superpowers.token';
import { ISuperpowers                    } from './i-superpowers';
import { ISuperpower                     } from './i-superpower';

/**
 * Manages all superpowers for a single map instance. Provided in the map component's injector to allow a clean state for each initialized map component.
 * 
 * This service communicates with `SuperpowersChargerService` through the `Superpowers` token.
 * `SuperpowersChargerService` registeres power types globally, and `SuperpowersService` instantiates them for the map it
 * was created for.
 */
@Injectable()
export class SuperpowersService extends Destroyable implements ISuperpowers
{
    private map   : IGoogleMap;
    private powers: { [type: string]: ISuperpower } = { };

    /**
     * Creates an instance of SuperpowersService.
     * 
     * @param {ChargedSuperpowers} chargedPowers All the superpower types currently charged and known to the system.
     * @param {Injector} injector The instance of the injector service.
     */
    constructor(@Inject(Superpowers) chargedPowers: ChargedSuperpowers, private injector: Injector)
    {
        super();

        this.subscribe(chargedPowers, this.load.bind(this));
    }

    /**
     * Instantiates a single superpower. If a map was already registered, the superpower will be attached to it.
     * Superpowers already registered will be ignored.
     *
     * @private
     * @param {Type<ISuperpower>} superpowerType The type of superpower to load.
     */
    private load(superpowerType: Type<ISuperpower>): void
    {
        const name = superpowerType.name;

        // Do not instantiate duplicate superpowers
        if (this.powers[name]) return;
        
        const power = this.injector.get(superpowerType);
        
        if (this.map)
            power.attach(this.map);

        this.powers[name] = power;
    }

    /**
     * Attaches all superpowers to the given map.
     * Any lazy loaded superpowers registered after the call to `attachToMap()` will automatically attach to it as well.
     *
     * @param {IGoogleMap} map The map to attach the superpowers to.
     */
    public attachToMap(map: IGoogleMap): void
    {
        this.map = map;

        Object.keys(this.powers).forEach(name => this.powers[name].attach(map));
    }
    
    /**
     * Extracts a superpower by its type. The superpower must be previously registered using `SuperpowersChargerService.charge()`.
     * Attempting to use unregistered superpowers will fail with an error.
     *
     * @template T The type of superpower being extracted.
     * @param {Type<T>} type The type of superpower being extracted.
     * @returns {T} The extracted superpower instance.
     */
    public use<T extends ISuperpower>(type: Type<T>): T
    {
        const power = this.powers[type.name] as T;

        if (!power)
            throw new Error(`
                Attempted to use superpower ${type.name}, which hasn't been registered yet.\n
                If ${type.name} is a custom superpower, make sure you call '<SuperpowersChargerService>.charge(${type.name})'.\n
                Otherwise, make sure you imported the relevant module (does ${type.name} belong to a lazy loaded module?).
            `);
        
        return power;
    }

    /**
     * Counts the number of powers instantiated.
     *
     * @readonly
     * @type {number}
     */
    public get count(): number
    {
        return Object.keys(this.powers).length;
    }
}

results matching ""

    No results matching ""