Rename model to config-serializer

This commit is contained in:
László Monda
2016-03-29 01:56:58 +02:00
parent d25910b969
commit ecb9d6f73c
14 changed files with 0 additions and 0 deletions

3
config-serializer/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
typings
uhk-config.bin
serializeConfig.js

8
config-serializer/.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"version": "0.1.0",
"command": "tsc",
"isShellCommand": true,
"showOutput": "silent",
"args": [],
"problemMatcher": "$tsc"
}

View File

@@ -0,0 +1,26 @@
class KeyAction {
static fromJsObject(jsObject: any): KeyAction {
switch (jsObject.keyActionType) {
case KeystrokeAction.actionTypeString:
return new KeystrokeAction().fromJsObject(jsObject);
case KeyActionNone.actionTypeString:
return new KeyActionNone().fromJsObject(jsObject);
default:
throw 'Invalid KeyAction.keyActionType: "${jsObject.actionType}"';
}
}
static fromBinary(buffer: UhkBuffer): KeyAction {
let keyActionFirstByte = buffer.readUInt8();
buffer.backtrack();
if (KeystrokeAction.isScancodeValid(keyActionFirstByte)) {
return new KeystrokeAction().fromBinary(buffer);
} else if (keyActionFirstByte === KeyActionNone.keyActionNoneId) {
return new KeyActionNone().fromBinary(buffer);
} else {
throw 'Invalid KeyAction first byte "${keyActionFirstByte}"';
}
}
}

View File

@@ -0,0 +1,38 @@
class KeyActionNone extends KeyAction implements Serializable<KeyActionNone> {
static actionTypeString = 'none';
static keyActionNoneId = 0;
static keyActionNoneParam = 0;
fromJsObject(jsObject: any): KeyActionNone {
if (jsObject.keyActionType !== KeyActionNone.actionTypeString) {
throw 'Invalid KeyActionNone.keyActionType: "${jsObject.keyActionType}"';
}
return this;
}
fromBinary(buffer: UhkBuffer): KeyActionNone {
let keyActionId = buffer.readUInt8();
if (keyActionId !== KeyActionNone.keyActionNoneId) {
throw 'Invalid KeyActionNone.id: ${keyActionId}';
}
let keyActionParam = buffer.readUInt8();
if (keyActionParam !== KeyActionNone.keyActionNoneParam) {
throw 'Invalid KeyActionNone.param: ${keyActionParam}';
}
return this;
}
toJsObject(): any {
return {
keyActionType: KeyActionNone.actionTypeString
};
}
toBinary(buffer: UhkBuffer) {
buffer.writeUInt8(KeyActionNone.keyActionNoneId);
buffer.writeUInt8(KeyActionNone.keyActionNoneParam);
}
}

View File

@@ -0,0 +1,50 @@
class KeystrokeAction extends KeyAction implements Serializable<KeystrokeAction> {
static actionTypeString = 'keystroke';
static firstValidScancode = 1;
static lastValidScancode = 231;
_scancode: number;
modifierMask: number;
get scancode() {
return this._scancode;
}
set scancode(value) {
if (!KeystrokeAction.isScancodeValid(value)) {
throw 'Invalid KeystrokeAction.scancode: ${scancode}';
}
this._scancode = value;
}
static isScancodeValid(scancode) {
return KeystrokeAction.firstValidScancode <= scancode &&
scancode <= KeystrokeAction.lastValidScancode;
}
fromJsObject(jsObject: any): KeystrokeAction {
this.scancode = jsObject.scancode;
this.modifierMask = jsObject.modifierMask;
return this;
}
fromBinary(buffer: UhkBuffer): KeystrokeAction {
this.scancode = buffer.readUInt8();
this.modifierMask = buffer.readUInt8();
return this;
}
toJsObject(): any {
return {
keyActionType: KeystrokeAction.actionTypeString,
scancode: this.scancode,
modifierMask: this.modifierMask
};
}
toBinary(buffer: UhkBuffer) {
buffer.writeUInt8(this.scancode);
buffer.writeUInt8(this.modifierMask);
}
}

View File

@@ -0,0 +1,6 @@
interface Serializable<T> {
fromJsObject(jsObject: any): T;
fromBinary(buffer: UhkBuffer): T;
toJsObject(): any;
toBinary(buffer: UhkBuffer);
}

View File

@@ -0,0 +1,127 @@
class UhkBuffer {
private static eepromSize = 32 * 1024;
private static maxStringByteLength = 0xFFFF;
private static longStringPrefix = 0xFF;
private static stringEncoding = 'utf8';
buffer: Buffer;
offset: number;
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.bytesToBacktrack = 1;
this.offset += this.bytesToBacktrack;
return value;
}
writeInt8(value: number): void {
this.buffer.writeInt8(value, this.offset);
this.offset += 1;
}
readUInt8(): number {
let value = this.buffer.readUInt8(this.offset);
this.bytesToBacktrack = 1;
this.offset += this.bytesToBacktrack;
return value;
}
writeUInt8(value: number): void {
this.buffer.writeUInt8(value, this.offset);
this.offset += 1;
}
readInt16(): number {
let value = this.buffer.readInt16LE(this.offset);
this.bytesToBacktrack = 2;
this.offset += this.bytesToBacktrack;
return value;
}
writeInt16(value: number): void {
this.buffer.writeInt16LE(value, this.offset);
this.offset += 2;
}
readUInt16(): number {
let value = this.buffer.readUInt16LE(this.offset);
this.bytesToBacktrack = 2;
this.offset += this.bytesToBacktrack;
return value;
}
writeUInt16(value: number): void {
this.buffer.writeUInt16LE(value, this.offset);
this.offset += 2;
}
readInt32(): number {
let value = this.buffer.readInt32LE(this.offset);
this.bytesToBacktrack = 4;
this.offset += this.bytesToBacktrack;
return value;
}
writeInt32(value: number): void {
this.buffer.writeInt32LE(value, this.offset);
this.offset += 4;
}
readUInt32(): number {
let value = this.buffer.readUInt32LE(this.offset);
this.bytesToBacktrack = 4;
this.offset += this.bytesToBacktrack;
return value;
}
writeUInt32(value: number): void {
this.buffer.writeUInt32LE(value, this.offset);
this.offset += 4;
}
readString(): string {
let stringByteLength = this.readUInt8();
if (stringByteLength === UhkBuffer.longStringPrefix) {
stringByteLength += this.readUInt8() << 8;
}
let str = this.buffer.toString(UhkBuffer.stringEncoding, this.offset, stringByteLength);
this.bytesToBacktrack = stringByteLength;
this.offset += stringByteLength;
return str;
}
writeString(str: string): void {
let stringByteLength = Buffer.byteLength(str, UhkBuffer.stringEncoding);
if (stringByteLength > UhkBuffer.maxStringByteLength) {
throw 'Cannot serialize string: ${stringByteLength} bytes is larger ' +
'than the maximum allowed length of ${UhkBuffer.maxStringByteLength} bytes';
}
if (stringByteLength >= UhkBuffer.longStringPrefix) {
this.writeUInt8(UhkBuffer.longStringPrefix);
this.writeUInt16(stringByteLength);
} else {
this.writeUInt8(stringByteLength);
}
this.buffer.write(str, this.offset, stringByteLength, UhkBuffer.stringEncoding);
this.offset += stringByteLength;
}
backtrack(): void {
this.offset -= this.bytesToBacktrack;
this.bytesToBacktrack = 0;
}
}

View File

@@ -0,0 +1,4 @@
{
"isKeymapsMenuExpanded": true,
"isMacrosMenuExpanded": true
}

View File

@@ -0,0 +1,138 @@
/// <reference path="Serializable.ts" />
/// <reference path="UhkBuffer.ts" />
/// <reference path="KeyAction.ts" />
/// <reference path="KeystrokeAction.ts" />
/// <reference path="KeyActionNone.ts" />
let fs = require('fs');
let writer = new UhkBuffer();
let uhkConfig = JSON.parse(fs.readFileSync('uhk-config.json'));
let keyActions = uhkConfig.keymaps[0].layers[0].modules[0].keyActions;
let ARRAY_LAST_ELEMENT_ID = 0;
let KEY_ACTION_ID_SWITCH_LAYER = 232;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_MOD = 233;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_FN = 234;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_MOUSE = 235;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_LEFT_CTRL = 236;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_LEFT_SHIFT = 237;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_LEFT_ALT = 238;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_LEFT_SUPER = 239;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_RIGHT_CTRL = 240;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_RIGHT_SHIFT = 241;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_RIGHT_ALT = 242;
let KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_RIGHT_SUPER = 243;
let KEY_ACTION_ID_MOUSE = 244;
let KEY_ACTION_ID_PLAY_MACRO = 245;
let KEY_ACTION_ID_SWITCH_KEYMAP = 246;
let KEY_ACTION_ID_NONE = 255;
let SWITCH_LAYER_MOD = 0;
let SWITCH_LAYER_FN = 1;
let SWITCH_LAYER_MOUSE = 2;
let SWITCH_LAYER_TOGGLE = 0x80;
let NONE_ACTION_PADDING = 0;
let MOUSE_ACTION_ID_LEFT_CLICK = 0;
let MOUSE_ACTION_ID_MIDDLE_CLICK = 1;
let MOUSE_ACTION_ID_RIGHT_CLICK = 2;
let MOUSE_ACTION_ID_MOVE_UP = 3;
let MOUSE_ACTION_ID_MOVE_DOWN = 4;
let MOUSE_ACTION_ID_MOVE_LEFT = 5;
let MOUSE_ACTION_ID_MOVE_RIGHT = 6;
let MOUSE_ACTION_ID_SCROLL_UP = 7;
let MOUSE_ACTION_ID_SCROLL_DOWN = 8;
let MOUSE_ACTION_ID_SCROLL_LEFT = 9;
let MOUSE_ACTION_ID_SCROLL_RIGHT = 10;
let MOUSE_ACTION_ID_ACCELERATE = 11;
let MOUSE_ACTION_ID_DECELERATE = 12;
function serializeKeyActions(keyActionsParam) {
keyActionsParam.forEach(function(keyAction) {
serializeKeyAction(keyAction);
});
writer.writeUInt8(ARRAY_LAST_ELEMENT_ID);
}
function serializeKeyAction(keyAction) {
switch (keyAction.actionType) {
case 'dualRoleKeystroke':
serializeDualRoleKeyAction(keyAction);
break;
case 'mouse':
serializeMouseAction(keyAction);
break;
case 'playMacro':
serializeMacroAction(keyAction);
break;
case 'switchKeymap':
serializeSwitchKeymapAction(keyAction);
break;
case 'switchLayer':
serializeSwitchLayerAction(keyAction);
break;
default:
throw 'KeyAction doesn\'t have a valid actionType property: ' + keyAction.actionType;
}
}
function serializeDualRoleKeyAction(dualRoleKeyAction) {
writer.writeUInt8({
mod : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_MOD,
fn : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_FN,
mouse : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_MOUSE,
leftControl : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_LEFT_CTRL,
leftShift : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_LEFT_SHIFT,
leftAlt : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_LEFT_ALT,
leftSuper : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_LEFT_SUPER,
rightControl: KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_RIGHT_CTRL,
rightShift : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_RIGHT_SHIFT,
rightAlt : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_RIGHT_ALT,
rightSuper : KEY_ACTION_ID_DUAL_ROLE_KEYSTROKE_RIGHT_SUPER
}[dualRoleKeyAction.longPressAction]);
writer.writeUInt8(dualRoleKeyAction.scancode);
}
function serializeMouseAction(mouseAction) {
writer.writeUInt8(KEY_ACTION_ID_MOUSE);
writer.writeUInt8({
leftClick : MOUSE_ACTION_ID_LEFT_CLICK,
middleClick: MOUSE_ACTION_ID_MIDDLE_CLICK,
rightClick : MOUSE_ACTION_ID_RIGHT_CLICK,
moveUp : MOUSE_ACTION_ID_MOVE_UP,
moveDown : MOUSE_ACTION_ID_MOVE_DOWN,
moveLeft : MOUSE_ACTION_ID_MOVE_LEFT,
moveRight : MOUSE_ACTION_ID_MOVE_RIGHT,
scrollUp : MOUSE_ACTION_ID_SCROLL_UP,
scrollDown : MOUSE_ACTION_ID_SCROLL_DOWN,
scrollLeft : MOUSE_ACTION_ID_SCROLL_LEFT,
scrollRight: MOUSE_ACTION_ID_SCROLL_RIGHT,
accelerate : MOUSE_ACTION_ID_ACCELERATE,
decelerate : MOUSE_ACTION_ID_DECELERATE
}[mouseAction.mouseAction]);
}
function serializeMacroAction(macroAction) {
writer.writeUInt8(KEY_ACTION_ID_PLAY_MACRO);
writer.writeUInt8(macroAction.macroId);
}
function serializeSwitchKeymapAction(switchKeymapAction) {
writer.writeUInt8(KEY_ACTION_ID_SWITCH_KEYMAP);
writer.writeUInt8(switchKeymapAction.keymapId);
}
function serializeSwitchLayerAction(switchLayerAction) {
writer.writeUInt8(KEY_ACTION_ID_SWITCH_LAYER);
writer.writeUInt8({
mod : SWITCH_LAYER_MOD,
fn : SWITCH_LAYER_FN,
mouse: SWITCH_LAYER_MOD
}[switchLayerAction] | switchLayerAction.toggle ? SWITCH_LAYER_TOGGLE : 0);
}
//serializeKeyActions(keyActions);
fs.writeFileSync('uhk-config.bin', writer.buffer);

View File

@@ -0,0 +1,10 @@
{
"compilerOptions": {
"out": "serializeConfig.js",
"target": "es5"
},
"files": [
"typings/main.d.ts",
"serializeConfig.ts"
]
}

View File

@@ -0,0 +1,100 @@
{
"rules": {
"member-ordering": [
true,
"public-before-private",
"static-before-instance",
"variables-before-functions"
],
"no-inferrable-types": true,
"no-internal-module": true,
"curly": true,
"no-construct": true,
"no-duplicate-key": true,
"no-duplicate-variable": true,
"no-eval": true,
"no-null-keyword": true,
"no-shadowed-variable": true,
"no-string-literal": true,
"no-switch-case-fall-through": true,
"no-unreachable": true,
"no-unused-expression": true,
"no-unused-variable": [
true,
"check-parameters"
],
"no-use-before-declare": true,
"no-var-keyword": true,
"radix": true,
"switch-default": true,
"triple-equals": true,
"eofline": true,
"indent": [
true,
"spaces"
],
"max-line-length": [
true,
120
],
"no-trailing-whitespace": true,
"trailing-comma": [
true, {
"multiline": "never",
"singleline": "never"
}
],
"align": [
true,
"parameters",
"arguments",
"statements"
],
"comment-format": [
true,
"check-space",
"check-uppercase"
],
"no-consecutive-blank-lines": true,
"one-line": [
true,
"check-open-brace",
"check-whitespace"
],
"quotemark": [
true,
"single"
],
"semicolon": [
true,
"always"
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"variable-name": [
true,
"ban-keywords",
"check-format",
"allow-leading-underscore"
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type",
"check-typecast"
]
}
}

View File

@@ -0,0 +1,5 @@
{
"ambientDependencies": {
"node": "registry:dt/node#4.0.0+20160319033040"
}
}

View File

@@ -0,0 +1,156 @@
{
"signature": "UHK",
"prologue": 1234678,
"hardwareId": 0,
"brandId": 0,
"dataModelVersion": 0,
"moduleConfigurations": [
{
"id": 1,
"initialSpeed": 1,
"acceleration": 5,
"maxSpeed": 200
}
],
"keymaps": [
{
"id": 0,
"isDefault": true,
"name": "QWERTY",
"abbreviation": "QTY",
"layers": [
{
"modules": [
{
"id": 0,
"pointerRoles": [
"move"
],
"keyActions": [
{
"keyActionType": "none"
},
{
"keyActionType": "keystroke",
"scancode": 120,
"modifierMask": 16
},
{
"keyActionType": "switchLayer",
"layer": "fn",
"toggle": false
},
{
"keyActionType": "dualRoleKeystroke",
"scancode": 111,
"longPressAction": "mod"
},
{
"keyActionType": "mouse",
"mouseAction": "scrollDown"
},
{
"keyActionType": "playMacro",
"macroId": 0
},
{
"keyActionType": "switchKeymap",
"keymapId": 1
}
]
},
{
"id": 1
},
{
"id": 2,
"pointerRoles": [
"scroll"
],
"keyActions": []
},
{
"id": 3,
"pointerRoles": [
"move"
],
"keyActions": []
}
]
},
{},
{},
{}
]
},
{
"id": 1,
"name": "Dvorak"
}
],
"macros": [
{
"id": 0,
"name": "My address",
"isPrivate": true,
"isLooped": false,
"macroActions": [
{
"macroActionType": "pressKey",
"scancode": 111
},
{
"macroActionType": "holdKey",
"scancode": 111
},
{
"macroActionType": "releaseKey",
"scancode": 111
},
{
"macroActionType": "pressModifiers",
"modifierMask": 111
},
{
"macroActionType": "holdModifiers",
"modifierMask": 111
},
{
"macroActionType": "releaseModifiers",
"modifierMask": 111
},
{
"macroActionType": "pressMouseButtons",
"mouseButtonsMask": 9
},
{
"macroActionType": "holdMouseButtons",
"mouseButtonsMask": 9
},
{
"macroActionType": "releaseMouseButtons",
"mouseButtonsMask": 9
},
{
"macroActionType": "moveMouse",
"x": 123,
"y": 123
},
{
"macroActionType": "scrollMouse",
"x": 123,
"y": 123
},
{
"macroActionType": "delay",
"delay": "1000"
},
{
"macroActionType": "text",
"text": "this is a text"
}
]
}
],
"epilogue": 1234678
}

View File

@@ -0,0 +1,24 @@
{
"isKeyboardMerged": false,
"moduleSlots": [
{
"id": true,
"name": "keycluster-left",
"factoryKeymap": {
"layers": [
{
"pointerRoles": [],
"keyStates": []
},
{},
{},
{}
]
}
},
{},
{},
{},
{}
]
}