|
|
|
/* typehints:start */
|
|
|
|
import { Application } from "../application";
|
|
|
|
import { InputReceiver } from "./input_receiver";
|
|
|
|
/* typehints:end */
|
|
|
|
|
|
|
|
import { Signal, STOP_PROPAGATION } from "./signal";
|
|
|
|
import { createLogger } from "./logging";
|
|
|
|
import { arrayDeleteValue, fastArrayDeleteValue } from "./utils";
|
|
|
|
|
|
|
|
const logger = createLogger("input_distributor");
|
|
|
|
|
|
|
|
export class InputDistributor {
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param {Application} app
|
|
|
|
*/
|
|
|
|
constructor(app) {
|
|
|
|
this.app = app;
|
|
|
|
|
|
|
|
/** @type {Array<InputReceiver>} */
|
|
|
|
this.recieverStack = [];
|
|
|
|
|
|
|
|
/** @type {Array<function(any) : boolean>} */
|
|
|
|
this.filters = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* All keys which are currently down
|
|
|
|
*/
|
|
|
|
this.keysDown = new Set();
|
|
|
|
|
|
|
|
this.bindToEvents();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Attaches a new filter which can filter and reject events
|
|
|
|
* @param {function(any): boolean} filter
|
|
|
|
*/
|
|
|
|
installFilter(filter) {
|
|
|
|
this.filters.push(filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes an attached filter
|
|
|
|
* @param {function(any) : boolean} filter
|
|
|
|
*/
|
|
|
|
dismountFilter(filter) {
|
|
|
|
fastArrayDeleteValue(this.filters, filter);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {InputReceiver} reciever
|
|
|
|
*/
|
|
|
|
pushReciever(reciever) {
|
|
|
|
if (this.isRecieverAttached(reciever)) {
|
|
|
|
assert(false, "Can not add reciever " + reciever.context + " twice");
|
|
|
|
logger.error("Can not add reciever", reciever.context, "twice");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.recieverStack.push(reciever);
|
|
|
|
|
|
|
|
if (this.recieverStack.length > 10) {
|
|
|
|
logger.error(
|
|
|
|
"Reciever stack is huge, probably some dead receivers arround:",
|
|
|
|
this.recieverStack.map(x => x.context)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {InputReceiver} reciever
|
|
|
|
*/
|
|
|
|
popReciever(reciever) {
|
|
|
|
if (this.recieverStack.indexOf(reciever) < 0) {
|
|
|
|
assert(false, "Can not pop reciever " + reciever.context + " since its not contained");
|
|
|
|
logger.error("Can not pop reciever", reciever.context, "since its not contained");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.recieverStack[this.recieverStack.length - 1] !== reciever) {
|
|
|
|
logger.warn(
|
|
|
|
"Popping reciever",
|
|
|
|
reciever.context,
|
|
|
|
"which is not on top of the stack. Stack is: ",
|
|
|
|
this.recieverStack.map(x => x.context)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
arrayDeleteValue(this.recieverStack, reciever);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {InputReceiver} reciever
|
|
|
|
*/
|
|
|
|
isRecieverAttached(reciever) {
|
|
|
|
return this.recieverStack.indexOf(reciever) >= 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {InputReceiver} reciever
|
|
|
|
*/
|
|
|
|
isRecieverOnTop(reciever) {
|
|
|
|
return (
|
|
|
|
this.isRecieverAttached(reciever) &&
|
|
|
|
this.recieverStack[this.recieverStack.length - 1] === reciever
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {InputReceiver} reciever
|
|
|
|
*/
|
|
|
|
makeSureAttachedAndOnTop(reciever) {
|
|
|
|
this.makeSureDetached(reciever);
|
|
|
|
this.pushReciever(reciever);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {InputReceiver} reciever
|
|
|
|
*/
|
|
|
|
makeSureDetached(reciever) {
|
|
|
|
if (this.isRecieverAttached(reciever)) {
|
|
|
|
arrayDeleteValue(this.recieverStack, reciever);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param {InputReceiver} reciever
|
|
|
|
*/
|
|
|
|
destroyReceiver(reciever) {
|
|
|
|
this.makeSureDetached(reciever);
|
|
|
|
reciever.cleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Internal
|
|
|
|
|
|
|
|
getTopReciever() {
|
|
|
|
if (this.recieverStack.length > 0) {
|
|
|
|
return this.recieverStack[this.recieverStack.length - 1];
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
bindToEvents() {
|
|
|
|
window.addEventListener("popstate", this.handleBackButton.bind(this), false);
|
|
|
|
document.addEventListener("backbutton", this.handleBackButton.bind(this), false);
|
|
|
|
|
|
|
|
window.addEventListener("keydown", this.handleKeyMouseDown.bind(this));
|
|
|
|
window.addEventListener("keyup", this.handleKeyMouseUp.bind(this));
|
|
|
|
|
|
|
|
window.addEventListener("mousedown", this.handleKeyMouseDown.bind(this));
|
|
|
|
window.addEventListener("mouseup", this.handleKeyMouseUp.bind(this));
|
|
|
|
|
|
|
|
window.addEventListener("blur", this.handleBlur.bind(this));
|
Mod Support - 1.5.0 Update (#1361)
* initial modloader draft
* modloader features
* Refactor mods to use signals
* Add support for modifying and registering new transltions
* Minor adjustments
* Support for string building ids for mods
* Initial support for adding new buildings
* Refactor how mods are loaded to resolve circular dependencies and prepare for future mod loading
* Lazy Load mods to make sure all dependencies are loaded
* Expose all exported members automatically to mods
* Fix duplicate exports
* Allow loading mods from standalone
* update changelog
* Fix mods folder incorrect path
* Fix modloading in standalone
* Fix sprites not getting replaced, update demo mod
* Load dev mod via raw loader
* Improve mod developing so mods are directly ready to be deployed, load mods from local file server
* Proper mods ui
* Allow mods to register game systems and draw stuff
* Change mods path
* Fix sprites not loading
* Minor adjustments, closes #1333
* Add support for loading atlases via mods
* Add support for loading mods from external sources in DEV
* Add confirmation when loading mods
* Fix circular dependency
* Minor Keybindings refactor, add support for keybindings to mods, add support for dialogs to mods
* Add some mod signals
* refactor game loading states
* Make shapez exports global
* Start to make mods safer
* Refactor file system electron event handling
* Properly isolate electron renderer process
* Update to latest electron
* Show errors when loading mods
* Update confirm dialgo
* Minor restructure, start to add mod examples
* Allow adding custom themesw
* Add more examples and allow defining custom item processor operations
* Add interface to register new buildings
* Fixed typescript type errors (#1335)
* Refactor building registry, make it easier for mods to add new buildings
* Allow overriding existing methods
* Add more examples and more features
* More mod examples
* Make mod loading simpler
* Add example how to add custom drawings
* Remove unused code
* Minor modloader adjustments
* Support for rotation variants in mods (was broken previously)
* Allow mods to replace builtin sub shapes
* Add helper methods to extend classes
* Fix menu bar on mac os
* Remember window state
* Add support for paste signals
* Add example how to add custom components and systems
* Support for mod settings
* Add example for adding a new item type
* Update class extensions
* Minor adjustments
* Fix typo
* Add notification blocks mod example
* Add small tutorial
* Update readme
* Add better instructions
* Update JSDoc for Replacing Methods (#1336)
* upgraded types for overriding methods
* updated comments
Co-authored-by: Edward Badel <you@example.com>
* Direction lock now indicates when there is a building inbetween
* Fix mod examples
* Fix linter error
* Game state register (#1341)
* Added a gamestate register helper
Added a gamestate register helper
* Update mod_interface.js
* export build options
* Fix runBeforeMethod and runAfterMethod
* Minor game system code cleanup
* Belt path drawing optimization
* Fix belt path optimization
* Belt drawing improvements, again
* Do not render belts in statics disabled view
* Allow external URL to load more than one mod (#1337)
* Allow external URL to load more than one mod
Instead of loading the text returned from the remote server, load a JSON object with a `mods` field, containing strings of all the mods. This lets us work on more than one mod at a time or without separate repos. This will break tooling such as `create-shapezio-mod` though.
* Update modloader.js
* Prettier fixes
* Added link to create-shapezio-mod npm page (#1339)
Added link to create-shapezio-mod npm page: https://www.npmjs.com/package/create-shapezio-mod
* allow command line switch to load more than one mod (#1342)
* Fixed class handle type (#1345)
* Fixed class handle type
* Fixed import game state
* Minor adjustments
* Refactor item acceptor to allow only single direction slots
* Allow specifying minimumGameVersion
* Add sandbox example
* Replaced concatenated strings with template literals (#1347)
* Mod improvements
* Make wired pins component optional on the storage
* Fix mod examples
* Bind `this` for method overriding JSDoc (#1352)
* fix entity debugger reaching HTML elements (#1353)
* Store mods in savegame and show warning when it differs
* Closes #1357
* Fix All Shapez Exports Being Const (#1358)
* Allowed setting of variables inside webpack modules
* remove console log
* Fix stringification of things inside of eval
Co-authored-by: Edward Badel <you@example.com>
* Fix building placer intersection warning
* Add example for storing data in the savegame
* Fix double painter bug (#1349)
* Add example on how to extend builtin buildings
* update readme
* Disable steam achievements when playing with mods
* Update translations
Co-authored-by: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com>
Co-authored-by: Bagel03 <70449196+Bagel03@users.noreply.github.com>
Co-authored-by: Edward Badel <you@example.com>
Co-authored-by: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com>
Co-authored-by: saile515 <63782477+saile515@users.noreply.github.com>
Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
2 years ago
|
|
|
|
|
|
|
document.addEventListener("paste", this.handlePaste.bind(this));
|
|
|
|
}
|
|
|
|
|
|
|
|
forwardToReceiver(eventId, payload = null) {
|
|
|
|
// Check filters
|
|
|
|
for (let i = 0; i < this.filters.length; ++i) {
|
|
|
|
if (!this.filters[i](eventId)) {
|
|
|
|
return STOP_PROPAGATION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const reciever = this.getTopReciever();
|
|
|
|
if (!reciever) {
|
|
|
|
logger.warn("Dismissing event because not reciever was found:", eventId);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const signal = reciever[eventId];
|
|
|
|
assert(signal instanceof Signal, "Not a valid event id");
|
|
|
|
return signal.dispatch(payload);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {Event} event
|
|
|
|
*/
|
|
|
|
handleBackButton(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
this.forwardToReceiver("backButton");
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles when the page got blurred
|
|
|
|
*/
|
|
|
|
handleBlur() {
|
|
|
|
this.forwardToReceiver("pageBlur", {});
|
|
|
|
this.keysDown.clear();
|
|
|
|
}
|
|
|
|
|
Mod Support - 1.5.0 Update (#1361)
* initial modloader draft
* modloader features
* Refactor mods to use signals
* Add support for modifying and registering new transltions
* Minor adjustments
* Support for string building ids for mods
* Initial support for adding new buildings
* Refactor how mods are loaded to resolve circular dependencies and prepare for future mod loading
* Lazy Load mods to make sure all dependencies are loaded
* Expose all exported members automatically to mods
* Fix duplicate exports
* Allow loading mods from standalone
* update changelog
* Fix mods folder incorrect path
* Fix modloading in standalone
* Fix sprites not getting replaced, update demo mod
* Load dev mod via raw loader
* Improve mod developing so mods are directly ready to be deployed, load mods from local file server
* Proper mods ui
* Allow mods to register game systems and draw stuff
* Change mods path
* Fix sprites not loading
* Minor adjustments, closes #1333
* Add support for loading atlases via mods
* Add support for loading mods from external sources in DEV
* Add confirmation when loading mods
* Fix circular dependency
* Minor Keybindings refactor, add support for keybindings to mods, add support for dialogs to mods
* Add some mod signals
* refactor game loading states
* Make shapez exports global
* Start to make mods safer
* Refactor file system electron event handling
* Properly isolate electron renderer process
* Update to latest electron
* Show errors when loading mods
* Update confirm dialgo
* Minor restructure, start to add mod examples
* Allow adding custom themesw
* Add more examples and allow defining custom item processor operations
* Add interface to register new buildings
* Fixed typescript type errors (#1335)
* Refactor building registry, make it easier for mods to add new buildings
* Allow overriding existing methods
* Add more examples and more features
* More mod examples
* Make mod loading simpler
* Add example how to add custom drawings
* Remove unused code
* Minor modloader adjustments
* Support for rotation variants in mods (was broken previously)
* Allow mods to replace builtin sub shapes
* Add helper methods to extend classes
* Fix menu bar on mac os
* Remember window state
* Add support for paste signals
* Add example how to add custom components and systems
* Support for mod settings
* Add example for adding a new item type
* Update class extensions
* Minor adjustments
* Fix typo
* Add notification blocks mod example
* Add small tutorial
* Update readme
* Add better instructions
* Update JSDoc for Replacing Methods (#1336)
* upgraded types for overriding methods
* updated comments
Co-authored-by: Edward Badel <you@example.com>
* Direction lock now indicates when there is a building inbetween
* Fix mod examples
* Fix linter error
* Game state register (#1341)
* Added a gamestate register helper
Added a gamestate register helper
* Update mod_interface.js
* export build options
* Fix runBeforeMethod and runAfterMethod
* Minor game system code cleanup
* Belt path drawing optimization
* Fix belt path optimization
* Belt drawing improvements, again
* Do not render belts in statics disabled view
* Allow external URL to load more than one mod (#1337)
* Allow external URL to load more than one mod
Instead of loading the text returned from the remote server, load a JSON object with a `mods` field, containing strings of all the mods. This lets us work on more than one mod at a time or without separate repos. This will break tooling such as `create-shapezio-mod` though.
* Update modloader.js
* Prettier fixes
* Added link to create-shapezio-mod npm page (#1339)
Added link to create-shapezio-mod npm page: https://www.npmjs.com/package/create-shapezio-mod
* allow command line switch to load more than one mod (#1342)
* Fixed class handle type (#1345)
* Fixed class handle type
* Fixed import game state
* Minor adjustments
* Refactor item acceptor to allow only single direction slots
* Allow specifying minimumGameVersion
* Add sandbox example
* Replaced concatenated strings with template literals (#1347)
* Mod improvements
* Make wired pins component optional on the storage
* Fix mod examples
* Bind `this` for method overriding JSDoc (#1352)
* fix entity debugger reaching HTML elements (#1353)
* Store mods in savegame and show warning when it differs
* Closes #1357
* Fix All Shapez Exports Being Const (#1358)
* Allowed setting of variables inside webpack modules
* remove console log
* Fix stringification of things inside of eval
Co-authored-by: Edward Badel <you@example.com>
* Fix building placer intersection warning
* Add example for storing data in the savegame
* Fix double painter bug (#1349)
* Add example on how to extend builtin buildings
* update readme
* Disable steam achievements when playing with mods
* Update translations
Co-authored-by: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com>
Co-authored-by: Bagel03 <70449196+Bagel03@users.noreply.github.com>
Co-authored-by: Edward Badel <you@example.com>
Co-authored-by: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com>
Co-authored-by: saile515 <63782477+saile515@users.noreply.github.com>
Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
2 years ago
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
handlePaste(ev) {
|
|
|
|
this.forwardToReceiver("paste", ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {KeyboardEvent | MouseEvent} event
|
|
|
|
*/
|
|
|
|
handleKeyMouseDown(event) {
|
|
|
|
const keyCode = event instanceof MouseEvent ? event.button + 1 : event.keyCode;
|
|
|
|
if (
|
|
|
|
keyCode === 4 || // MB4
|
|
|
|
keyCode === 5 || // MB5
|
|
|
|
keyCode === 9 || // TAB
|
|
|
|
keyCode === 16 || // SHIFT
|
|
|
|
keyCode === 17 || // CTRL
|
|
|
|
keyCode === 18 || // ALT
|
|
|
|
(keyCode >= 112 && keyCode < 122) // F1 - F10
|
|
|
|
) {
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
|
|
|
|
|
|
|
const isInitial = !this.keysDown.has(keyCode);
|
|
|
|
this.keysDown.add(keyCode);
|
|
|
|
|
|
|
|
if (
|
|
|
|
this.forwardToReceiver("keydown", {
|
|
|
|
keyCode: keyCode,
|
|
|
|
shift: event.shiftKey,
|
|
|
|
alt: event.altKey,
|
Mod Support - 1.5.0 Update (#1361)
* initial modloader draft
* modloader features
* Refactor mods to use signals
* Add support for modifying and registering new transltions
* Minor adjustments
* Support for string building ids for mods
* Initial support for adding new buildings
* Refactor how mods are loaded to resolve circular dependencies and prepare for future mod loading
* Lazy Load mods to make sure all dependencies are loaded
* Expose all exported members automatically to mods
* Fix duplicate exports
* Allow loading mods from standalone
* update changelog
* Fix mods folder incorrect path
* Fix modloading in standalone
* Fix sprites not getting replaced, update demo mod
* Load dev mod via raw loader
* Improve mod developing so mods are directly ready to be deployed, load mods from local file server
* Proper mods ui
* Allow mods to register game systems and draw stuff
* Change mods path
* Fix sprites not loading
* Minor adjustments, closes #1333
* Add support for loading atlases via mods
* Add support for loading mods from external sources in DEV
* Add confirmation when loading mods
* Fix circular dependency
* Minor Keybindings refactor, add support for keybindings to mods, add support for dialogs to mods
* Add some mod signals
* refactor game loading states
* Make shapez exports global
* Start to make mods safer
* Refactor file system electron event handling
* Properly isolate electron renderer process
* Update to latest electron
* Show errors when loading mods
* Update confirm dialgo
* Minor restructure, start to add mod examples
* Allow adding custom themesw
* Add more examples and allow defining custom item processor operations
* Add interface to register new buildings
* Fixed typescript type errors (#1335)
* Refactor building registry, make it easier for mods to add new buildings
* Allow overriding existing methods
* Add more examples and more features
* More mod examples
* Make mod loading simpler
* Add example how to add custom drawings
* Remove unused code
* Minor modloader adjustments
* Support for rotation variants in mods (was broken previously)
* Allow mods to replace builtin sub shapes
* Add helper methods to extend classes
* Fix menu bar on mac os
* Remember window state
* Add support for paste signals
* Add example how to add custom components and systems
* Support for mod settings
* Add example for adding a new item type
* Update class extensions
* Minor adjustments
* Fix typo
* Add notification blocks mod example
* Add small tutorial
* Update readme
* Add better instructions
* Update JSDoc for Replacing Methods (#1336)
* upgraded types for overriding methods
* updated comments
Co-authored-by: Edward Badel <you@example.com>
* Direction lock now indicates when there is a building inbetween
* Fix mod examples
* Fix linter error
* Game state register (#1341)
* Added a gamestate register helper
Added a gamestate register helper
* Update mod_interface.js
* export build options
* Fix runBeforeMethod and runAfterMethod
* Minor game system code cleanup
* Belt path drawing optimization
* Fix belt path optimization
* Belt drawing improvements, again
* Do not render belts in statics disabled view
* Allow external URL to load more than one mod (#1337)
* Allow external URL to load more than one mod
Instead of loading the text returned from the remote server, load a JSON object with a `mods` field, containing strings of all the mods. This lets us work on more than one mod at a time or without separate repos. This will break tooling such as `create-shapezio-mod` though.
* Update modloader.js
* Prettier fixes
* Added link to create-shapezio-mod npm page (#1339)
Added link to create-shapezio-mod npm page: https://www.npmjs.com/package/create-shapezio-mod
* allow command line switch to load more than one mod (#1342)
* Fixed class handle type (#1345)
* Fixed class handle type
* Fixed import game state
* Minor adjustments
* Refactor item acceptor to allow only single direction slots
* Allow specifying minimumGameVersion
* Add sandbox example
* Replaced concatenated strings with template literals (#1347)
* Mod improvements
* Make wired pins component optional on the storage
* Fix mod examples
* Bind `this` for method overriding JSDoc (#1352)
* fix entity debugger reaching HTML elements (#1353)
* Store mods in savegame and show warning when it differs
* Closes #1357
* Fix All Shapez Exports Being Const (#1358)
* Allowed setting of variables inside webpack modules
* remove console log
* Fix stringification of things inside of eval
Co-authored-by: Edward Badel <you@example.com>
* Fix building placer intersection warning
* Add example for storing data in the savegame
* Fix double painter bug (#1349)
* Add example on how to extend builtin buildings
* update readme
* Disable steam achievements when playing with mods
* Update translations
Co-authored-by: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com>
Co-authored-by: Bagel03 <70449196+Bagel03@users.noreply.github.com>
Co-authored-by: Edward Badel <you@example.com>
Co-authored-by: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com>
Co-authored-by: saile515 <63782477+saile515@users.noreply.github.com>
Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
2 years ago
|
|
|
ctrl: event.ctrlKey,
|
|
|
|
initial: isInitial,
|
|
|
|
event,
|
|
|
|
}) === STOP_PROPAGATION
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keyCode === 27) {
|
|
|
|
// Escape key
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
return this.forwardToReceiver("backButton");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param {KeyboardEvent | MouseEvent} event
|
|
|
|
*/
|
|
|
|
handleKeyMouseUp(event) {
|
|
|
|
const keyCode = event instanceof MouseEvent ? event.button + 1 : event.keyCode;
|
|
|
|
this.keysDown.delete(keyCode);
|
|
|
|
|
|
|
|
this.forwardToReceiver("keyup", {
|
|
|
|
keyCode: keyCode,
|
|
|
|
shift: event.shiftKey,
|
|
|
|
alt: event.altKey,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|