Folder restructuring (#86)
This commit is contained in:
54
src/config-serializer/ClassArray.ts
Normal file
54
src/config-serializer/ClassArray.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import {Serializable} from './Serializable';
|
||||
import {UhkBuffer} from './UhkBuffer';
|
||||
|
||||
export abstract class ClassArray<T extends Serializable<T>> extends Serializable<ClassArray<T>> {
|
||||
|
||||
elements: T[] = [];
|
||||
|
||||
_fromJsObject(jsObjects: any): ClassArray<T> {
|
||||
for (let jsObject of jsObjects) {
|
||||
this.elements.push(this.jsObjectToClass(jsObject));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): ClassArray<T> {
|
||||
let arrayLength = buffer.readCompactLength();
|
||||
|
||||
if (buffer.enableDump) {
|
||||
buffer.enableDump = false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < arrayLength; i++) {
|
||||
this.elements.push(this.binaryToClass(buffer));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
let array: any[] = [];
|
||||
for (let element of this.elements) {
|
||||
array.push(element.toJsObject());
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeCompactLength(this.elements.length);
|
||||
|
||||
if (buffer.enableDump) {
|
||||
buffer.enableDump = false;
|
||||
}
|
||||
|
||||
for (let element of this.elements) {
|
||||
element.toBinary(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<${this.constructor.name} length="${this.elements.length}">`;
|
||||
}
|
||||
|
||||
abstract jsObjectToClass(jsObject: any): T;
|
||||
abstract binaryToClass(buffer: UhkBuffer): T;
|
||||
}
|
||||
3
src/config-serializer/Function.d.ts
vendored
Normal file
3
src/config-serializer/Function.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
interface Function {
|
||||
name: string;
|
||||
}
|
||||
87
src/config-serializer/README.md
Normal file
87
src/config-serializer/README.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Configuration serializer
|
||||
|
||||
This directory contains the configuration serializer of Agent.
|
||||
|
||||
The configuration of the UHK is unusually complex for a keyboard, and is composed of a number of items of different types, including keymaps, layers, macros, and the like. This is a supposed to be a short guide for the aspiring hacker. Let's get right into it!
|
||||
|
||||
## Setup
|
||||
|
||||
Given that the development dependencies are installed on your system you should be able to build the configuration serializer tester by executing `npm run build:test` in this directory, then start the test by running `node test-serializer.js`.
|
||||
|
||||
## Configuration representations
|
||||
|
||||
There are 3 different representations of the configuration, each filling a specific purpose.
|
||||
|
||||
The **JavaScript representation** is optimally suited to be serialized as JSON, and saved to the file system, or transmitted over the network. As a plaintext format, it's human-readable and easily editable. See [uhk-config.json](uhk-config.json) for an example configuration.
|
||||
|
||||
The **TypeScript representation** is structurally similar to the JavaScript representation, but it features strongly typed TypeScript objects instead of typeless JavaScript objects. This representation is meant to be used by Agent. Extensive, per-property [assertion](assert.ts) takes place upon initializing the TypeScript objects to ensure the integrity of the configuration.
|
||||
|
||||
The **binary representation** is meant to be written to, and read from the EEPROM of the UHK. It's designed to be very compact in order to maximize the use of the 32kbyte EEPROM space.
|
||||
|
||||
## Configuration item types
|
||||
|
||||
Each configuration item belongs to a specific type. The following types are available:
|
||||
|
||||
**Primitive types** are integers of different sizes, and string. See [UhkBuffer](UhkBuffer.ts) which implements all the primitive types.
|
||||
|
||||
**Compound types** are composed of primitive types, and/or compound types. All compound types must descend from the [Serializable](Serializable.ts) class, and saved into the [config-items](config-items) directory.
|
||||
|
||||
**Array type** is a special compound type which is composed of a sequence of items of a specific type. Array items must descend from the [ClassArray](ClassArray.ts) class.
|
||||
|
||||
## Dumping serialization
|
||||
|
||||
The serialization of configuration items is a complicated business, and many things can go wrong. That's the exact reason why serialization can be dumped to ease debugging. All you have to do is to set `Serializable.enableDump` to `true`, and you'll see something like the following upon serialization actions:
|
||||
|
||||
```
|
||||
KeyActions.fromJsObject: [{"keyActionType":"none"},{"keyActionType":"keystroke","scancode":110},{"keyActionType":"keystrokeModifiers","modifierMask":33},{"keyActionType":"keystrokeWithM...
|
||||
NoneAction.fromJsObject: {"keyActionType":"none"} => <NoneAction>
|
||||
KeystrokeAction.fromJsObject: {"keyActionType":"keystroke","scancode":110} => <KeystrokeAction scancode="110">
|
||||
KeystrokeModifiersAction.fromJsObject: {"keyActionType":"keystrokeModifiers","modifierMask":33} => <KeystrokeModifiersAction modifierMask="33">
|
||||
KeystrokeWithModifiersAction.fromJsObject: {"keyActionType":"keystrokeWithModifiers","scancode":120,"modifierMask":16} => <KeystrokeWithModifiersAction scancode="120" modifierMask="16">
|
||||
SwitchLayerAction.fromJsObject: {"keyActionType":"switchLayer","layer":"fn","toggle":false} => <SwitchLayerAction layer="1" toggle="false">
|
||||
DualRoleKeystrokeAction.fromJsObject: {"keyActionType":"dualRoleKeystroke","scancode":111,"longPressAction":"mod"} => <DualRoleKeystrokeAction scancode="111" longPressAction="8">
|
||||
MouseAction.fromJsObject: {"keyActionType":"mouse","mouseAction":"scrollDown"} => <MouseAction mouseAction="8">
|
||||
PlayMacroAction.fromJsObject: {"keyActionType":"playMacro","macroId":0} => <PlayMacroAction macroId="0">
|
||||
SwitchKeymapAction.fromJsObject: {"keyActionType":"switchKeymap","keymapId":1} => <SwitchKeymapAction keymapId="1">
|
||||
KeyActions.toBinary: <KeyActions length="9"> => ['u8(9)]
|
||||
NoneAction.toBinary: <NoneAction> => ['u8(0)]
|
||||
KeystrokeAction.toBinary: <KeystrokeAction scancode="110"> => ['u8(1), u8(110)]
|
||||
KeystrokeModifiersAction.toBinary: <KeystrokeModifiersAction modifierMask="33"> => ['u8(2), u8(33)]
|
||||
KeystrokeWithModifiersAction.toBinary: <KeystrokeWithModifiersAction scancode="120" modifierMask="16"> => ['u8(3), u8(120), u8(16)]
|
||||
SwitchLayerAction.toBinary: <SwitchLayerAction layer="1" toggle="false"> => ['u8(5), u8(1)]
|
||||
DualRoleKeystrokeAction.toBinary: <DualRoleKeystrokeAction scancode="111" longPressAction="8"> => ['u8(4), u8(111), u8(8)]
|
||||
MouseAction.toBinary: <MouseAction mouseAction="8"> => ['u8(7), u8(8)]
|
||||
PlayMacroAction.toBinary: <PlayMacroAction macroId="0"> => ['u8(8), u8(0)]
|
||||
SwitchKeymapAction.toBinary: <SwitchKeymapAction keymapId="1"> => ['u8(6), u8(1)]
|
||||
KeyActions.fromBinary: [u8(9)]
|
||||
NoneAction.fromBinary: [u8(0)] => <NoneAction>
|
||||
KeystrokeAction.fromBinary: [u8(1), u8(110)] => <KeystrokeAction scancode="110">
|
||||
KeystrokeModifiersAction.fromBinary: [u8(2), u8(33)] => <KeystrokeModifiersAction modifierMask="33">
|
||||
KeystrokeWithModifiersAction.fromBinary: [u8(3), u8(120), u8(16)] => <KeystrokeWithModifiersAction scancode="120" modifierMask="16">
|
||||
SwitchLayerAction.fromBinary: [u8(5), u8(1)] => <SwitchLayerAction layer="1" toggle="false">
|
||||
DualRoleKeystrokeAction.fromBinary: [u8(4), u8(111), u8(8)] => <DualRoleKeystrokeAction scancode="111" longPressAction="8">
|
||||
MouseAction.fromBinary: [u8(7), u8(8)] => <MouseAction mouseAction="8">
|
||||
PlayMacroAction.fromBinary: [u8(8), u8(0)] => <PlayMacroAction macroId="0">
|
||||
SwitchKeymapAction.fromBinary: [u8(6), u8(1)] => <SwitchKeymapAction keymapId="1">
|
||||
KeyActions.toJsObject: <KeyActions length="9">
|
||||
NoneAction.toJsObject: <NoneAction> => {"keyActionType":"none"}
|
||||
KeystrokeAction.toJsObject: <KeystrokeAction scancode="110"> => {"keyActionType":"keystroke","scancode":110}
|
||||
KeystrokeModifiersAction.toJsObject: <KeystrokeModifiersAction modifierMask="33"> => {"keyActionType":"keystrokeModifiers","modifierMask":33}
|
||||
KeystrokeWithModifiersAction.toJsObject: <KeystrokeWithModifiersAction scancode="120" modifierMask="16"> => {"keyActionType":"keystrokeWithModifiers","scancode":120,"modifierMask":16}
|
||||
SwitchLayerAction.toJsObject: <SwitchLayerAction layer="1" toggle="false"> => {"keyActionType":"switchLayer","layer":"fn","toggle":false}
|
||||
DualRoleKeystrokeAction.toJsObject: <DualRoleKeystrokeAction scancode="111" longPressAction="8"> => {"keyActionType":"dualRoleKeystroke","scancode":111,"longPressAction":"mod"}
|
||||
MouseAction.toJsObject: <MouseAction mouseAction="8"> => {"keyActionType":"mouse","mouseAction":"scrollDown"}
|
||||
PlayMacroAction.toJsObject: <PlayMacroAction macroId="0"> => {"keyActionType":"playMacro","macroId":0}
|
||||
SwitchKeymapAction.toJsObject: <SwitchKeymapAction keymapId="1"> => {"keyActionType":"switchKeymap","keymapId":1}
|
||||
```
|
||||
|
||||
## Testing the serializer
|
||||
|
||||
[test-serializer.ts](test-serializer.ts) is designed to test the serializer by taking [uhk-config.json](uhk-config.json), and transforming it to TypeScript representation, then to binary representation, then finally back to JavaScript representation. This should exercise every major code path.
|
||||
|
||||
If the testing is successful the following should be displayed:
|
||||
|
||||
```
|
||||
JSON configurations are identical.
|
||||
Binary configurations are identical.
|
||||
```
|
||||
74
src/config-serializer/Serializable.ts
Normal file
74
src/config-serializer/Serializable.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
/// <references path="Function.d.ts">
|
||||
|
||||
import {UhkBuffer} from './UhkBuffer';
|
||||
|
||||
export abstract class Serializable<T> {
|
||||
|
||||
private static depth = 0;
|
||||
private static maxDisplayedJsonLength = 160;
|
||||
private static enableDump = false;
|
||||
|
||||
fromJsObject(jsObject: any): T {
|
||||
this.dump(`${this.getIndentation()}${this.constructor.name}.fromJsObject: ` +
|
||||
`${this.strintifyJsObject(jsObject)}\n`);
|
||||
Serializable.depth++;
|
||||
let value = this._fromJsObject(jsObject);
|
||||
Serializable.depth--;
|
||||
this.dump(`${this.getIndentation()}=> ${value}\n`);
|
||||
return value;
|
||||
}
|
||||
|
||||
fromBinary(buffer: UhkBuffer): T {
|
||||
this.dump(`\n${this.getIndentation()}${this.constructor.name}.fromBinary: [`);
|
||||
Serializable.depth++;
|
||||
buffer.enableDump = Serializable.enableDump;
|
||||
let value = this._fromBinary(buffer);
|
||||
buffer.enableDump = false;
|
||||
Serializable.depth--;
|
||||
this.dump(`]\n${this.getIndentation()}=> ${value}`);
|
||||
return value;
|
||||
}
|
||||
|
||||
toJsObject(): any {
|
||||
this.dump(`${this.getIndentation()}${this.constructor.name}.toJsObject: ${this}\n`);
|
||||
Serializable.depth++;
|
||||
let value = this._toJsObject();
|
||||
Serializable.depth--;
|
||||
this.dump(`${this.getIndentation()}=> ${this.strintifyJsObject(value)}\n`);
|
||||
return value;
|
||||
}
|
||||
|
||||
// TODO: remove parameter and return the buffer
|
||||
toBinary(buffer: UhkBuffer): void {
|
||||
this.dump(`\n${this.getIndentation()}${this.constructor.name}.toBinary: ${this} [`);
|
||||
Serializable.depth++;
|
||||
buffer.enableDump = Serializable.enableDump;
|
||||
let value = this._toBinary(buffer);
|
||||
buffer.enableDump = false;
|
||||
Serializable.depth--;
|
||||
this.dump(`]`);
|
||||
return value;
|
||||
}
|
||||
|
||||
abstract _fromJsObject(jsObject: any): T;
|
||||
abstract _fromBinary(buffer: UhkBuffer): T;
|
||||
abstract _toJsObject(): any;
|
||||
abstract _toBinary(buffer: UhkBuffer): void;
|
||||
|
||||
private dump(value: any) {
|
||||
if (Serializable.enableDump) {
|
||||
process.stdout.write(value);
|
||||
}
|
||||
}
|
||||
|
||||
private getIndentation() {
|
||||
return new Array(Serializable.depth + 1).join(' ');
|
||||
}
|
||||
|
||||
private strintifyJsObject(jsObject: any): string {
|
||||
let json = JSON.stringify(jsObject);
|
||||
return json.length > Serializable.maxDisplayedJsonLength
|
||||
? json.substr(0, Serializable.maxDisplayedJsonLength) + '...'
|
||||
: json;
|
||||
}
|
||||
}
|
||||
189
src/config-serializer/UhkBuffer.ts
Normal file
189
src/config-serializer/UhkBuffer.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
export class UhkBuffer {
|
||||
|
||||
private static eepromSize = 32 * 1024;
|
||||
private static maxCompactLength = 0xFFFF;
|
||||
private static longCompactLengthPrefix = 0xFF;
|
||||
private static stringEncoding = 'utf8';
|
||||
private static isFirstElementToDump = false;
|
||||
|
||||
offset: number;
|
||||
private _enableDump = false;
|
||||
|
||||
private buffer: Buffer;
|
||||
private bytesToBacktrack: number;
|
||||
|
||||
constructor() {
|
||||
this.offset = 0;
|
||||
this.bytesToBacktrack = 0;
|
||||
this.buffer = new Buffer(UhkBuffer.eepromSize);
|
||||
this.buffer.fill(0);
|
||||
}
|
||||
|
||||
readInt8(): number {
|
||||
let value = this.buffer.readInt8(this.offset);
|
||||
this.dump(`i8(${value})`);
|
||||
this.bytesToBacktrack = 1;
|
||||
this.offset += this.bytesToBacktrack;
|
||||
return value;
|
||||
}
|
||||
|
||||
writeInt8(value: number): void {
|
||||
this.dump(`i8(${value})`);
|
||||
this.buffer.writeInt8(value, this.offset);
|
||||
this.offset += 1;
|
||||
}
|
||||
|
||||
readUInt8(): number {
|
||||
let value = this.buffer.readUInt8(this.offset);
|
||||
this.dump(`u8(${value})`);
|
||||
this.bytesToBacktrack = 1;
|
||||
this.offset += this.bytesToBacktrack;
|
||||
return value;
|
||||
}
|
||||
|
||||
writeUInt8(value: number): void {
|
||||
this.dump(`u8(${value})`);
|
||||
this.buffer.writeUInt8(value, this.offset);
|
||||
this.offset += 1;
|
||||
}
|
||||
|
||||
readInt16(): number {
|
||||
let value = this.buffer.readInt16LE(this.offset);
|
||||
this.dump(`i16(${value})`);
|
||||
this.bytesToBacktrack = 2;
|
||||
this.offset += this.bytesToBacktrack;
|
||||
return value;
|
||||
}
|
||||
|
||||
writeInt16(value: number): void {
|
||||
this.dump(`i16(${value})`);
|
||||
this.buffer.writeInt16LE(value, this.offset);
|
||||
this.offset += 2;
|
||||
}
|
||||
|
||||
readUInt16(): number {
|
||||
let value = this.buffer.readUInt16LE(this.offset);
|
||||
this.dump(`u16(${value})`);
|
||||
this.bytesToBacktrack = 2;
|
||||
this.offset += this.bytesToBacktrack;
|
||||
return value;
|
||||
}
|
||||
|
||||
writeUInt16(value: number): void {
|
||||
this.dump(`u16(${value})`);
|
||||
this.buffer.writeUInt16LE(value, this.offset);
|
||||
this.offset += 2;
|
||||
}
|
||||
|
||||
readInt32(): number {
|
||||
let value = this.buffer.readInt32LE(this.offset);
|
||||
this.dump(`i32(${value})`);
|
||||
this.bytesToBacktrack = 4;
|
||||
this.offset += this.bytesToBacktrack;
|
||||
return value;
|
||||
}
|
||||
|
||||
writeInt32(value: number): void {
|
||||
this.dump(`i32(${value})`);
|
||||
this.buffer.writeInt32LE(value, this.offset);
|
||||
this.offset += 4;
|
||||
}
|
||||
|
||||
readUInt32(): number {
|
||||
let value = this.buffer.readUInt32LE(this.offset);
|
||||
this.dump(`u32(${value})`);
|
||||
this.bytesToBacktrack = 4;
|
||||
this.offset += this.bytesToBacktrack;
|
||||
return value;
|
||||
}
|
||||
|
||||
writeUInt32(value: number): void {
|
||||
this.dump(`u32(${value})`);
|
||||
this.buffer.writeUInt32LE(value, this.offset);
|
||||
this.offset += 4;
|
||||
}
|
||||
|
||||
readCompactLength(): number {
|
||||
let length = this.readUInt8();
|
||||
if (length === UhkBuffer.longCompactLengthPrefix) {
|
||||
length += this.readUInt8() << 8;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
writeCompactLength(length: number) {
|
||||
if (length >= UhkBuffer.longCompactLengthPrefix) {
|
||||
this.writeUInt8(UhkBuffer.longCompactLengthPrefix);
|
||||
this.writeUInt16(length);
|
||||
} else {
|
||||
this.writeUInt8(length);
|
||||
}
|
||||
}
|
||||
|
||||
readString(): string {
|
||||
let stringByteLength = this.readCompactLength();
|
||||
let str = this.buffer.toString(UhkBuffer.stringEncoding, this.offset, this.offset + stringByteLength);
|
||||
this.dump(`${UhkBuffer.stringEncoding}(${str})`);
|
||||
this.bytesToBacktrack = stringByteLength;
|
||||
this.offset += stringByteLength;
|
||||
return str;
|
||||
}
|
||||
|
||||
writeString(str: string): void {
|
||||
let stringByteLength = Buffer.byteLength(str, UhkBuffer.stringEncoding);
|
||||
|
||||
if (stringByteLength > UhkBuffer.maxCompactLength) {
|
||||
throw 'Cannot serialize string: ${stringByteLength} bytes is larger ' +
|
||||
'than the maximum allowed length of ${UhkBuffer.maxStringByteLength} bytes';
|
||||
}
|
||||
|
||||
this.writeCompactLength(stringByteLength);
|
||||
this.dump(`${UhkBuffer.stringEncoding}(${str})`);
|
||||
this.buffer.write(str, this.offset, stringByteLength, UhkBuffer.stringEncoding);
|
||||
this.offset += stringByteLength;
|
||||
}
|
||||
|
||||
readBoolean(): boolean {
|
||||
return this.readUInt8() !== 0;
|
||||
}
|
||||
|
||||
writeBoolean(bool: boolean) {
|
||||
this.writeUInt8(bool ? 1 : 0);
|
||||
}
|
||||
|
||||
backtrack(): void {
|
||||
this.offset -= this.bytesToBacktrack;
|
||||
this.bytesToBacktrack = 0;
|
||||
}
|
||||
|
||||
getBufferContent(): Buffer {
|
||||
return this.buffer.slice(0, this.offset);
|
||||
}
|
||||
|
||||
get enableDump() {
|
||||
return this._enableDump;
|
||||
}
|
||||
|
||||
set enableDump(value) {
|
||||
if (value) {
|
||||
UhkBuffer.isFirstElementToDump = true;
|
||||
}
|
||||
this._enableDump = value;
|
||||
}
|
||||
|
||||
dump(value: any) {
|
||||
if (!this.enableDump) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UhkBuffer.isFirstElementToDump) {
|
||||
process.stdout.write(', ');
|
||||
}
|
||||
|
||||
process.stdout.write(value);
|
||||
|
||||
if (UhkBuffer.isFirstElementToDump) {
|
||||
UhkBuffer.isFirstElementToDump = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
src/config-serializer/assert.ts
Normal file
78
src/config-serializer/assert.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
export function assertUInt8(target: any, key: string) {
|
||||
return assertInteger(target, key, 0, 0xFF);
|
||||
}
|
||||
|
||||
export function assertInt8(target: any, key: string) {
|
||||
return assertInteger(target, key, -0x80, 0x7F);
|
||||
}
|
||||
|
||||
export function assertUInt16(target: any, key: string) {
|
||||
return assertInteger(target, key, 0, 0xFFFF);
|
||||
}
|
||||
|
||||
export function assertInt16(target: any, key: string) {
|
||||
return assertInteger(target, key, -0x8000, 0x7FFF);
|
||||
}
|
||||
|
||||
export function assertUInt32(target: any, key: string) {
|
||||
return assertInteger(target, key, 0, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
export function assertInt32(target: any, key: string) {
|
||||
return assertInteger(target, key, -0x80000000, 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
export function assertCompactLength(target: any, key: string) {
|
||||
return assertUInt16(target, key);
|
||||
}
|
||||
|
||||
function assertInteger(target: any, key: string, min: number, max: number) {
|
||||
const priv = '_' + key;
|
||||
|
||||
function getter() {
|
||||
return this[priv];
|
||||
}
|
||||
|
||||
function setter(newVal: any) {
|
||||
if (this[priv] !== newVal) {
|
||||
if (newVal < min || newVal > max) {
|
||||
throw `${target.constructor.name}.${key}: ` +
|
||||
`Integer ${newVal} is outside the valid [${min}, ${max}] interval`;
|
||||
}
|
||||
this[priv] = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(target, key, {
|
||||
get: getter,
|
||||
set: setter,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
|
||||
export function assertEnum<E>(enumerated: E) {
|
||||
return function(target: any, key: string) {
|
||||
const priv = '_' + key;
|
||||
|
||||
function getter() {
|
||||
return this[priv];
|
||||
}
|
||||
|
||||
function setter(newVal: any) {
|
||||
if (this[priv] !== newVal) {
|
||||
if (enumerated[newVal] === undefined) {
|
||||
throw `${target.constructor.name}.${key}: ${newVal} is not enum`;
|
||||
}
|
||||
this[priv] = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(target, key, {
|
||||
get: getter,
|
||||
set: setter,
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
};
|
||||
}
|
||||
37
src/config-serializer/config-items/DelayMacroAction.ts
Normal file
37
src/config-serializer/config-items/DelayMacroAction.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {MacroAction, macroActionType, MacroActionId} from './MacroAction';
|
||||
import {assertUInt16} from '../assert';
|
||||
|
||||
export class DelayMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt16
|
||||
delay: number;
|
||||
|
||||
_fromJsObject(jsObject: any): DelayMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.delay = jsObject.delay;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): DelayMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.delay = buffer.readUInt16();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.DelayMacroAction,
|
||||
delay: this.delay
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.DelayMacroAction);
|
||||
buffer.writeUInt16(this.delay);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<DelayMacroAction delay="${this.delay}">`;
|
||||
}
|
||||
}
|
||||
37
src/config-serializer/config-items/HoldKeyMacroAction.ts
Normal file
37
src/config-serializer/config-items/HoldKeyMacroAction.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class HoldKeyMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
scancode: number;
|
||||
|
||||
_fromJsObject(jsObject: any): HoldKeyMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.scancode = jsObject.scancode;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): HoldKeyMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.scancode = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.HoldKeyMacroAction,
|
||||
scancode: this.scancode
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.HoldKeyMacroAction);
|
||||
buffer.writeUInt8(this.scancode);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<HoldKeyMacroAction scancode="${this.scancode}">`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {KeyModifiers} from './KeyModifiers';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class HoldModifiersMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
modifierMask: number;
|
||||
|
||||
_fromJsObject(jsObject: any): HoldModifiersMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.modifierMask = jsObject.modifierMask;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): HoldModifiersMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.modifierMask = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.HoldModifiersMacroAction,
|
||||
modifierMask: this.modifierMask
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.HoldModifiersMacroAction);
|
||||
buffer.writeUInt8(this.modifierMask);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<HoldModifiersMacroAction modifierMask="${this.modifierMask}">`;
|
||||
}
|
||||
|
||||
isModifierActive(modifier: KeyModifiers): boolean {
|
||||
return (this.modifierMask & modifier) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class HoldMouseButtonsMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
mouseButtonsMask: number;
|
||||
|
||||
_fromJsObject(jsObject: any): HoldMouseButtonsMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.mouseButtonsMask = jsObject.mouseButtonsMask;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): HoldMouseButtonsMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.mouseButtonsMask = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.HoldMouseButtonsMacroAction,
|
||||
mouseButtonsMask: this.mouseButtonsMask
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.HoldMouseButtonsMacroAction);
|
||||
buffer.writeUInt8(this.mouseButtonsMask);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<HoldMouseButtonsMacroAction mouseButtonsMask="${this.mouseButtonsMask}">`;
|
||||
}
|
||||
}
|
||||
60
src/config-serializer/config-items/KeyAction.ts
Normal file
60
src/config-serializer/config-items/KeyAction.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
/// <reference path="../Function.d.ts" />
|
||||
|
||||
import {Serializable} from '../Serializable';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
|
||||
export enum KeyActionId {
|
||||
NoneAction = 0,
|
||||
KeystrokeAction = 1,
|
||||
/*
|
||||
1 - 7 are reserved for KeystrokeAction
|
||||
3 bits:
|
||||
1: Do we have scancode?
|
||||
2: Do we have modifiers?
|
||||
3: Do we have longpress?
|
||||
*/
|
||||
LastKeystrokeAction = 7, // TODO: remove this after refactoring the keyActionId check
|
||||
SwitchLayerAction = 8,
|
||||
SwitchKeymapAction = 9,
|
||||
MouseAction = 10,
|
||||
PlayMacroAction = 11
|
||||
}
|
||||
|
||||
export let keyActionType = {
|
||||
NoneAction : 'none',
|
||||
KeystrokeAction : 'keystroke',
|
||||
SwitchLayerAction : 'switchLayer',
|
||||
SwitchKeymapAction : 'switchKeymap',
|
||||
MouseAction : 'mouse',
|
||||
PlayMacroAction : 'playMacro'
|
||||
};
|
||||
|
||||
export abstract class KeyAction extends Serializable<KeyAction> {
|
||||
|
||||
assertKeyActionType(jsObject: any): void {
|
||||
let keyActionClassname: string = this.constructor.name;
|
||||
let keyActionTypeString: string = keyActionType[keyActionClassname];
|
||||
if (jsObject.keyActionType !== keyActionTypeString) {
|
||||
throw `Invalid ${keyActionClassname}.keyActionType: ${jsObject.keyActionType}`;
|
||||
}
|
||||
}
|
||||
|
||||
readAndAssertKeyActionId(buffer: UhkBuffer): KeyActionId {
|
||||
let classname: string = this.constructor.name;
|
||||
let readKeyActionId: number = buffer.readUInt8();
|
||||
let keyActionId: number = KeyActionId[classname];
|
||||
if (keyActionId === KeyActionId.KeystrokeAction) {
|
||||
if (readKeyActionId < KeyActionId.KeystrokeAction || readKeyActionId > KeyActionId.LastKeystrokeAction) {
|
||||
throw `Invalid ${classname} first byte: ${readKeyActionId}`;
|
||||
}
|
||||
} else if (readKeyActionId !== keyActionId) {
|
||||
throw `Invalid ${classname} first byte: ${readKeyActionId}`;
|
||||
}
|
||||
return readKeyActionId;
|
||||
}
|
||||
|
||||
abstract _fromJsObject(jsObject: any): KeyAction;
|
||||
abstract _fromBinary(buffer: UhkBuffer): KeyAction;
|
||||
abstract _toJsObject(): any;
|
||||
abstract _toBinary(buffer: UhkBuffer): void;
|
||||
}
|
||||
60
src/config-serializer/config-items/KeyActions.ts
Normal file
60
src/config-serializer/config-items/KeyActions.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import {ClassArray} from '../ClassArray';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {NoneAction} from './NoneAction';
|
||||
import {KeystrokeAction} from './KeystrokeAction';
|
||||
import {keyActionType, KeyActionId, KeyAction} from './KeyAction';
|
||||
import {SwitchLayerAction} from './SwitchLayerAction';
|
||||
import {SwitchKeymapAction} from './SwitchKeymapAction';
|
||||
import {MouseAction} from './MouseAction';
|
||||
import {PlayMacroAction} from './PlayMacroAction';
|
||||
|
||||
export class KeyActions extends ClassArray<KeyAction> {
|
||||
|
||||
jsObjectToClass(jsObject: any): KeyAction {
|
||||
switch (jsObject.keyActionType) {
|
||||
case keyActionType.NoneAction:
|
||||
return new NoneAction().fromJsObject(jsObject);
|
||||
case keyActionType.KeystrokeAction:
|
||||
return new KeystrokeAction().fromJsObject(jsObject);
|
||||
case keyActionType.SwitchLayerAction:
|
||||
return new SwitchLayerAction().fromJsObject(jsObject);
|
||||
case keyActionType.SwitchKeymapAction:
|
||||
return new SwitchKeymapAction().fromJsObject(jsObject);
|
||||
case keyActionType.MouseAction:
|
||||
return new MouseAction().fromJsObject(jsObject);
|
||||
case keyActionType.PlayMacroAction:
|
||||
return new PlayMacroAction().fromJsObject(jsObject);
|
||||
default:
|
||||
throw `Invalid KeyAction.keyActionType: "${jsObject.keyActionType}"`;
|
||||
}
|
||||
}
|
||||
|
||||
binaryToClass(buffer: UhkBuffer): KeyAction {
|
||||
let keyActionFirstByte = buffer.readUInt8();
|
||||
buffer.backtrack();
|
||||
|
||||
if (buffer.enableDump) {
|
||||
process.stdout.write(']\n');
|
||||
buffer.enableDump = false;
|
||||
}
|
||||
|
||||
if (keyActionFirstByte >= KeyActionId.KeystrokeAction && keyActionFirstByte < KeyActionId.LastKeystrokeAction) {
|
||||
return new KeystrokeAction().fromBinary(buffer);
|
||||
}
|
||||
|
||||
switch (keyActionFirstByte) {
|
||||
case KeyActionId.NoneAction:
|
||||
return new NoneAction().fromBinary(buffer);
|
||||
case KeyActionId.SwitchLayerAction:
|
||||
return new SwitchLayerAction().fromBinary(buffer);
|
||||
case KeyActionId.SwitchKeymapAction:
|
||||
return new SwitchKeymapAction().fromBinary(buffer);
|
||||
case KeyActionId.MouseAction:
|
||||
return new MouseAction().fromBinary(buffer);
|
||||
case KeyActionId.PlayMacroAction:
|
||||
return new PlayMacroAction().fromBinary(buffer);
|
||||
default:
|
||||
throw `Invalid KeyAction first byte: ${keyActionFirstByte}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/config-serializer/config-items/KeyModifiers.ts
Normal file
10
src/config-serializer/config-items/KeyModifiers.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export enum KeyModifiers {
|
||||
leftCtrl = 1 << 0,
|
||||
leftShift = 1 << 1,
|
||||
leftAlt = 1 << 2,
|
||||
leftGui = 1 << 3,
|
||||
rightCtrl = 1 << 4,
|
||||
rightShift = 1 << 5,
|
||||
rightAlt = 1 << 6,
|
||||
rightGui = 1 << 7
|
||||
}
|
||||
58
src/config-serializer/config-items/Keymap.ts
Normal file
58
src/config-serializer/config-items/Keymap.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import {Serializable} from '../Serializable';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {Layers} from './Layers';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class Keymap extends Serializable<Keymap> {
|
||||
|
||||
@assertUInt8
|
||||
id: number;
|
||||
|
||||
name: string;
|
||||
|
||||
abbreviation: string;
|
||||
|
||||
isDefault: boolean;
|
||||
|
||||
layers: Layers;
|
||||
|
||||
_fromJsObject(jsObject: any): Keymap {
|
||||
this.id = jsObject.id;
|
||||
this.isDefault = jsObject.isDefault;
|
||||
this.abbreviation = jsObject.abbreviation;
|
||||
this.name = jsObject.name;
|
||||
this.layers = new Layers().fromJsObject(jsObject.layers);
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): Keymap {
|
||||
this.id = buffer.readUInt8();
|
||||
this.isDefault = buffer.readBoolean();
|
||||
this.abbreviation = buffer.readString();
|
||||
this.name = buffer.readString();
|
||||
this.layers = new Layers().fromBinary(buffer);
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
id: this.id,
|
||||
isDefault: this.isDefault,
|
||||
abbreviation: this.abbreviation,
|
||||
name: this.name,
|
||||
layers: this.layers.toJsObject()
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer): void {
|
||||
buffer.writeUInt8(this.id);
|
||||
buffer.writeBoolean(this.isDefault);
|
||||
buffer.writeString(this.abbreviation);
|
||||
buffer.writeString(this.name);
|
||||
this.layers.toBinary(buffer);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<Keymap id="${this.id}" name="${this.name}">`;
|
||||
}
|
||||
}
|
||||
15
src/config-serializer/config-items/Keymaps.ts
Normal file
15
src/config-serializer/config-items/Keymaps.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import {ClassArray} from '../ClassArray';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {Keymap} from './Keymap';
|
||||
|
||||
export class Keymaps extends ClassArray<Keymap> {
|
||||
|
||||
jsObjectToClass(jsObject: any): Keymap {
|
||||
return new Keymap().fromJsObject(jsObject);
|
||||
}
|
||||
|
||||
binaryToClass(buffer: UhkBuffer): Keymap {
|
||||
return new Keymap().fromBinary(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
133
src/config-serializer/config-items/KeystrokeAction.ts
Normal file
133
src/config-serializer/config-items/KeystrokeAction.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {keyActionType, KeyActionId, KeyAction} from './KeyAction';
|
||||
import {KeyModifiers} from './KeyModifiers';
|
||||
import {assertUInt8, assertEnum} from '../assert';
|
||||
import {LongPressAction} from './LongPressAction';
|
||||
|
||||
export enum KeystrokeActionFlag {
|
||||
scancode = 1 << 0,
|
||||
modifierMask = 1 << 1,
|
||||
longPressAction = 1 << 2,
|
||||
}
|
||||
|
||||
interface JsObjectKeystrokeAction {
|
||||
keyActionType: string;
|
||||
scancode?: number;
|
||||
modifierMask?: number;
|
||||
longPressAction?: string;
|
||||
}
|
||||
|
||||
export class KeystrokeAction extends KeyAction {
|
||||
|
||||
@assertUInt8
|
||||
scancode: number;
|
||||
|
||||
@assertUInt8
|
||||
modifierMask: number;
|
||||
|
||||
@assertEnum(LongPressAction)
|
||||
longPressAction: LongPressAction;
|
||||
|
||||
_fromJsObject(jsObject: JsObjectKeystrokeAction): KeystrokeAction {
|
||||
this.assertKeyActionType(jsObject);
|
||||
this.scancode = jsObject.scancode;
|
||||
this.modifierMask = jsObject.modifierMask;
|
||||
this.longPressAction = LongPressAction[jsObject.longPressAction];
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): KeystrokeAction {
|
||||
let keyActionId: KeyActionId = this.readAndAssertKeyActionId(buffer);
|
||||
let flags: number = keyActionId - KeyActionId.KeystrokeAction;
|
||||
if (flags & KeystrokeActionFlag.scancode) {
|
||||
this.scancode = buffer.readUInt8();
|
||||
}
|
||||
if (flags & KeystrokeActionFlag.modifierMask) {
|
||||
this.modifierMask = buffer.readUInt8();
|
||||
}
|
||||
if (flags & KeystrokeActionFlag.longPressAction) {
|
||||
this.longPressAction = buffer.readUInt8();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): JsObjectKeystrokeAction {
|
||||
let jsObject: JsObjectKeystrokeAction = {
|
||||
keyActionType: keyActionType.KeystrokeAction
|
||||
};
|
||||
|
||||
if (this.hasScancode()) {
|
||||
jsObject.scancode = this.scancode;
|
||||
}
|
||||
|
||||
if (this.hasActiveModifier()) {
|
||||
jsObject.modifierMask = this.modifierMask;
|
||||
}
|
||||
|
||||
if (this.hasLongPressAction()) {
|
||||
jsObject.longPressAction = LongPressAction[this.longPressAction];
|
||||
}
|
||||
|
||||
return jsObject;
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
let flags = 0;
|
||||
let bufferData: number[] = [];
|
||||
|
||||
if (this.hasScancode()) {
|
||||
flags |= KeystrokeActionFlag.scancode;
|
||||
bufferData.push(this.scancode);
|
||||
}
|
||||
|
||||
if (this.hasActiveModifier()) {
|
||||
flags |= KeystrokeActionFlag.modifierMask;
|
||||
bufferData.push(this.modifierMask);
|
||||
}
|
||||
|
||||
if (this.hasLongPressAction()) {
|
||||
flags |= KeystrokeActionFlag.longPressAction;
|
||||
bufferData.push(this.longPressAction);
|
||||
}
|
||||
|
||||
buffer.writeUInt8(KeyActionId.KeystrokeAction + flags);
|
||||
for (let i = 0; i < bufferData.length; ++i) {
|
||||
buffer.writeUInt8(bufferData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
let properties: string[] = [];
|
||||
if (this.hasScancode()) {
|
||||
properties.push(`scancode="${this.scancode}"`);
|
||||
}
|
||||
if (this.hasActiveModifier()) {
|
||||
properties.push(`modifierMask="${this.modifierMask}"`);
|
||||
}
|
||||
if (this.hasLongPressAction()) {
|
||||
properties.push(`longPressAction="${this.longPressAction}"`);
|
||||
}
|
||||
|
||||
return `<KeystrokeAction ${properties.join(' ')}>`;
|
||||
}
|
||||
|
||||
isActive(modifier: KeyModifiers): boolean {
|
||||
return (this.modifierMask & modifier) > 0;
|
||||
}
|
||||
|
||||
hasActiveModifier(): boolean {
|
||||
return this.modifierMask > 0;
|
||||
}
|
||||
|
||||
hasLongPressAction(): boolean {
|
||||
return this.longPressAction !== undefined;
|
||||
}
|
||||
|
||||
hasScancode(): boolean {
|
||||
return !!this.scancode;
|
||||
}
|
||||
|
||||
hasOnlyOneActiveModifier(): boolean {
|
||||
return this.modifierMask !== 0 && !(this.modifierMask & this.modifierMask - 1);
|
||||
}
|
||||
}
|
||||
35
src/config-serializer/config-items/Layer.ts
Normal file
35
src/config-serializer/config-items/Layer.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Serializable } from '../Serializable';
|
||||
import { Modules } from './Modules';
|
||||
import { UhkBuffer } from '../UhkBuffer';
|
||||
import { AnimationKeyboard } from '../../components/svg/wrap';
|
||||
|
||||
export class Layer extends Serializable<Layer> {
|
||||
|
||||
modules: Modules;
|
||||
animation: AnimationKeyboard = 'none';
|
||||
|
||||
_fromJsObject(jsObject: any): Layer {
|
||||
this.modules = new Modules().fromJsObject(jsObject.modules);
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): Layer {
|
||||
this.modules = new Modules().fromBinary(buffer);
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
modules: this.modules.toJsObject()
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer): void {
|
||||
this.modules.toBinary(buffer);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<Layer>`;
|
||||
}
|
||||
|
||||
}
|
||||
15
src/config-serializer/config-items/Layers.ts
Normal file
15
src/config-serializer/config-items/Layers.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import {ClassArray} from '../ClassArray';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {Layer} from './Layer';
|
||||
|
||||
export class Layers extends ClassArray<Layer> {
|
||||
|
||||
jsObjectToClass(jsObject: any): Layer {
|
||||
return new Layer().fromJsObject(jsObject);
|
||||
}
|
||||
|
||||
binaryToClass(buffer: UhkBuffer): Layer {
|
||||
return new Layer().fromBinary(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
13
src/config-serializer/config-items/LongPressAction.ts
Normal file
13
src/config-serializer/config-items/LongPressAction.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export enum LongPressAction {
|
||||
leftCtrl,
|
||||
leftShift,
|
||||
leftAlt,
|
||||
leftSuper,
|
||||
rightCtrl,
|
||||
rightShift,
|
||||
rightAlt,
|
||||
rightSuper,
|
||||
mod,
|
||||
fn,
|
||||
mouse
|
||||
};
|
||||
58
src/config-serializer/config-items/Macro.ts
Normal file
58
src/config-serializer/config-items/Macro.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import {Serializable} from '../Serializable';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {MacroActions} from './MacroActions';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class Macro extends Serializable<Macro> {
|
||||
|
||||
@assertUInt8
|
||||
id: number;
|
||||
|
||||
isLooped: boolean;
|
||||
|
||||
isPrivate: boolean;
|
||||
|
||||
name: string;
|
||||
|
||||
macroActions: MacroActions;
|
||||
|
||||
_fromJsObject(jsObject: any): Macro {
|
||||
this.id = jsObject.id;
|
||||
this.isLooped = jsObject.isLooped;
|
||||
this.isPrivate = jsObject.isPrivate;
|
||||
this.name = jsObject.name;
|
||||
this.macroActions = new MacroActions().fromJsObject(jsObject.macroActions);
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): Macro {
|
||||
this.id = buffer.readUInt8();
|
||||
this.isLooped = buffer.readBoolean();
|
||||
this.isPrivate = buffer.readBoolean();
|
||||
this.name = buffer.readString();
|
||||
this.macroActions = new MacroActions().fromBinary(buffer);
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
id: this.id,
|
||||
isLooped: this.isLooped,
|
||||
isPrivate: this.isPrivate,
|
||||
name: this.name,
|
||||
macroActions: this.macroActions.toJsObject()
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer): void {
|
||||
buffer.writeUInt8(this.id);
|
||||
buffer.writeBoolean(this.isLooped);
|
||||
buffer.writeBoolean(this.isPrivate);
|
||||
buffer.writeString(this.name);
|
||||
this.macroActions.toBinary(buffer);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<Macro id="${this.id}" name="${this.name}">`;
|
||||
}
|
||||
}
|
||||
58
src/config-serializer/config-items/MacroAction.ts
Normal file
58
src/config-serializer/config-items/MacroAction.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import {Serializable} from '../Serializable';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
|
||||
export enum MacroActionId {
|
||||
PressKeyMacroAction = 0,
|
||||
HoldKeyMacroAction = 1,
|
||||
ReleaseKeyMacroAction = 2,
|
||||
PressModifiersMacroAction = 3,
|
||||
HoldModifiersMacroAction = 4,
|
||||
ReleaseModifiersMacroAction = 5,
|
||||
PressMouseButtonsMacroAction = 6,
|
||||
HoldMouseButtonsMacroAction = 7,
|
||||
ReleaseMouseButtonsMacroAction = 8,
|
||||
MoveMouseMacroAction = 9,
|
||||
ScrollMouseMacroAction = 10,
|
||||
DelayMacroAction = 11,
|
||||
TextMacroAction = 12
|
||||
}
|
||||
|
||||
export let macroActionType = {
|
||||
PressKeyMacroAction : 'pressKey',
|
||||
HoldKeyMacroAction : 'holdKey',
|
||||
ReleaseKeyMacroAction : 'releaseKey',
|
||||
PressModifiersMacroAction : 'pressModifiers',
|
||||
HoldModifiersMacroAction : 'holdModifiers',
|
||||
ReleaseModifiersMacroAction : 'releaseModifiers',
|
||||
PressMouseButtonsMacroAction : 'pressMouseButtons',
|
||||
HoldMouseButtonsMacroAction : 'holdMouseButtons',
|
||||
ReleaseMouseButtonsMacroAction : 'releaseMouseButtons',
|
||||
MoveMouseMacroAction : 'moveMouse',
|
||||
ScrollMouseMacroAction : 'scrollMouse',
|
||||
DelayMacroAction : 'delay',
|
||||
TextMacroAction : 'text'
|
||||
};
|
||||
|
||||
export abstract class MacroAction extends Serializable<MacroAction> {
|
||||
assertMacroActionType(jsObject: any) {
|
||||
let macroActionClassname = this.constructor.name;
|
||||
let macroActionTypeString = macroActionType[macroActionClassname];
|
||||
if (jsObject.macroActionType !== macroActionTypeString) {
|
||||
throw `Invalid ${macroActionClassname}.macroActionType: ${jsObject.macroActionType}`;
|
||||
}
|
||||
}
|
||||
|
||||
readAndAssertMacroActionId(buffer: UhkBuffer) {
|
||||
let classname = this.constructor.name;
|
||||
let readMacroActionId = buffer.readUInt8();
|
||||
let macroActionId = MacroActionId[<string> classname];
|
||||
if (readMacroActionId !== macroActionId) {
|
||||
throw `Invalid ${classname} first byte: ${readMacroActionId}`;
|
||||
}
|
||||
}
|
||||
|
||||
abstract _fromJsObject(jsObject: any): MacroAction;
|
||||
abstract _fromBinary(buffer: UhkBuffer): MacroAction;
|
||||
abstract _toJsObject(): any;
|
||||
abstract _toBinary(buffer: UhkBuffer): void;
|
||||
}
|
||||
93
src/config-serializer/config-items/MacroActions.ts
Normal file
93
src/config-serializer/config-items/MacroActions.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import {ClassArray} from '../ClassArray';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {DelayMacroAction} from './DelayMacroAction';
|
||||
import {MacroAction, macroActionType, MacroActionId} from './MacroAction';
|
||||
import {HoldKeyMacroAction} from './HoldKeyMacroAction';
|
||||
import {HoldModifiersMacroAction} from './HoldModifiersMacroAction';
|
||||
import {HoldMouseButtonsMacroAction} from './HoldMouseButtonsMacroAction';
|
||||
import {MoveMouseMacroAction} from './MoveMouseMacroAction';
|
||||
import {PressKeyMacroAction} from './PressKeyMacroAction';
|
||||
import {PressModifiersMacroAction} from './PressModifiersMacroAction';
|
||||
import {PressMouseButtonsMacroAction} from './PressMouseButtonsMacroAction';
|
||||
import {ReleaseKeyMacroAction} from './ReleaseKeyMacroAction';
|
||||
import {ReleaseModifiersMacroAction} from './ReleaseModifiersMacroAction';
|
||||
import {ReleaseMouseButtonsMacroAction} from './ReleaseMouseButtonsMacroAction';
|
||||
import {ScrollMouseMacroAction} from './ScrollMouseMacroAction';
|
||||
import {TextMacroAction} from './TextMacroAction';
|
||||
|
||||
export class MacroActions extends ClassArray<MacroAction> {
|
||||
|
||||
jsObjectToClass(jsObject: any): MacroAction {
|
||||
switch (jsObject.macroActionType) {
|
||||
case macroActionType.PressKeyMacroAction:
|
||||
return new PressKeyMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.HoldKeyMacroAction:
|
||||
return new HoldKeyMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.ReleaseKeyMacroAction:
|
||||
return new ReleaseKeyMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.PressModifiersMacroAction:
|
||||
return new PressModifiersMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.HoldModifiersMacroAction:
|
||||
return new HoldModifiersMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.ReleaseModifiersMacroAction:
|
||||
return new ReleaseModifiersMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.PressMouseButtonsMacroAction:
|
||||
return new PressMouseButtonsMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.HoldMouseButtonsMacroAction:
|
||||
return new HoldMouseButtonsMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.ReleaseMouseButtonsMacroAction:
|
||||
return new ReleaseMouseButtonsMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.MoveMouseMacroAction:
|
||||
return new MoveMouseMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.ScrollMouseMacroAction:
|
||||
return new ScrollMouseMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.DelayMacroAction:
|
||||
return new DelayMacroAction().fromJsObject(jsObject);
|
||||
case macroActionType.TextMacroAction:
|
||||
return new TextMacroAction().fromJsObject(jsObject);
|
||||
default:
|
||||
throw `Invalid MacroAction.macroActionType: "${jsObject.macroActionType}"`;
|
||||
}
|
||||
}
|
||||
|
||||
binaryToClass(buffer: UhkBuffer): MacroAction {
|
||||
let macroActionFirstByte = buffer.readUInt8();
|
||||
buffer.backtrack();
|
||||
|
||||
if (buffer.enableDump) {
|
||||
process.stdout.write(']\n');
|
||||
buffer.enableDump = false;
|
||||
}
|
||||
|
||||
switch (macroActionFirstByte) {
|
||||
case MacroActionId.PressKeyMacroAction:
|
||||
return new PressKeyMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.HoldKeyMacroAction:
|
||||
return new HoldKeyMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.ReleaseKeyMacroAction:
|
||||
return new ReleaseKeyMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.PressModifiersMacroAction:
|
||||
return new PressModifiersMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.HoldModifiersMacroAction:
|
||||
return new HoldModifiersMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.ReleaseModifiersMacroAction:
|
||||
return new ReleaseModifiersMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.PressMouseButtonsMacroAction:
|
||||
return new PressMouseButtonsMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.HoldMouseButtonsMacroAction:
|
||||
return new HoldMouseButtonsMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.ReleaseMouseButtonsMacroAction:
|
||||
return new ReleaseMouseButtonsMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.MoveMouseMacroAction:
|
||||
return new MoveMouseMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.ScrollMouseMacroAction:
|
||||
return new ScrollMouseMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.DelayMacroAction:
|
||||
return new DelayMacroAction().fromBinary(buffer);
|
||||
case MacroActionId.TextMacroAction:
|
||||
return new TextMacroAction().fromBinary(buffer);
|
||||
default:
|
||||
throw `Invalid MacroAction first byte: ${macroActionFirstByte}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/config-serializer/config-items/Macros.ts
Normal file
15
src/config-serializer/config-items/Macros.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import {ClassArray} from '../ClassArray';
|
||||
import {Macro} from './Macro';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
|
||||
export class Macros extends ClassArray<Macro> {
|
||||
|
||||
jsObjectToClass(jsObject: any): Macro {
|
||||
return new Macro().fromJsObject(jsObject);
|
||||
}
|
||||
|
||||
binaryToClass(buffer: UhkBuffer): Macro {
|
||||
return new Macro().fromBinary(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
54
src/config-serializer/config-items/Module.ts
Normal file
54
src/config-serializer/config-items/Module.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import {Serializable} from '../Serializable';
|
||||
import {KeyActions} from './KeyActions';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8, assertEnum} from '../assert';
|
||||
|
||||
enum PointerRole {
|
||||
none,
|
||||
move,
|
||||
scroll
|
||||
}
|
||||
|
||||
export class Module extends Serializable<Module> {
|
||||
|
||||
@assertUInt8
|
||||
id: number;
|
||||
|
||||
keyActions: KeyActions;
|
||||
|
||||
@assertEnum(PointerRole)
|
||||
private pointerRole: PointerRole;
|
||||
|
||||
_fromJsObject(jsObject: any): Module {
|
||||
this.id = jsObject.id;
|
||||
this.pointerRole = PointerRole[<string> jsObject.pointerRole];
|
||||
this.keyActions = new KeyActions().fromJsObject(jsObject.keyActions);
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): Module {
|
||||
this.id = buffer.readUInt8();
|
||||
this.pointerRole = buffer.readUInt8();
|
||||
this.keyActions = new KeyActions().fromBinary(buffer);
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
id: this.id,
|
||||
pointerRole: PointerRole[this.pointerRole],
|
||||
keyActions: this.keyActions.toJsObject()
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer): void {
|
||||
buffer.writeUInt8(this.id);
|
||||
buffer.writeUInt8(this.pointerRole);
|
||||
this.keyActions.toBinary(buffer);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<Module id="${this.id}" pointerRole="${this.pointerRole}">`;
|
||||
}
|
||||
|
||||
}
|
||||
59
src/config-serializer/config-items/ModuleConfiguration.ts
Normal file
59
src/config-serializer/config-items/ModuleConfiguration.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import {Serializable} from '../Serializable';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class ModuleConfiguration extends Serializable<ModuleConfiguration> {
|
||||
|
||||
/*
|
||||
* module id enumeration is a separate story
|
||||
*/
|
||||
|
||||
@assertUInt8
|
||||
id: number;
|
||||
|
||||
@assertUInt8
|
||||
initialPointerSpeed: number;
|
||||
|
||||
@assertUInt8
|
||||
pointerAcceleration: number;
|
||||
|
||||
@assertUInt8
|
||||
maxPointerSpeed: number;
|
||||
|
||||
_fromJsObject(jsObject: any): ModuleConfiguration {
|
||||
this.id = jsObject.id;
|
||||
this.initialPointerSpeed = jsObject.initialPointerSpeed;
|
||||
this.pointerAcceleration = jsObject.pointerAcceleration;
|
||||
this.maxPointerSpeed = jsObject.maxPointerSpeed;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): ModuleConfiguration {
|
||||
this.id = buffer.readUInt8();
|
||||
this.initialPointerSpeed = buffer.readUInt8();
|
||||
this.pointerAcceleration = buffer.readUInt8();
|
||||
this.maxPointerSpeed = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
id: this.id,
|
||||
initialPointerSpeed: this.initialPointerSpeed,
|
||||
pointerAcceleration: this.pointerAcceleration,
|
||||
maxPointerSpeed: this.maxPointerSpeed
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer): void {
|
||||
buffer.writeUInt8(this.id);
|
||||
buffer.writeUInt8(this.initialPointerSpeed);
|
||||
buffer.writeUInt8(this.pointerAcceleration);
|
||||
buffer.writeUInt8(this.maxPointerSpeed);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<ModuleConfiguration id="${this.id}" >`;
|
||||
}
|
||||
|
||||
}
|
||||
15
src/config-serializer/config-items/ModuleConfigurations.ts
Normal file
15
src/config-serializer/config-items/ModuleConfigurations.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import {ClassArray} from '../ClassArray';
|
||||
import {ModuleConfiguration} from './ModuleConfiguration';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
|
||||
export class ModuleConfigurations extends ClassArray<ModuleConfiguration> {
|
||||
|
||||
jsObjectToClass(jsObject: any): ModuleConfiguration {
|
||||
return new ModuleConfiguration().fromJsObject(jsObject);
|
||||
}
|
||||
|
||||
binaryToClass(buffer: UhkBuffer): ModuleConfiguration {
|
||||
return new ModuleConfiguration().fromBinary(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
15
src/config-serializer/config-items/Modules.ts
Normal file
15
src/config-serializer/config-items/Modules.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import {ClassArray} from '../ClassArray';
|
||||
import {Module} from './Module';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
|
||||
export class Modules extends ClassArray<Module> {
|
||||
|
||||
jsObjectToClass(jsObject: any): Module {
|
||||
return new Module().fromJsObject(jsObject);
|
||||
}
|
||||
|
||||
binaryToClass(buffer: UhkBuffer): Module {
|
||||
return new Module().fromBinary(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
53
src/config-serializer/config-items/MouseAction.ts
Normal file
53
src/config-serializer/config-items/MouseAction.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import {keyActionType, KeyActionId, KeyAction} from './KeyAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertEnum} from '../assert';
|
||||
|
||||
export enum MouseActionParam {
|
||||
leftClick,
|
||||
middleClick,
|
||||
rightClick,
|
||||
moveUp,
|
||||
moveDown,
|
||||
moveLeft,
|
||||
moveRight,
|
||||
scrollUp,
|
||||
scrollDown,
|
||||
scrollLeft,
|
||||
scrollRight,
|
||||
accelerate,
|
||||
decelerate
|
||||
}
|
||||
|
||||
export class MouseAction extends KeyAction {
|
||||
|
||||
@assertEnum(MouseActionParam)
|
||||
mouseAction: MouseActionParam;
|
||||
|
||||
_fromJsObject(jsObject: any): MouseAction {
|
||||
this.assertKeyActionType(jsObject);
|
||||
this.mouseAction = MouseActionParam[<string> jsObject.mouseAction];
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): MouseAction {
|
||||
this.readAndAssertKeyActionId(buffer);
|
||||
this.mouseAction = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
keyActionType: keyActionType.MouseAction,
|
||||
mouseAction: MouseActionParam[this.mouseAction]
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(KeyActionId.MouseAction);
|
||||
buffer.writeUInt8(this.mouseAction);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<MouseAction mouseAction="${this.mouseAction}">`;
|
||||
}
|
||||
}
|
||||
44
src/config-serializer/config-items/MoveMouseMacroAction.ts
Normal file
44
src/config-serializer/config-items/MoveMouseMacroAction.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import {MacroAction, macroActionType, MacroActionId} from './MacroAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertInt16} from '../assert';
|
||||
|
||||
export class MoveMouseMacroAction extends MacroAction {
|
||||
|
||||
@assertInt16
|
||||
x: number;
|
||||
|
||||
@assertInt16
|
||||
y: number;
|
||||
|
||||
_fromJsObject(jsObject: any): MoveMouseMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.x = jsObject.x;
|
||||
this.y = jsObject.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): MoveMouseMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.x = buffer.readInt16();
|
||||
this.y = buffer.readInt16();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.MoveMouseMacroAction,
|
||||
x: this.x,
|
||||
y: this.y
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.MoveMouseMacroAction);
|
||||
buffer.writeInt16(this.x);
|
||||
buffer.writeInt16(this.y);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<MoveMouseMacroAction pos="(${this.x},${this.y})">`;
|
||||
}
|
||||
}
|
||||
29
src/config-serializer/config-items/NoneAction.ts
Normal file
29
src/config-serializer/config-items/NoneAction.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import {keyActionType, KeyActionId, KeyAction} from './KeyAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
|
||||
export class NoneAction extends KeyAction {
|
||||
|
||||
_fromJsObject(jsObject: any): NoneAction {
|
||||
this.assertKeyActionType(jsObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): NoneAction {
|
||||
this.readAndAssertKeyActionId(buffer);
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
keyActionType: keyActionType.NoneAction
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(KeyActionId.NoneAction);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return '<NoneAction>';
|
||||
}
|
||||
}
|
||||
37
src/config-serializer/config-items/PlayMacroAction.ts
Normal file
37
src/config-serializer/config-items/PlayMacroAction.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {keyActionType, KeyActionId, KeyAction} from './KeyAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class PlayMacroAction extends KeyAction {
|
||||
|
||||
@assertUInt8
|
||||
macroId: number;
|
||||
|
||||
_fromJsObject(jsObject: any): PlayMacroAction {
|
||||
this.assertKeyActionType(jsObject);
|
||||
this.macroId = jsObject.macroId;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): PlayMacroAction {
|
||||
this.readAndAssertKeyActionId(buffer);
|
||||
this.macroId = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
keyActionType: keyActionType.PlayMacroAction,
|
||||
macroId: this.macroId
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(KeyActionId.PlayMacroAction);
|
||||
buffer.writeUInt8(this.macroId);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<PlayMacroAction macroId="${this.macroId}">`;
|
||||
}
|
||||
}
|
||||
37
src/config-serializer/config-items/PressKeyMacroAction.ts
Normal file
37
src/config-serializer/config-items/PressKeyMacroAction.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class PressKeyMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
scancode: number;
|
||||
|
||||
_fromJsObject(jsObject: any): PressKeyMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.scancode = jsObject.scancode;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): PressKeyMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.scancode = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.PressKeyMacroAction,
|
||||
scancode: this.scancode
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.PressKeyMacroAction);
|
||||
buffer.writeUInt8(this.scancode);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<PressKeyMacroAction scancode="${this.scancode}">`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {KeyModifiers} from './KeyModifiers';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class PressModifiersMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
modifierMask: number;
|
||||
|
||||
_fromJsObject(jsObject: any): PressModifiersMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.modifierMask = jsObject.modifierMask;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): PressModifiersMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.modifierMask = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.PressModifiersMacroAction,
|
||||
modifierMask: this.modifierMask
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.PressModifiersMacroAction);
|
||||
buffer.writeUInt8(this.modifierMask);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<PressModifiersMacroAction modifierMask="${this.modifierMask}">`;
|
||||
}
|
||||
|
||||
isModifierActive(modifier: KeyModifiers): boolean {
|
||||
return (this.modifierMask & modifier) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class PressMouseButtonsMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
mouseButtonsMask: number;
|
||||
|
||||
_fromJsObject(jsObject: any): PressMouseButtonsMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.mouseButtonsMask = jsObject.mouseButtonsMask;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): PressMouseButtonsMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.mouseButtonsMask = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.PressMouseButtonsMacroAction,
|
||||
mouseButtonsMask: this.mouseButtonsMask
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.PressMouseButtonsMacroAction);
|
||||
buffer.writeUInt8(this.mouseButtonsMask);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<PressMouseButtonsMacroAction mouseButtonsMask="${this.mouseButtonsMask}">`;
|
||||
}
|
||||
}
|
||||
37
src/config-serializer/config-items/ReleaseKeyMacroAction.ts
Normal file
37
src/config-serializer/config-items/ReleaseKeyMacroAction.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class ReleaseKeyMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
scancode: number;
|
||||
|
||||
_fromJsObject(jsObject: any): ReleaseKeyMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.scancode = jsObject.scancode;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): ReleaseKeyMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.scancode = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.ReleaseKeyMacroAction,
|
||||
scancode: this.scancode
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.ReleaseKeyMacroAction);
|
||||
buffer.writeUInt8(this.scancode);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<ReleaseKeyMacroAction scancode="${this.scancode}">`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {KeyModifiers} from './KeyModifiers';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class ReleaseModifiersMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
modifierMask: number;
|
||||
|
||||
_fromJsObject(jsObject: any): ReleaseModifiersMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.modifierMask = jsObject.modifierMask;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): ReleaseModifiersMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.modifierMask = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.ReleaseModifiersMacroAction,
|
||||
modifierMask: this.modifierMask
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.ReleaseModifiersMacroAction);
|
||||
buffer.writeUInt8(this.modifierMask);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<ReleaseModifiersMacroAction modifierMask="${this.modifierMask}">`;
|
||||
}
|
||||
|
||||
isModifierActive(modifier: KeyModifiers): boolean {
|
||||
return (this.modifierMask & modifier) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class ReleaseMouseButtonsMacroAction extends MacroAction {
|
||||
|
||||
@assertUInt8
|
||||
mouseButtonsMask: number;
|
||||
|
||||
_fromJsObject(jsObject: any): ReleaseMouseButtonsMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.mouseButtonsMask = jsObject.mouseButtonsMask;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): ReleaseMouseButtonsMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.mouseButtonsMask = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.ReleaseMouseButtonsMacroAction,
|
||||
mouseButtonsMask: this.mouseButtonsMask
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.ReleaseMouseButtonsMacroAction);
|
||||
buffer.writeUInt8(this.mouseButtonsMask);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<ReleaseMouseButtonsMacroAction mouseButtonsMask="${this.mouseButtonsMask}">`;
|
||||
}
|
||||
}
|
||||
44
src/config-serializer/config-items/ScrollMouseMacroAction.ts
Normal file
44
src/config-serializer/config-items/ScrollMouseMacroAction.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertInt16} from '../assert';
|
||||
|
||||
export class ScrollMouseMacroAction extends MacroAction {
|
||||
|
||||
@assertInt16
|
||||
x: number;
|
||||
|
||||
@assertInt16
|
||||
y: number;
|
||||
|
||||
_fromJsObject(jsObject: any): ScrollMouseMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.x = jsObject.x;
|
||||
this.y = jsObject.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): ScrollMouseMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.x = buffer.readInt16();
|
||||
this.y = buffer.readInt16();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.ScrollMouseMacroAction,
|
||||
x: this.x,
|
||||
y: this.y
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.ScrollMouseMacroAction);
|
||||
buffer.writeInt16(this.x);
|
||||
buffer.writeInt16(this.y);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<ScrollMouseMacroAction pos="(${this.x},${this.y})">`;
|
||||
}
|
||||
}
|
||||
37
src/config-serializer/config-items/SwitchKeymapAction.ts
Normal file
37
src/config-serializer/config-items/SwitchKeymapAction.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {keyActionType, KeyActionId, KeyAction} from './KeyAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8} from '../assert';
|
||||
|
||||
export class SwitchKeymapAction extends KeyAction {
|
||||
|
||||
@assertUInt8
|
||||
keymapId: number;
|
||||
|
||||
_fromJsObject(jsObject: any): SwitchKeymapAction {
|
||||
this.assertKeyActionType(jsObject);
|
||||
this.keymapId = jsObject.keymapId;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): SwitchKeymapAction {
|
||||
this.readAndAssertKeyActionId(buffer);
|
||||
this.keymapId = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
keyActionType: keyActionType.SwitchKeymapAction,
|
||||
keymapId: this.keymapId
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(KeyActionId.SwitchKeymapAction);
|
||||
buffer.writeUInt8(this.keymapId);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<SwitchKeymapAction keymapId="${this.keymapId}">`;
|
||||
}
|
||||
}
|
||||
50
src/config-serializer/config-items/SwitchLayerAction.ts
Normal file
50
src/config-serializer/config-items/SwitchLayerAction.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import {keyActionType, KeyActionId, KeyAction} from './KeyAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertEnum} from '../assert';
|
||||
|
||||
export enum LayerName {
|
||||
mod,
|
||||
fn,
|
||||
mouse
|
||||
}
|
||||
|
||||
export class SwitchLayerAction extends KeyAction {
|
||||
|
||||
isLayerToggleable: boolean;
|
||||
|
||||
@assertEnum(LayerName)
|
||||
layer: LayerName;
|
||||
|
||||
_fromJsObject(jsObject: any): SwitchLayerAction {
|
||||
this.assertKeyActionType(jsObject);
|
||||
this.layer = LayerName[<string> jsObject.layer];
|
||||
this.isLayerToggleable = jsObject.toggle;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): SwitchLayerAction {
|
||||
this.readAndAssertKeyActionId(buffer);
|
||||
this.layer = buffer.readUInt8();
|
||||
this.isLayerToggleable = buffer.readBoolean();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
keyActionType: keyActionType.SwitchLayerAction,
|
||||
layer: LayerName[this.layer],
|
||||
toggle: this.isLayerToggleable
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(KeyActionId.SwitchLayerAction);
|
||||
buffer.writeUInt8(this.layer);
|
||||
buffer.writeBoolean(this.isLayerToggleable);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<SwitchLayerAction layer="${this.layer}" toggle="${this.isLayerToggleable}">`;
|
||||
}
|
||||
|
||||
}
|
||||
35
src/config-serializer/config-items/TextMacroAction.ts
Normal file
35
src/config-serializer/config-items/TextMacroAction.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import {MacroAction, MacroActionId, macroActionType} from './MacroAction';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
|
||||
export class TextMacroAction extends MacroAction {
|
||||
|
||||
text: string;
|
||||
|
||||
_fromJsObject(jsObject: any): TextMacroAction {
|
||||
this.assertMacroActionType(jsObject);
|
||||
this.text = jsObject.text;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): TextMacroAction {
|
||||
this.readAndAssertMacroActionId(buffer);
|
||||
this.text = buffer.readString();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
macroActionType: macroActionType.TextMacroAction,
|
||||
text: this.text
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer) {
|
||||
buffer.writeUInt8(MacroActionId.TextMacroAction);
|
||||
buffer.writeString(this.text);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<TextMacroAction text="${this.text}">`;
|
||||
}
|
||||
}
|
||||
103
src/config-serializer/config-items/UhkConfiguration.ts
Normal file
103
src/config-serializer/config-items/UhkConfiguration.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import {Serializable} from '../Serializable';
|
||||
import {ModuleConfigurations} from './ModuleConfigurations';
|
||||
import {Keymap} from './Keymap';
|
||||
import {Keymaps} from './Keymaps';
|
||||
import {Macro} from './Macro';
|
||||
import {Macros} from './Macros';
|
||||
import {UhkBuffer} from '../UhkBuffer';
|
||||
import {assertUInt8, assertUInt32} from '../assert';
|
||||
|
||||
export class UhkConfiguration extends Serializable<UhkConfiguration> {
|
||||
|
||||
signature: string;
|
||||
|
||||
@assertUInt8
|
||||
dataModelVersion: number;
|
||||
|
||||
@assertUInt32
|
||||
prologue: number;
|
||||
|
||||
@assertUInt8
|
||||
hardwareId: number;
|
||||
|
||||
@assertUInt8
|
||||
brandId: number;
|
||||
|
||||
moduleConfigurations: ModuleConfigurations;
|
||||
|
||||
keymaps: Keymaps;
|
||||
|
||||
macros: Macros;
|
||||
|
||||
@assertUInt32
|
||||
epilogue: number;
|
||||
|
||||
_fromJsObject(jsObject: any): UhkConfiguration {
|
||||
this.signature = jsObject.signature;
|
||||
this.dataModelVersion = jsObject.dataModelVersion;
|
||||
this.prologue = jsObject.prologue;
|
||||
this.hardwareId = jsObject.hardwareId;
|
||||
this.brandId = jsObject.brandId;
|
||||
this.moduleConfigurations = new ModuleConfigurations().fromJsObject(jsObject.moduleConfigurations);
|
||||
this.keymaps = new Keymaps().fromJsObject(jsObject.keymaps);
|
||||
this.macros = new Macros().fromJsObject(jsObject.macros);
|
||||
this.epilogue = jsObject.epilogue;
|
||||
return this;
|
||||
}
|
||||
|
||||
_fromBinary(buffer: UhkBuffer): UhkConfiguration {
|
||||
this.signature = buffer.readString();
|
||||
this.dataModelVersion = buffer.readUInt8();
|
||||
this.prologue = buffer.readUInt32();
|
||||
this.hardwareId = buffer.readUInt8();
|
||||
this.brandId = buffer.readUInt8();
|
||||
this.moduleConfigurations = new ModuleConfigurations().fromBinary(buffer);
|
||||
this.keymaps = new Keymaps().fromBinary(buffer);
|
||||
this.macros = new Macros().fromBinary(buffer);
|
||||
this.epilogue = buffer.readUInt32();
|
||||
return this;
|
||||
}
|
||||
|
||||
_toJsObject(): any {
|
||||
return {
|
||||
signature: this.signature,
|
||||
dataModelVersion: this.dataModelVersion,
|
||||
prologue: this.prologue,
|
||||
hardwareId: this.hardwareId,
|
||||
brandId: this.brandId,
|
||||
moduleConfigurations: this.moduleConfigurations.toJsObject(),
|
||||
keymaps: this.keymaps.toJsObject(),
|
||||
macros: this.macros.toJsObject(),
|
||||
epilogue: this.epilogue
|
||||
};
|
||||
}
|
||||
|
||||
_toBinary(buffer: UhkBuffer): void {
|
||||
buffer.writeString(this.signature);
|
||||
buffer.writeUInt8(this.dataModelVersion);
|
||||
buffer.writeUInt32(this.prologue);
|
||||
buffer.writeUInt8(this.hardwareId);
|
||||
buffer.writeUInt8(this.brandId);
|
||||
this.moduleConfigurations.toBinary(buffer);
|
||||
this.keymaps.toBinary(buffer);
|
||||
this.macros.toBinary(buffer);
|
||||
buffer.writeUInt32(this.epilogue);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<UhkConfiguration signature="${this.signature}">`;
|
||||
}
|
||||
|
||||
getKeymap(keymapId: number): Keymap {
|
||||
let keymaps: Keymap[] = this.keymaps.elements;
|
||||
for (let i = 0; i < keymaps.length; ++i) {
|
||||
if (keymapId === keymaps[i].id) {
|
||||
return keymaps[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getMacro(macroId: number): Macro {
|
||||
return this.macros.elements.find(macro => macroId === macro.id);
|
||||
}
|
||||
}
|
||||
164
src/config-serializer/config-schema.json
Normal file
164
src/config-serializer/config-schema.json
Normal file
@@ -0,0 +1,164 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "UHK Configuration",
|
||||
"description": "UHK Configuration",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"prologue": {
|
||||
"description": "Prologue",
|
||||
"type": "integer"
|
||||
},
|
||||
"keymaps": {
|
||||
"description": "Array of keymaps",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Id of the keymap",
|
||||
"type": "integer"
|
||||
},
|
||||
"isDefault": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"layers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"modules": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"keyActions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"keyActionType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"keystroke",
|
||||
"switchLayer",
|
||||
"switchKeymap",
|
||||
"playMacro",
|
||||
"mouse"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"keyActionType"
|
||||
],
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"keyActionType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"mouse"
|
||||
]
|
||||
},
|
||||
"mouseAction": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"leftClick",
|
||||
"middleClick",
|
||||
"rightClick",
|
||||
"moveUp",
|
||||
"moveDown",
|
||||
"moveLeft",
|
||||
"moveRight",
|
||||
"scrollUp",
|
||||
"scrollDown",
|
||||
"scrollLeft",
|
||||
"scrollRight",
|
||||
"accelerate",
|
||||
"decelerate"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"keyActionType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"keystroke"
|
||||
]
|
||||
},
|
||||
"scancode": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"keyActionType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"switchLayer"
|
||||
]
|
||||
},
|
||||
"layer": {
|
||||
"type": "string"
|
||||
},
|
||||
"toggle": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"keyActionType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"switchKeymap"
|
||||
]
|
||||
},
|
||||
"keymapId": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"keyActionType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"playMacro"
|
||||
]
|
||||
},
|
||||
"macroId": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"keyActionType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1071
src/config-serializer/uhk-config.json
Normal file
1071
src/config-serializer/uhk-config.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user