Skip to content

Commit

Permalink
refact(skymp5-client): separate KeyboardEventsService (skyrim-multipl…
Browse files Browse the repository at this point in the history
  • Loading branch information
Pospelove authored Aug 11, 2024
1 parent 5815d9d commit 0c82198
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 33 deletions.
4 changes: 3 additions & 1 deletion skymp5-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { GamemodeUpdateService } from "./services/services/gamemodeUpdateService
import { FrontHotReloadService } from "./services/services/frontHotReloadService";
import { BlockedAnimationsService } from "./services/services/blockedAnimationsService";
import { WorldView } from "./view/worldView";
import { KeyboardEventsService } from "./services/services/keyboardEventsService";

once("update", () => {
Utility.setINIBool("bAlwaysActive:General", true);
Expand Down Expand Up @@ -99,7 +100,8 @@ const main = () => {
new GamemodeUpdateService(sp, controller),
new FrontHotReloadService(sp, controller),
new BlockedAnimationsService(sp, controller),
new WorldView(sp, controller)
new WorldView(sp, controller),
new KeyboardEventsService(sp, controller)
];
SpApiInteractor.setup(listeners);
}
Expand Down
4 changes: 3 additions & 1 deletion skymp5-client/src/services/events/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { AuthAttemptEvent } from "./authAttemptEvent";
import { NewLocalLagValueCalculatedEvent } from "./newLocalLagValueCalculatedEvent";
import { AuthNeededEvent } from "./authNeededEvent";
import { QueryBlockSetInventoryEvent } from "./queryBlockSetInventoryEvent";
import { QueryKeyCodeBindings } from "./queryKeyCodeBindings";

type EventTypes = {
'gameLoad': [GameLoadEvent],
Expand Down Expand Up @@ -72,7 +73,8 @@ type EventTypes = {
'authNeeded': [AuthNeededEvent],
'anyMessage': [ConnectionMessage<AnyMessage>],
'newLocalLagValueCalculated': [NewLocalLagValueCalculatedEvent],
'queryBlockSetInventoryEvent': [QueryBlockSetInventoryEvent]
'queryBlockSetInventoryEvent': [QueryBlockSetInventoryEvent],
'queryKeyCodeBindings': [QueryKeyCodeBindings]
}

// https://blog.makerx.com.au/a-type-safe-event-emitter-in-node-js/
Expand Down
5 changes: 5 additions & 0 deletions skymp5-client/src/services/events/queryKeyCodeBindings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { DxScanCode } from "@skyrim-platform/skyrim-platform";

export interface QueryKeyCodeBindings {
isDown: (binding: DxScanCode[]) => boolean;
}
56 changes: 25 additions & 31 deletions skymp5-client/src/services/services/browserService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

// TODO: send event instead of direct dependency on FormView class
import { FormView } from "../../view/formView";
import { QueryKeyCodeBindings } from "../events/queryKeyCodeBindings";

import { ClientListener, CombinedController, Sp } from "./clientListener";
import { BrowserMessageEvent, DxScanCode, Menu, MenuCloseEvent, MenuOpenEvent } from "skyrimPlatform";
Expand All @@ -11,27 +12,38 @@ export class BrowserService extends ClientListener {

this.sp.browser.setVisible(false);

this.controller.emitter.on("queryKeyCodeBindings", (e) => this.onQueryKeyCodeBindings(e));
this.controller.once("update", () => this.onceUpdate());
this.controller.on("update", () => this.onUpdate());
this.controller.on("browserMessage", (e) => this.onBrowserMessage(e));
this.controller.on("menuOpen", (e) => this.onMenuOpen(e));
this.controller.on("menuClose", (e) => this.onMenuClose(e));
}

private onceUpdate() {
this.sp.browser.setVisible(true);
// TODO: keycodes should be configurable
private onQueryKeyCodeBindings(e: QueryKeyCodeBindings) {
if (e.isDown([DxScanCode.F1])) {
FormView.isDisplayingNicknames = !FormView.isDisplayingNicknames;
}
if (e.isDown([DxScanCode.F2])) {
this.sp.browser.setVisible(!this.sp.browser.isVisible());
}
if (e.isDown([DxScanCode.F6])) {
this.sp.browser.setFocused(!this.sp.browser.isFocused());
}
if (e.isDown([DxScanCode.Enter])) {
if (this.badMenusOpen.size === 0) {
this.sp.browser.setFocused(true);
}
}
if (e.isDown([DxScanCode.Escape])) {
if (this.sp.browser.isFocused()) {
this.sp.browser.setFocused(false);
}
}
}

private onUpdate() {
const numKeys = this.sp.Input.getNumKeysPressed();

if (this.lastNumKeys === numKeys) return;

this.lastNumKeys = numKeys;

this.binding.forEach((fn, keyCodes) => {
if (keyCodes.every((key) => this.sp.Input.isKeyPressed(key))) fn();
});
private onceUpdate() {
this.sp.browser.setVisible(true);
}

private onBrowserMessage(e: BrowserMessageEvent) {
Expand Down Expand Up @@ -67,26 +79,8 @@ export class BrowserService extends ClientListener {
return this.badMenus.includes(menu as Menu);
}

private lastNumKeys = 0;

private badMenusOpen = new Set<string>();

// TODO: keycodes should be configurable
private binding = new Map<DxScanCode[], () => void>([
[[DxScanCode.F1], () => FormView.isDisplayingNicknames = !FormView.isDisplayingNicknames],
[[DxScanCode.F2], () => this.sp.browser.setVisible(!this.sp.browser.isVisible())],
[[DxScanCode.F6], () => this.sp.browser.setFocused(!this.sp.browser.isFocused())],
[[DxScanCode.Enter], () => {
if (this.badMenusOpen.size === 0) {
this.sp.browser.setFocused(true);
}
}],
[
[DxScanCode.Escape],
() => this.sp.browser.isFocused() && this.sp.browser.setFocused(false),
],
]);

private readonly badMenus: Menu[] = [
Menu.Barter,
Menu.Book,
Expand Down
30 changes: 30 additions & 0 deletions skymp5-client/src/services/services/keyboardEventsService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

import { DxScanCode } from "@skyrim-platform/skyrim-platform";
import { Sp, CombinedController, ClientListener } from "./clientListener";

export class KeyboardEventsService extends ClientListener {
constructor(private sp: Sp, private controller: CombinedController) {
super();

controller.on("update", () => this.onUpdate());
}

private onUpdate() {
const numKeys = this.sp.Input.getNumKeysPressed();

if (this.lastNumKeys !== numKeys) {
this.lastNumKeys = numKeys;
}

this.controller.emitter.emit("queryKeyCodeBindings", {
isDown: (binding: DxScanCode[]) => {
if (binding.every((key) => this.sp.Input.isKeyPressed(key))) {
return true;
}
return false;
}
});
}

private lastNumKeys = 0;
};

0 comments on commit 0c82198

Please sign in to comment.