ui working

;
materials
Bronwen 2021-07-25 13:57:47 -04:00
parent 6a56a70b9c
commit 18ad39f6af
19 changed files with 1509 additions and 125 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@ node_modules
out
data
*.log
bin

43
.vscode/tasks.json vendored
View File

@ -2,9 +2,9 @@
"version": "2.0.0",
"tasks": [
{
"label": "build",
"label": "tsc",
"type": "npm",
"script": "compile:watch",
"script": "tsc:watch",
"isBackground": true,
"group": {
"kind": "build",
@ -17,12 +17,49 @@
"reveal": "never",
"echo": false,
"focus": false,
"panel": "dedicated"
"panel": "shared",
"group": "main"
},
"problemMatcher": {
"base": "$tsc-watch",
"applyTo": "allDocuments"
}
},
{
"label": "dev",
"type": "npm",
"script": "dev",
"isBackground": true,
"group": "build",
"runOptions": {
"runOn": "folderOpen"
},
"presentation": {
"reveal": "never",
"echo": false,
"focus": false,
"panel": "shared",
"group": "main"
},
"problemMatcher": []
},
{
"label": "rollup",
"type": "npm",
"script": "rollup:watch",
"isBackground": true,
"group": "build",
"runOptions": {
"runOn": "folderOpen"
},
"presentation": {
"reveal": "never",
"echo": false,
"focus": false,
"panel": "shared",
"group": "main"
},
"problemMatcher": []
}
]
}

10
babel.config.json 100644
View File

@ -0,0 +1,10 @@
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
]
}

View File

@ -1,40 +0,0 @@
import path from 'path';
const moduleAliases = {
"@themes": "./out/src/registries/Themes.js",
"@actions": "./out/src/registries/Actions.js",
"@tasks": "./out/src/registries/Tasks.js",
"@items": "./out/src/registries/Items.js",
"@world": "./out/src/World.js",
// "@ui": "./out/src/term-ui/UI.js",
"@ui": "./out/src/qt/index.js",
"@game": "./out/src/Game.js"
};
const getAliases = () => {
const base = process.cwd();
const aliases = moduleAliases || {};
const absoluteAliases = Object.keys(aliases).reduce((acc, key) =>
aliases[key][0] === '/'
? acc
: { ...acc, [key]: 'file:///' + path.join(base, aliases[key]) },
aliases)
return absoluteAliases;
}
const isAliasInSpecifier = (path, alias) => {
return path.indexOf(alias) === 0
&& (path.length === alias.length || path[alias.length] === '/')
}
const aliases = getAliases();
export const resolve = (specifier, parentModuleURL, defaultResolve) => {
const alias = Object.keys(aliases).find((key) => isAliasInSpecifier(specifier, key));
const newSpecifier = alias === undefined
? specifier
: path.join(aliases[alias], specifier.substr(alias.length));
return defaultResolve(newSpecifier, parentModuleURL);
}

View File

@ -5,7 +5,11 @@
"license": "MIT",
"type": "module",
"dependencies": {
"@nodegui/nodegui": "^0.33.3",
"@babel/core": "^7.14.8",
"@babel/preset-env": "^7.14.8",
"@nodegui/nodegui": "^0.34.0",
"@rollup/plugin-alias": "^3.1.4",
"@rollup/plugin-babel": "^5.3.0",
"@types/blessed": "^0.1.17",
"@types/bonjour": "^3.5.8",
"@types/chai": "^4.2.19",
@ -28,11 +32,13 @@
"get-port": "^5.1.1",
"mocha": "^9.0.1",
"module-alias": "^2.2.2",
"multiview": "^3.0.1",
"neo-blessed": "^0.2.0",
"node-dev": "^7.0.0",
"node-ipc": "^10.0.2",
"nodemon": "^2.0.7",
"printable-characters": "^1.0.42",
"rollup": "^2.53.3",
"sisteransi": "^1.0.5",
"supervisor": "^0.12.0",
"typescript": "^4.3.2",
@ -43,15 +49,19 @@
"yarn": "^1.22.10"
},
"scripts": {
"compile:watch": "tsc --watch",
"start": "yarn x out/src/index.js",
"dev": "yarn x out/src/hot-index.js",
"compile": "yarn tsc & yarn rollup",
"start": "yarn qode bin/app.bundle.js",
"dev": "yarn x bin/ipc-tower.bundle.js",
"prod": "git fetch && git pull && yarn && tsc && yarn start",
"test": "mocha",
"lint": "eslint src/**/*.ts",
"web": "web-dev-server --open index.html --node-resolve --watch",
"profile": "node --inspect-brk --no-warnings --loader ./lib/aliases.mjs --enable-source-maps out/src/index.js",
"qx": "qode --no-warnings --loader ./lib/aliases.mjs",
"x": "node --no-warnings --loader ./lib/aliases.mjs"
"profile": "yarn qode --inspect-brk bin/app.bundle.js",
"qode": "qode",
"x": "node",
"tsc": "tsc",
"tsc:watch": "yarn tsc --watch",
"rollup": "rollup --config rollup.config.js",
"rollup:watch": "yarn rollup --watch"
}
}

15
perf.js
View File

@ -1,15 +0,0 @@
console.clear();
const n = 10 ** 8;
// const map = new Map();
console.log('sequential insertion');
for(let run = 0; run < 10; run ++) {
const arr = [];
console.time('array');
for(let i = 0; i < n; i ++) {
arr.push(133769420)
}
console.timeEnd('array')
}

46
rollup.config.js 100644
View File

@ -0,0 +1,46 @@
import alias from '@rollup/plugin-alias';
import { dirname, resolve } from 'path';
import { fileURLToPath } from 'url';
import tsconfig from './tsconfig.json';
const __dirname = dirname(fileURLToPath(import.meta.url));
const aliases = Object.entries(tsconfig.compilerOptions.paths).map(([name, [path]]) => {
return {
find: name,
replacement: resolve(__dirname, 'out', path) + '.js'
};
});
const shared = {
plugins: [
alias({
entries: [
...aliases,
{ find: 'frigid', replacement: resolve(__dirname, 'node_modules/frigid/out/index.js') }
]
})
],
watch: {
include: 'out/**/*'
}
}
export default [
{
...shared,
input: './out/src/index.js',
output: {
file: 'bin/app.bundle.js',
format: 'es'
}
},
{
...shared,
input: './out/src/hot-index.js',
output: {
file: 'bin/ipc-tower.bundle.js',
format: 'es'
}
}
];

View File

@ -1,8 +1,10 @@
export const IPC_PATH = '/tmp/dfi.dev';
export const IPC_CLIENT_APPSAPCE = 'dfi.';
export const IPC_CLIENT_CONNECT_NAME = 'dev';
export const IPC_QUIT_EVENT = 'app.quit';
export const IPC_RESTART_EVENT = 'app.restart';
export const IPC_REQUEST_RESTART = 'app.request-restart';
export const MDNS_TYPE = 'hdn';
export const APPLICATION_NAME = 'Hadean'

View File

@ -1,5 +1,4 @@
import { Frigid, Serializable } from 'frigid';
import { DEBUG } from 'frigid/out/Serializable.js';
import { Pawn } from './Pawn.js';
import { TaskList } from './TaskList.js';
import { Inventory } from './Inventory.js';
@ -20,8 +19,6 @@ export class Game extends Frigid implements Tickable {
name: string;
world: World;
[DEBUG] = true;
static get current(): Game {
if (!game) throw new Error('Somehow called a game before it existed?');
return game;

View File

@ -1,23 +1,17 @@
import EventEmitter from 'events';
import ipc from 'node-ipc';
import {
IPC_CLIENT_CONNECT_NAME,
IPC_CLIENT_APPSAPCE,
IPC_QUIT_EVENT,
IPC_RESTART_EVENT
IPC_RESTART_EVENT,
IPC_REQUEST_RESTART
} from './Constants.js';
const name = IPC_CLIENT_CONNECT_NAME;
ipc.config.appspace = IPC_CLIENT_APPSAPCE;
ipc.config.silent = true;
let connected = false;
ipc.connectTo(name, () => {
ipc.of[name].on('connect', () => connected = true);
ipc.of[name].on('disconnect', () => connected = false);
});
export function quit() {
class ProcessManagerClass extends EventEmitter {
quit() {
if (connected) {
ipc.of[name].emit(IPC_QUIT_EVENT);
} else {
@ -25,10 +19,25 @@ export function quit() {
}
}
export function restart() {
restart() {
if (connected) {
ipc.of[name].emit(IPC_RESTART_EVENT);
} else {
process.exit(1);
}
}
}
export const ProcessManager = new ProcessManagerClass();
const name = IPC_CLIENT_CONNECT_NAME;
ipc.config.appspace = IPC_CLIENT_APPSAPCE;
ipc.config.silent = true;
ipc.connectTo(name, () => {
ipc.of[name].on('connect', () => connected = true);
ipc.of[name].on('disconnect', () => connected = false);
ipc.of[name].on(IPC_REQUEST_RESTART, () => {
ProcessManager.emit('reload');
})
});

View File

@ -2,17 +2,18 @@ import ipc from 'node-ipc';
import {
IPC_PATH,
IPC_QUIT_EVENT,
IPC_RESTART_EVENT
IPC_RESTART_EVENT,
IPC_REQUEST_RESTART
} from './Constants.js';
import { spawn, ChildProcess } from 'child_process';
import watch from 'watch';
import chalk from 'chalk';
ipc.config.silent = true;
const exec = 'qode';
const exec = 'yarn';
const args = [
...process.execArgv,
'out/src/index.js'
'start'
]
ipc.serve(IPC_PATH, () => {
@ -29,10 +30,10 @@ ipc.server.start();
let proc: ChildProcess = null;
function startProcess() {
console.log('starting process...');
proc = spawn(exec, args, {
stdio: 'inherit'
});
console.log(`[${proc.pid}] ${chalk.grey(`${exec} ${args.join(' ')}`)}`);
proc.on('exit', () => {
console.log('process died');
proc = null;
@ -68,9 +69,9 @@ function fileChange() {
// console.log(cluster.isMaster, evt, path);
if(restartTimer) clearTimeout(restartTimer)
restartTimer = setTimeout(() => {
restart();
ipc.server.broadcast(IPC_REQUEST_RESTART);
restartTimer = null;
}, 1000);
}
// chokidar.watch('./out').on('all', fileChange);
watch.watchTree('./out', fileChange);
watch.watchTree('./bin', fileChange);

View File

@ -43,7 +43,6 @@ ensureDirSync(parse(saveFile).dir);
for (let seconds = 0; seconds > 0; seconds --) {
process.stdout.write('Starting ' + APPLICATION_NAME + ' in ' + seconds + '\r');
await new Promise(res => setTimeout(res, 1000));
}
process.stdout.write('Starting ' + APPLICATION_NAME + ' in ' + 0 + '\n');
// console.clear();

View File

@ -11,6 +11,7 @@ import { inspect } from 'util'
import { Pawn } from '../Pawn.js';
import { Game } from '../Game.js';
import { Player } from './Player.js';
import { MDNS_TYPE } from '../Constants.js';
const mdns = bonjour();
const ID = uuid.v4();
@ -32,7 +33,7 @@ export default network;
export async function ready(name: string) {
const port = await getPort({port: getPort.makeRange(52300, 52399)});
mdns.publish({
type: 'dfi',
type: MDNS_TYPE,
name,
port: port
});
@ -64,7 +65,7 @@ export async function ready(name: string) {
}
mdns.find({
type: 'dfi'
type: MDNS_TYPE
}, (service) => {
const p = new Player();
p.name = service.name;

View File

@ -1,5 +1,10 @@
import { Game } from '@game';
import { QLabel, QWidget } from '@nodegui/nodegui';
import {
QLabel,
QTabWidget,
QWidget,
QIcon
} from '@nodegui/nodegui';
import { View } from './View.js';
// 40x30
@ -9,14 +14,14 @@ export class GameView extends View {
game: Game;
title: QLabel;
left: QWidget;
right: QWidget;
right: QTabWidget;
addComponents(): void {
this.addLayout();
this.title = new QLabel();
this.left = new QWidget();
this.right = new QWidget();
this.right = new QTabWidget();
this.title.setText(this.game.name);
@ -29,6 +34,14 @@ export class GameView extends View {
this.layout.addWidget(this.title, 0, 0, 1, w);
this.layout.addWidget(this.left, 1, 0, h - 1, w / 2);
this.layout.addWidget(this.right, 1, w / 2, h - 1, w / 2);
const page1 = new QLabel();
page1.setText('Page 1');
const page2 = new QLabel();
page2.setText('Page 2');
this.right.addTab(page1, new QIcon(), "Page 1");
this.right.addTab(page2, new QIcon(), "Page 2");
}
constructor(game: Game) {
@ -36,3 +49,4 @@ export class GameView extends View {
this.game = game;
}
}

View File

@ -0,0 +1,26 @@
import { QGridLayout, QLabel, QMainWindow, QPushButton, QWidget } from "@nodegui/nodegui";
import { ProcessManager } from "../ProcessManager";
export class RequestReloadPopup {
static show() {
const window = new QMainWindow();
window.setFixedSize(200, 100);
const root = new QWidget();
window.setCentralWidget(root);
const layout = new QGridLayout();
root.setLayout(layout);
const label = new QLabel();
label.setText('A reload has been requested');
layout.addWidget(label, 0, 0, 4, 3);
const reloadButton = new QPushButton();
reloadButton.setText('Reload');
layout.addWidget(reloadButton, 4, 2, 1, 1);
window.show();
reloadButton.addEventListener('clicked', () => {
ProcessManager.restart();
})
}
}
//

View File

@ -2,7 +2,9 @@ import {
QMainWindow, WidgetEventTypes
} from '@nodegui/nodegui';
import { APPLICATION_NAME } from '../Constants.js';
import { ProcessManager } from '../ProcessManager.js';
import { LoadingView } from './LoadingView.js';
import { RequestReloadPopup } from './RequestReloadPopup.js';
import { View } from './View.js';
export { GameView } from './GameView.js';
export { Popup } from './Popup.js';
@ -26,13 +28,27 @@ win.setStyleSheet(`
font-family: 'MxPlus IBM VGA 8x16';
font-size: 16px;
}
QTabWidget {
border: 1px solid white;
}
QTabWidget::pane {
background: black;
border: none;
border-radius: 0px;
}
QTabBar::tab {
background: black;
color: cyan;
padding: 4px 12px;
}
QTabBar::tab:selected {
background: cyan;
color: black;
}
`);
win.show();
(global as any).win = win;
win.addEventListener(WidgetEventTypes.Paint, _ => _);
win.addEventListener(WidgetEventTypes.UpdateRequest, () => {
console.log('sdfghj');
});
win.addEventListener('customContextMenuRequested', console.log)
win.addEventListener('objectNameChanged', console.log)
win.addEventListener('windowIconChanged', console.log)
@ -64,6 +80,11 @@ export function isStarted() {
return win.isVisible();
}
ProcessManager.on('reload', () => {
RequestReloadPopup.show();
//
})
// HACK this is bullshit, :)
function f() {

View File

@ -2,7 +2,7 @@ import { Game } from "@game";
import { boxStyle, getTheme } from "@themes";
import { panels } from "./UI.js";
import blessed from 'neo-blessed';
import { quit, restart } from "../ProcessManager.js";
import { ProcessManager } from "../ProcessManager.js";
// TODO convert all these popup-y things to be View based
// make them be boxes that have a view
@ -45,12 +45,12 @@ export class EscapeMenu {
break;
}
case 1: {
restart();
ProcessManager.restart();
break;
}
case 2: {
Game.current.sync();
quit();
ProcessManager.quit();
}
}
} else if(key.full === 'escape') {

1289
yarn.lock

File diff suppressed because it is too large Load Diff