Add type hints to signals

pull/33/head
tobspr 4 years ago
parent ca3f4ff02a
commit cf5d776270

@ -8,7 +8,7 @@ export class Signal {
/**
* Adds a new signal listener
* @param {object} receiver
* @param {function} receiver
* @param {object} scope
*/
add(receiver, scope = null) {
@ -40,7 +40,7 @@ export class Signal {
/**
* Removes a receiver
* @param {object} receiver
* @param {function} receiver
*/
remove(receiver) {
let index = null;

@ -90,18 +90,6 @@ export class BaseHUDPart {
// Helpers
/**
* Calls closeMethod if an overlay is opened
* @param {function=} closeMethod
*/
closeOnOverlayOpen(closeMethod = null) {
this.root.hud.signals.overlayOpened.add(overlay => {
if (overlay !== this) {
(closeMethod || this.close).call(this);
}
}, this);
}
/**
* Helper method to construct a new click detector
* @param {Element} element The element to listen on

@ -16,6 +16,7 @@ import { IS_MOBILE } from "../../core/config";
import { HUDMassSelector } from "./parts/mass_selector";
import { HUDVignetteOverlay } from "./parts/vignette_overlay";
import { HUDStatistics } from "./parts/statistics";
import { MetaBuilding } from "../meta_building";
export class GameHUD {
/**
@ -29,10 +30,6 @@ export class GameHUD {
* Initializes the hud parts
*/
initialize() {
this.signals = {
overlayOpened: new Signal(/* overlay */),
};
this.parts = {
processingOverlay: new HUDProcessingOverlay(this.root),
@ -54,7 +51,7 @@ export class GameHUD {
};
this.signals = {
selectedPlacementBuildingChanged: new Signal(/* metaBuilding|null */),
selectedPlacementBuildingChanged: /** @type {TypedSignal<[MetaBuilding|null]>} */ (new Signal()),
};
if (!IS_MOBILE) {

@ -1,6 +1,8 @@
import { GameRoot } from "./root";
import { ShapeDefinition } from "./shape_definition";
import { globalConfig } from "../core/config";
import { BaseItem } from "./base_item";
import { ShapeItem } from "./items/shape_item";
/** @enum {string} */
export const enumAnalyticsDataSource = {
@ -27,7 +29,7 @@ export class ProductionAnalytics {
}
this.root.signals.shapeDelivered.add(this.onShapeDelivered, this);
this.root.signals.shapeProduced.add(this.onShapeProduced, this);
this.root.signals.itemProduced.add(this.onItemProduced, this);
this.lastAnalyticsSlice = 0;
}
@ -42,12 +44,15 @@ export class ProductionAnalytics {
}
/**
* @param {ShapeDefinition} definition
* @param {BaseItem} item
*/
onShapeProduced(definition) {
const key = definition.getHash();
const entry = this.history[enumAnalyticsDataSource.produced];
entry[entry.length - 1][key] = (entry[entry.length - 1][key] || 0) + 1;
onItemProduced(item) {
if (item instanceof ShapeItem) {
const definition = item.definition;
const key = definition.getHash();
const entry = this.history[enumAnalyticsDataSource.produced];
entry[entry.length - 1][key] = (entry[entry.length - 1][key] || 0) + 1;
}
}
/**

@ -28,6 +28,9 @@ import { PerlinNoise } from "../core/perlin_noise";
import { HubGoals } from "./hub_goals";
import { BufferMaintainer } from "../core/buffer_maintainer";
import { ProductionAnalytics } from "./production_analytics";
import { Entity } from "./entity";
import { ShapeDefinition } from "./shape_definition";
import { BaseItem } from "./base_item";
/* typehints:end */
const logger = createLogger("game/root");
@ -131,32 +134,32 @@ export class GameRoot {
this.signals = {
// Entities
entityAdded: new Signal(/* entity */),
entityGotNewComponent: new Signal(/* entity */),
entityQueuedForDestroy: new Signal(/* entity */),
entityDestroyed: new Signal(/* entity */),
entityAdded: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityGotNewComponent: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityQueuedForDestroy: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
entityDestroyed: /** @type {TypedSignal<[Entity]>} */ (new Signal()),
// Global
resized: new Signal(/* w, h */), // Game got resized,
readyToRender: new Signal(),
aboutToDestruct: new Signal(),
resized: /** @type {TypedSignal<[number, number]>} */ (new Signal()),
readyToRender: /** @type {TypedSignal<[]>} */ (new Signal()),
aboutToDestruct: /** @type {TypedSignal<[]>} */ new Signal(),
// Game Hooks
gameSaved: new Signal(), // Game got saved
gameRestored: new Signal(), // Game got restored
gameOver: new Signal(), // Game over
gameSaved: /** @type {TypedSignal<[]>} */ (new Signal()), // Game got saved
gameRestored: /** @type {TypedSignal<[]>} */ (new Signal()), // Game got restored
gameOver: /** @type {TypedSignal<[]>} */ (new Signal()), // Game over
storyGoalCompleted: new Signal(/* level, reward */),
upgradePurchased: new Signal(),
storyGoalCompleted: /** @type {TypedSignal<[number, string]>} */ (new Signal()),
upgradePurchased: /** @type {TypedSignal<[string]>} */ (new Signal()),
// Called right after game is initialized
postLoadHook: new Signal(),
postLoadHook: /** @type {TypedSignal<[]>} */ (new Signal()),
// Can be used to trigger an async task
performAsync: new Signal(),
performAsync: /** @type {TypedSignal<[function]>} */ (new Signal()),
shapeDelivered: new Signal(/* definition */),
shapeProduced: new Signal(/* definition */),
shapeDelivered: /** @type {TypedSignal<[ShapeDefinition]>} */ (new Signal()),
itemProduced: /** @type {TypedSignal<[BaseItem]>} */ (new Signal()),
};
// RNG's

@ -157,11 +157,9 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
item: new ShapeItem(cutDefinition1),
requiredSlot: 0,
});
this.root.signals.shapeProduced.dispatch(cutDefinition1);
}
if (!cutDefinition2.isEntirelyEmpty()) {
this.root.signals.shapeProduced.dispatch(cutDefinition2);
outItems.push({
item: new ShapeItem(cutDefinition2),
requiredSlot: 1,
@ -178,7 +176,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
const inputDefinition = inputItem.definition;
const rotatedDefinition = this.root.shapeDefinitionMgr.shapeActionRotateCW(inputDefinition);
this.root.signals.shapeProduced.dispatch(rotatedDefinition);
outItems.push({
item: new ShapeItem(rotatedDefinition),
});
@ -200,7 +197,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
lowerItem.definition,
upperItem.definition
);
this.root.signals.shapeProduced.dispatch(stackedDefinition);
outItems.push({
item: new ShapeItem(stackedDefinition),
});
@ -253,7 +249,6 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
colorItem.color
);
this.root.signals.shapeProduced.dispatch(colorizedDefinition);
outItems.push({
item: new ShapeItem(colorizedDefinition),
});
@ -277,6 +272,11 @@ export class ItemProcessorSystem extends GameSystemWithFilter {
assertAlways(false, "Unkown item processor type: " + processorComp.type);
}
// Track produced items
for (let i = 0; i < outItems.length; ++i) {
this.root.signals.itemProduced.dispatch(outItems[i].item);
}
processorComp.itemsToEject = outItems;
}

@ -38,9 +38,7 @@ export class MinerSystem extends GameSystemWithFilter {
}
// Analytics hook
if (lowerLayerItem instanceof ShapeItem) {
this.root.signals.shapeProduced.dispatch(lowerLayerItem.definition);
}
this.root.signals.itemProduced.dispatch(lowerLayerItem);
// Try actually ejecting
if (!ejectComp.tryEject(0, lowerLayerItem)) {

@ -193,3 +193,14 @@ declare class TypedTrackedState<T> {
setSilent(value: any): void;
get(): T;
}
declare const STOP_PROPAGATION = "stop_propagation";
declare interface TypedSignal<T extends Array<any>> {
add(receiver: (...args: T) => typeof STOP_PROPAGATION | void, scope?: object);
remove(receiver: (...args: T) => typeof STOP_PROPAGATION | void);
dispatch(...args: T): typeof STOP_PROPAGATION | void;
removeAll();
}

@ -92,7 +92,7 @@ export class InGameState extends GameState {
getThemeMusic() {
// set later
return MUSIC.gameBg;
return MUSIC.mainMenu;
}
onBeforeExit() {
@ -115,7 +115,7 @@ export class InGameState extends GameState {
}
getPauseOnFocusLost() {
return !this.isMultiplayer();
return false;
}
getHasUnloadConfirmation() {
@ -407,7 +407,6 @@ export class InGameState extends GameState {
return;
if (!this.savegame || !this.savegame.isSaveable()) {
// Can not save in multiplayer
return Promise.resolve();
}

Loading…
Cancel
Save