diff --git a/electron/src/components/keymap/edit/keymap-edit.component.ts b/electron/src/components/keymap/edit/keymap-edit.component.ts index 882393d6..bb115d3e 100644 --- a/electron/src/components/keymap/edit/keymap-edit.component.ts +++ b/electron/src/components/keymap/edit/keymap-edit.component.ts @@ -8,6 +8,7 @@ import 'rxjs/add/operator/do'; import 'rxjs/add/operator/first'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/switchMap'; +import 'rxjs/add/operator/withLatestFrom'; import { Keymap } from '../../../shared/config-serializer/config-items/keymap'; import { UhkBuffer } from '../../../shared/config-serializer/uhk-buffer'; @@ -16,6 +17,7 @@ import { SvgKeyboardWrapComponent } from '../../../shared/components/svg/wrap'; import { KeymapEditComponent as SharedKeymapEditComponent } from '../../../shared/components/keymap/edit'; import { UhkDeviceService } from '../../../services/uhk-device.service'; +import { getUserConfiguration } from '../../../shared/store/reducers/user-configuration'; @Component({ selector: 'keymap-edit', @@ -58,9 +60,10 @@ export class KeymapEditComponent extends SharedKeymapEditComponent { this.keymap$ .first() .map(keymap => keymap.layers[currentLayer]) - .map(layer => { + .withLatestFrom(this.store.let(getUserConfiguration())) + .map(([layer, userConfig]) => { const uhkBuffer = new UhkBuffer(); - layer.toBinary(uhkBuffer); + layer.toBinary(uhkBuffer, userConfig); return uhkBuffer.getBufferContent(); }) .switchMap((buffer: Buffer) => this.uhkDevice.sendConfig(buffer)) @@ -76,9 +79,10 @@ export class KeymapEditComponent extends SharedKeymapEditComponent { private sendKeymap(): void { this.keymap$ .first() - .map(keymap => { + .withLatestFrom(this.store.let(getUserConfiguration())) + .map(([keymap, userConfig]) => { const uhkBuffer = new UhkBuffer(); - keymap.toBinary(uhkBuffer); + keymap.toBinary(uhkBuffer, userConfig); return uhkBuffer.getBufferContent(); }) .switchMap((buffer: Buffer) => this.uhkDevice.sendConfig(buffer)) diff --git a/shared/src/config-serializer/config-items/key-action/helper.ts b/shared/src/config-serializer/config-items/key-action/helper.ts index 0f1c66c2..ac06bad5 100644 --- a/shared/src/config-serializer/config-items/key-action/helper.ts +++ b/shared/src/config-serializer/config-items/key-action/helper.ts @@ -7,7 +7,8 @@ import { PlayMacroAction, SwitchKeymapAction, SwitchLayerAction, - keyActionType + keyActionType, + UnresolvedSwitchKeymapAction } from './index'; import { Macro } from '../macro'; @@ -39,7 +40,7 @@ export class Helper { case KeyActionId.SwitchLayerAction: return new SwitchLayerAction().fromBinary(buffer); case KeyActionId.SwitchKeymapAction: - return new SwitchKeymapAction().fromBinary(buffer); + return new UnresolvedSwitchKeymapAction().fromBinary(buffer); case KeyActionId.MouseAction: return new MouseAction().fromBinary(buffer); case KeyActionId.PlayMacroAction: diff --git a/shared/src/config-serializer/config-items/key-action/key-action.ts b/shared/src/config-serializer/config-items/key-action/key-action.ts index e4664e73..d33eb10a 100644 --- a/shared/src/config-serializer/config-items/key-action/key-action.ts +++ b/shared/src/config-serializer/config-items/key-action/key-action.ts @@ -1,5 +1,6 @@ import { Macro } from '../macro'; import { UhkBuffer } from '../../uhk-buffer'; +import { UserConfiguration } from '../user-configuration'; export enum KeyActionId { NoneAction = 0, @@ -44,7 +45,7 @@ export abstract class KeyAction { const keyActionId: number = KeyActionId[classname]; if (keyActionId === KeyActionId.KeystrokeAction) { if (readKeyActionId < KeyActionId.KeystrokeAction || readKeyActionId > KeyActionId.LastKeystrokeAction) { - throw `Invalid ${classname} first byte: ${readKeyActionId}`; + throw `Invalid ${classname} first byte: ${readKeyActionId}`; } } else if (readKeyActionId !== keyActionId) { throw `Invalid ${classname} first byte: ${readKeyActionId}`; @@ -53,7 +54,7 @@ export abstract class KeyAction { } abstract toJsonObject(macros?: Macro[]): any; - abstract toBinary(buffer: UhkBuffer, macros?: Macro[]): any; + abstract toBinary(buffer: UhkBuffer, userConfiguration?: UserConfiguration): void; renameKeymap(oldAbbr: string, newAbbr: string): KeyAction { return this; diff --git a/shared/src/config-serializer/config-items/key-action/play-macro-action.ts b/shared/src/config-serializer/config-items/key-action/play-macro-action.ts index 7d9efd43..7e2cb221 100644 --- a/shared/src/config-serializer/config-items/key-action/play-macro-action.ts +++ b/shared/src/config-serializer/config-items/key-action/play-macro-action.ts @@ -2,6 +2,7 @@ import { assertUInt8 } from '../../assert'; import { UhkBuffer } from '../../uhk-buffer'; import { Macro } from '../macro'; import { KeyAction, KeyActionId, keyActionType } from './key-action'; +import { UserConfiguration } from '../user-configuration'; export class PlayMacroAction extends KeyAction { @@ -40,9 +41,9 @@ export class PlayMacroAction extends KeyAction { }; } - toBinary(buffer: UhkBuffer, macros: Macro[]) { + toBinary(buffer: UhkBuffer, userConfiguration: UserConfiguration) { buffer.writeUInt8(KeyActionId.PlayMacroAction); - buffer.writeUInt8(macros.findIndex(macro => macro.id === this.macroId)); + buffer.writeUInt8(userConfiguration.macros.findIndex(macro => macro.id === this.macroId)); } toString(): string { diff --git a/shared/src/config-serializer/config-items/key-action/switch-keymap-action.ts b/shared/src/config-serializer/config-items/key-action/switch-keymap-action.ts index 86163cec..9c87a7f4 100644 --- a/shared/src/config-serializer/config-items/key-action/switch-keymap-action.ts +++ b/shared/src/config-serializer/config-items/key-action/switch-keymap-action.ts @@ -1,6 +1,8 @@ +import { assertUInt8 } from '../../assert'; import { UhkBuffer } from '../../uhk-buffer'; import { Keymap } from '../keymap'; import { KeyAction, KeyActionId, keyActionType } from './key-action'; +import { UserConfiguration } from '../user-configuration'; export class SwitchKeymapAction extends KeyAction { @@ -26,12 +28,6 @@ export class SwitchKeymapAction extends KeyAction { return this; } - fromBinary(buffer: UhkBuffer): SwitchKeymapAction { - this.readAndAssertKeyActionId(buffer); - this.keymapAbbreviation = buffer.readString(); - return this; - } - toJsonObject(): any { return { keyActionType: keyActionType.SwitchKeymapAction, @@ -39,9 +35,10 @@ export class SwitchKeymapAction extends KeyAction { }; } - toBinary(buffer: UhkBuffer) { + toBinary(buffer: UhkBuffer, userConfiguration: UserConfiguration): void { + const keymapIndex = userConfiguration.keymaps.findIndex(keymap => keymap.abbreviation === this.keymapAbbreviation); buffer.writeUInt8(KeyActionId.SwitchKeymapAction); - buffer.writeString(this.keymapAbbreviation); + buffer.writeUInt8(keymapIndex); } toString(): string { @@ -55,3 +52,33 @@ export class SwitchKeymapAction extends KeyAction { return new SwitchKeymapAction(newAbbr); } } + +export class UnresolvedSwitchKeymapAction extends KeyAction { + + @assertUInt8 + keymapIndex: number; + + constructor(keymapIndex?: number) { + super(); + this.keymapIndex = keymapIndex; + } + + fromBinary(buffer: UhkBuffer): UnresolvedSwitchKeymapAction { + buffer.readUInt8(); // Skip key action id + this.keymapIndex = buffer.readUInt8(); + return this; + } + + toBinary(buffer: UhkBuffer) { + buffer.writeUInt8(KeyActionId.SwitchKeymapAction); + buffer.writeUInt8(this.keymapIndex); + } + + toJsonObject(): any { + throw new Error('UnresolvedSwitchKeymapAction cannot be serialized directly. Convert it to SwitchKeymapAction first.'); + } + + resolve(keymaps: Keymap[]): SwitchKeymapAction { + return new SwitchKeymapAction(keymaps[this.keymapIndex]); + } +} diff --git a/shared/src/config-serializer/config-items/keymap.ts b/shared/src/config-serializer/config-items/keymap.ts index 038ca2f1..0bc621ca 100644 --- a/shared/src/config-serializer/config-items/keymap.ts +++ b/shared/src/config-serializer/config-items/keymap.ts @@ -2,6 +2,8 @@ import { UhkBuffer } from '../uhk-buffer'; import { Layer } from './layer'; import { Macro } from './macro'; import { SwitchLayerAction, KeyAction } from './key-action'; +import { ConfigSerializer } from '../config-serializer'; +import { UserConfiguration } from './user-configuration'; export class Keymap { @@ -59,13 +61,13 @@ export class Keymap { }; } - toBinary(buffer: UhkBuffer, macros?: Macro[]): void { + toBinary(buffer: UhkBuffer, userConfiguration: UserConfiguration): void { buffer.writeString(this.abbreviation); buffer.writeBoolean(this.isDefault); buffer.writeString(this.name); buffer.writeString(this.description); buffer.writeArray(this.layers, (uhkBuffer: UhkBuffer, layer: Layer) => { - layer.toBinary(uhkBuffer, macros); + layer.toBinary(uhkBuffer, userConfiguration); }); } diff --git a/shared/src/config-serializer/config-items/layer.ts b/shared/src/config-serializer/config-items/layer.ts index 072d8674..33cf093f 100644 --- a/shared/src/config-serializer/config-items/layer.ts +++ b/shared/src/config-serializer/config-items/layer.ts @@ -1,6 +1,8 @@ import { UhkBuffer } from '../uhk-buffer'; import { Macro } from './macro'; import { Module } from './module'; +import { UserConfiguration } from './user-configuration'; +import { ConfigSerializer } from '../config-serializer'; export class Layer { @@ -31,9 +33,9 @@ export class Layer { }; } - toBinary(buffer: UhkBuffer, macros?: Macro[]): void { + toBinary(buffer: UhkBuffer, userConfiguration: UserConfiguration): void { buffer.writeArray(this.modules, (uhkBuffer: UhkBuffer, module: Module) => { - module.toBinary(uhkBuffer, macros); + module.toBinary(uhkBuffer, userConfiguration); }); } diff --git a/shared/src/config-serializer/config-items/module.ts b/shared/src/config-serializer/config-items/module.ts index 267b3318..a626c37b 100644 --- a/shared/src/config-serializer/config-items/module.ts +++ b/shared/src/config-serializer/config-items/module.ts @@ -2,6 +2,7 @@ import { assertEnum, assertUInt8 } from '../assert'; import { UhkBuffer } from '../uhk-buffer'; import { Helper as KeyActionHelper, KeyAction, NoneAction, PlayMacroAction, SwitchKeymapAction } from './key-action'; import { Macro } from './macro'; +import { UserConfiguration } from './user-configuration'; enum PointerRole { none, @@ -60,7 +61,7 @@ export class Module { }; } - toBinary(buffer: UhkBuffer, macros?: Macro[]): void { + toBinary(buffer: UhkBuffer, userConfiguration: UserConfiguration): void { buffer.writeUInt8(this.id); buffer.writeUInt8(this.pointerRole); @@ -74,7 +75,7 @@ export class Module { }); buffer.writeArray(keyActions, (uhkBuffer: UhkBuffer, keyAction: KeyAction) => { - keyAction.toBinary(uhkBuffer, macros); + keyAction.toBinary(uhkBuffer, userConfiguration); }); } diff --git a/shared/src/config-serializer/config-items/user-configuration.ts b/shared/src/config-serializer/config-items/user-configuration.ts index 819bef0b..a79a7cdb 100644 --- a/shared/src/config-serializer/config-items/user-configuration.ts +++ b/shared/src/config-serializer/config-items/user-configuration.ts @@ -3,6 +3,7 @@ import { UhkBuffer } from '../uhk-buffer'; import { Keymap } from './keymap'; import { Macro } from './macro'; import { ModuleConfiguration } from './module-configuration'; +import { ConfigSerializer } from '../config-serializer'; export class UserConfiguration { @@ -40,6 +41,7 @@ export class UserConfiguration { return macro; }); this.keymaps = buffer.readArray(uhkBuffer => new Keymap().fromBinary(uhkBuffer, this.macros)); + ConfigSerializer.resolveSwitchKeymapActions(this.keymaps); return this; } @@ -57,7 +59,7 @@ export class UserConfiguration { buffer.writeArray(this.moduleConfigurations); buffer.writeArray(this.macros); buffer.writeArray(this.keymaps, (uhkBuffer: UhkBuffer, keymap: Keymap) => { - keymap.toBinary(uhkBuffer, this.macros); + keymap.toBinary(uhkBuffer, this); }); } diff --git a/shared/src/config-serializer/config-serializer.ts b/shared/src/config-serializer/config-serializer.ts new file mode 100644 index 00000000..181a8466 --- /dev/null +++ b/shared/src/config-serializer/config-serializer.ts @@ -0,0 +1,20 @@ +import { Keymap } from './config-items/keymap'; +import { UnresolvedSwitchKeymapAction } from './config-items/key-action'; + +export namespace ConfigSerializer { + + export function resolveSwitchKeymapActions(keymaps: Keymap[]) { + for (const keymap of keymaps) { + for (const layer of keymap.layers) { + for (const module of layer.modules) { + for (let i = 0; i < module.keyActions.length; ++i) { + const keyAction = module.keyActions[i]; + if (keyAction instanceof UnresolvedSwitchKeymapAction) { + module.keyActions[i] = keyAction.resolve(keymaps); + } + } + } + } + } + } +} diff --git a/shared/src/config-serializer/index.ts b/shared/src/config-serializer/index.ts new file mode 100644 index 00000000..456f542e --- /dev/null +++ b/shared/src/config-serializer/index.ts @@ -0,0 +1 @@ +export { ConfigSerializer } from './config-serializer';