mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Add type hints to signals
This commit is contained in:
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,13 +44,16 @@ export class ProductionAnalytics {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ShapeDefinition} definition
|
||||
* @param {BaseItem} item
|
||||
*/
|
||||
onShapeProduced(definition) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new time slice
|
||||
|
@ -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)) {
|
||||
|
11
src/js/globals.d.ts
vendored
11
src/js/globals.d.ts
vendored
@ -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…
Reference in New Issue
Block a user