Logging handlers can now be adapted to special needs
This commit is contained in:
parent
9042579518
commit
1480ad8145
55
dist/iwmlib.js
vendored
55
dist/iwmlib.js
vendored
@ -1545,14 +1545,34 @@
|
||||
|
||||
}
|
||||
|
||||
/* eslint-disable no-undef */
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-unused-vars */
|
||||
let ipc = null;
|
||||
let logMessages = new Set();
|
||||
let logHandlers = {
|
||||
log: console.log,
|
||||
warn: console.warn,
|
||||
error: console.error
|
||||
};
|
||||
|
||||
try {
|
||||
ipc = require('electron').ipcRenderer;
|
||||
} catch (e) {}
|
||||
logHandlers.log = message => ipc.send('log', message);
|
||||
logHandlers.warn = message => ipc.send('warn', message);
|
||||
logHandlers.error = message => ipc.send('error', message);
|
||||
} catch (e) {
|
||||
console.log('Cannot use electron logging.');
|
||||
}
|
||||
|
||||
/** Basic class for app specific logging requirements.
|
||||
* Can be used to implement persistent logging in electron apps.
|
||||
* Uses a logMessage cache to prevent error overflows. This is
|
||||
* needed since errors may occur very frequently
|
||||
* (e.g. display update loops at 60fps, programmatic loops, ...).
|
||||
*
|
||||
* The logging handlers can be overwritten by calling the static
|
||||
* setup method.
|
||||
*/
|
||||
class Logging {
|
||||
|
||||
@ -1560,13 +1580,38 @@
|
||||
* @param {*} message
|
||||
*/
|
||||
static log(message) {
|
||||
logHandlers.log(message);
|
||||
}
|
||||
|
||||
if (ipc) {
|
||||
ipc.send('log', message);
|
||||
} else {
|
||||
console.log(message);
|
||||
/**
|
||||
* Static warn function.
|
||||
* Emits each warning only once per session.
|
||||
* @param {*} message
|
||||
*/
|
||||
static warn(message) {
|
||||
if (!logMessages.has(message)) {
|
||||
logMessages.add(message);
|
||||
logHandlers.warn(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static error function.
|
||||
* Emits each error message only once per session.
|
||||
* @param {*} message
|
||||
*/
|
||||
static error(message) {
|
||||
if (!logMessages.has(message)) {
|
||||
logMessages.add(message);
|
||||
logHandlers.error(message);
|
||||
}
|
||||
}
|
||||
|
||||
static setup({log=console.log, warn=console.warn, error=console.error} = {}) {
|
||||
logHandlers.log = log;
|
||||
logHandlers.warn = warn;
|
||||
logHandlers.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
/* globals Hammer, propagating */
|
||||
|
198
dist/iwmlib.pixi.js
vendored
198
dist/iwmlib.pixi.js
vendored
@ -4709,28 +4709,73 @@
|
||||
// }
|
||||
}
|
||||
|
||||
/* eslint-disable no-undef */
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-unused-vars */
|
||||
let ipc = null;
|
||||
let logMessages = new Set();
|
||||
let logHandlers = {
|
||||
log: console.log,
|
||||
warn: console.warn,
|
||||
error: console.error
|
||||
};
|
||||
|
||||
try {
|
||||
ipc = require('electron').ipcRenderer;
|
||||
} catch (e) {}
|
||||
logHandlers.log = message => ipc.send('log', message);
|
||||
logHandlers.warn = message => ipc.send('warn', message);
|
||||
logHandlers.error = message => ipc.send('error', message);
|
||||
} catch (e) {
|
||||
console.log('Cannot use electron logging.');
|
||||
}
|
||||
|
||||
/** Basic class for app specific logging requirements.
|
||||
* Can be used to implement persistent logging in electron apps.
|
||||
* Uses a logMessage cache to prevent error overflows. This is
|
||||
* needed since errors may occur very frequently
|
||||
* (e.g. display update loops at 60fps, programmatic loops, ...).
|
||||
*
|
||||
* The logging handlers can be overwritten by calling the static
|
||||
* setup method.
|
||||
*/
|
||||
class Logging {
|
||||
class Logging$1 {
|
||||
|
||||
/** Static log function.
|
||||
* @param {*} message
|
||||
*/
|
||||
static log(message) {
|
||||
logHandlers.log(message);
|
||||
}
|
||||
|
||||
if (ipc) {
|
||||
ipc.send('log', message);
|
||||
} else {
|
||||
console.log(message);
|
||||
/**
|
||||
* Static warn function.
|
||||
* Emits each warning only once per session.
|
||||
* @param {*} message
|
||||
*/
|
||||
static warn(message) {
|
||||
if (!logMessages.has(message)) {
|
||||
logMessages.add(message);
|
||||
logHandlers.warn(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Static error function.
|
||||
* Emits each error message only once per session.
|
||||
* @param {*} message
|
||||
*/
|
||||
static error(message) {
|
||||
if (!logMessages.has(message)) {
|
||||
logMessages.add(message);
|
||||
logHandlers.error(message);
|
||||
}
|
||||
}
|
||||
|
||||
static setup({log=console.log, warn=console.warn, error=console.error} = {}) {
|
||||
logHandlers.log = log;
|
||||
logHandlers.warn = warn;
|
||||
logHandlers.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
/* globals Hammer, propagating */
|
||||
@ -5676,7 +5721,7 @@
|
||||
let size = this.interaction.current.size;
|
||||
let limit = this.logInteractionsAbove;
|
||||
if (size > limit) {
|
||||
Logging.log(`Number of interactions ${size} exceeds ${limit}`);
|
||||
Logging$1.log(`Number of interactions ${size} exceeds ${limit}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7805,10 +7850,12 @@
|
||||
/* globals PIXI, console*/
|
||||
|
||||
const registeredTiles = new Map();
|
||||
// const pendingTiles = new Map()
|
||||
/** Implements a baseTexture cache. The last textures are kept for reuse */
|
||||
let keepTextures = 0;
|
||||
const keptTextures = [];
|
||||
const lateTextures = new Map();
|
||||
let lastSweepTime = 0;
|
||||
let sweepInterval = 2000.0;
|
||||
|
||||
/** The current Tile implementation simply uses PIXI.Sprites.
|
||||
*
|
||||
@ -7833,43 +7880,6 @@
|
||||
keepTextures = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the given url as pending. Pending tiles should not be destroyed
|
||||
*
|
||||
* @static
|
||||
* @param {*} url
|
||||
* @memberof Tile
|
||||
*/
|
||||
/* static schedule(url) {
|
||||
let count = 0
|
||||
if (pendingTiles.has(url)) {
|
||||
count = pendingTiles.get(url)
|
||||
}
|
||||
pendingTiles.set(url, count + 1)
|
||||
// console.log("Tile.scheduled", url, pendingTiles.size)
|
||||
} */
|
||||
|
||||
/**
|
||||
* Removes the given url from pending urls.
|
||||
*
|
||||
* @static
|
||||
* @param {*} url
|
||||
* @memberof Tile
|
||||
*/
|
||||
/* static unschedule(url) {
|
||||
if (pendingTiles.has(url)) {
|
||||
let count = pendingTiles.get(url)
|
||||
if (count > 1) {
|
||||
pendingTiles.set(url, count - 1)
|
||||
}
|
||||
else {
|
||||
pendingTiles.clear(url)
|
||||
}
|
||||
}
|
||||
// console.log("Tile.unscheduled", url, pendingTiles.size)
|
||||
} */
|
||||
|
||||
|
||||
/**
|
||||
* Returns true iff the url is pending
|
||||
*
|
||||
@ -8001,14 +8011,60 @@
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized renderWebGL to avoid freezing system
|
||||
*
|
||||
* @param {*} renderer
|
||||
* @memberof Tile
|
||||
*/
|
||||
renderWebGL(renderer) {
|
||||
try {
|
||||
super.renderWebGL(renderer);
|
||||
}
|
||||
catch (e) {
|
||||
// We want persistent logging here
|
||||
Logging.error("Error in Tile.renderWebGL: " + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes lately arrived texture if they have not been touched in the meanwhile.
|
||||
*
|
||||
* @static
|
||||
* @memberof Tile
|
||||
*/
|
||||
static sweepLateTextures() {
|
||||
let now = performance.now();
|
||||
if (now > lastSweepTime + sweepInterval) {
|
||||
lastSweepTime = now;
|
||||
let count = 0;
|
||||
for (let [url, texture] of lateTextures.entries()) {
|
||||
if (texture) {
|
||||
let base = texture.baseTexture;
|
||||
if (base != null && base.touched == 0) {
|
||||
texture.destroy(true);
|
||||
//console.info("Sweeping ", url)
|
||||
count += 1;
|
||||
lateTextures.delete(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count > 0)
|
||||
console.log("Sweeping textures", count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Texture received too late. We do not need it.
|
||||
* @param {*} url
|
||||
* @param {*} texture
|
||||
*/
|
||||
static lateTexture(url, texture) {
|
||||
let destroyBase = !registeredTiles.has(url);
|
||||
texture.destroy(destroyBase);
|
||||
lateTextures.set(url, texture);
|
||||
//console.warn("Tile.lateTexture")
|
||||
// We cannot destroy the texture since we got errors in t.renderWebGL.
|
||||
// Perhaps we can destroy unsed textures later on
|
||||
Tile.sweepLateTextures();
|
||||
}
|
||||
|
||||
static printInfos() {
|
||||
@ -11811,6 +11867,10 @@
|
||||
return ['decade', 'year', 'month', 'day', 'hour', 'minute', 'second']
|
||||
}
|
||||
|
||||
static get largeTickSize() {
|
||||
return 4.2
|
||||
}
|
||||
|
||||
get minWidth() {
|
||||
return 10
|
||||
}
|
||||
@ -11885,7 +11945,7 @@
|
||||
return date.toLocaleDateString('de', format)
|
||||
}
|
||||
|
||||
draw(timeline, range, width, height, available, format, nextFormat, level) {
|
||||
draw(timeline, range, width, height, available, format, nextFormat, level, extraTicks=false) {
|
||||
let first = null;
|
||||
let last = null;
|
||||
let keyedFormat = (format) ? format[this.formatKey] : null;
|
||||
@ -11893,7 +11953,6 @@
|
||||
let redundant = (nextFormat) ? this.formatKey in nextFormat : false;
|
||||
let fullyRedundant = keyedFormat != null && keyedFormat == keyedNextFormat;
|
||||
let y = timeline.getY();
|
||||
|
||||
for (let { start, end } of this.iterRanges(range)) {
|
||||
let x = timeline.toX(start);
|
||||
let xx = x;
|
||||
@ -11902,11 +11961,10 @@
|
||||
let key = this.dateKey(start);
|
||||
let text = this.toLocaleString(start, format);
|
||||
let align = 'center';
|
||||
let downTick = false;
|
||||
if (nextFormat) {
|
||||
yy = y + timeline.tickLabelOffset(-1, 1);
|
||||
align = 'left';
|
||||
timeline.drawTick(x, 4.2);
|
||||
timeline.drawTick(x, Ticks.largeTickSize);
|
||||
let nextX = timeline.toX(end) - 100;
|
||||
if (x < 0 && nextX > -100 && !redundant) {
|
||||
xx = Math.min(4, nextX);
|
||||
@ -11914,20 +11972,18 @@
|
||||
else {
|
||||
xx -= 2;
|
||||
}
|
||||
downTick = true;
|
||||
}
|
||||
else if (level > 0) {
|
||||
xx = x + available / 2;
|
||||
}
|
||||
else {
|
||||
downTick = true;
|
||||
}
|
||||
|
||||
if (!fullyRedundant) {
|
||||
timeline.ensureLabel(key, text,
|
||||
{ x: xx, y: yy, align },
|
||||
FontInfo.small);
|
||||
}
|
||||
if (downTick) timeline.drawTick(x, -1);
|
||||
if (extraTicks)
|
||||
timeline.drawTick(x, -level);
|
||||
}
|
||||
if (timeline.visibleRange(start, end)) {
|
||||
if (first == null)
|
||||
@ -11939,6 +11995,15 @@
|
||||
return null
|
||||
return { start: first, end: last }
|
||||
}
|
||||
|
||||
drawExtra(timeline, range, size) {
|
||||
for (let { start } of this.iterRanges(range)) {
|
||||
if (timeline.visibleDate(start)) {
|
||||
let x = timeline.toX(start);
|
||||
timeline.drawTick(x, -size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DecadeTicks extends Ticks {
|
||||
@ -12125,15 +12190,34 @@
|
||||
visible.push(ticks);
|
||||
}
|
||||
let level = 0;
|
||||
let ranges = [];
|
||||
for (let ticks of visible) {
|
||||
if (range == null)
|
||||
return
|
||||
continue
|
||||
range = ticks.draw(timeline, range, width, height,
|
||||
availables.get(ticks),
|
||||
formats.get(ticks),
|
||||
nextFormats.get(ticks), level);
|
||||
if (range) {
|
||||
ranges.push({ticks, range});
|
||||
}
|
||||
level += 1;
|
||||
}
|
||||
|
||||
let extraLevel = ranges.length - 1;
|
||||
let extraStart = extraLevel;
|
||||
for(let {ticks, range} of ranges) {
|
||||
ticks.drawExtra(timeline, range, extraLevel);
|
||||
extraLevel -= 1;
|
||||
if (extraLevel <= 0) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
timeline.drawTick(start, Ticks.largeTickSize);
|
||||
timeline.drawTick(start, -extraStart);
|
||||
timeline.drawTick(end, Ticks.largeTickSize);
|
||||
timeline.drawTick(end, -extraStart);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,15 +8,26 @@
|
||||
<link rel="stylesheet" href="../css/doctest.css">
|
||||
<script src="./3rdparty/highlight/highlight.pack.js"></script>
|
||||
<script src="../dist/iwmlib.3rdparty.js"></script>
|
||||
<script src="../dist/iwmlib.js"></script>
|
||||
<script src="../dist/iwmlib.js"></script>
|
||||
</head>
|
||||
|
||||
<body id="page" onload="Doctest.run()">
|
||||
<h1>
|
||||
Logging
|
||||
</h1>
|
||||
<p>Store informations of your app permanently.</p>
|
||||
<p>Store informations of your app permanently or use app specific logging functions.</p>
|
||||
<script class="doctest">
|
||||
Logging.log('app started')
|
||||
Logging.warn("shouldn't happen")
|
||||
Logging.error('restart')
|
||||
|
||||
Logging.setup({ log: message => console.log("app specific" + message) })
|
||||
Logging.log("now app related")
|
||||
</script>
|
||||
<p>You can overwrite the log, warn, and error handler by using Logging.setup with
|
||||
app specific functions.</p>
|
||||
<script class="doctest">
|
||||
Logging.setup({ log: message => console.log("app specific" + message) })
|
||||
Logging.log("now app related")
|
||||
</script>
|
||||
</body>
|
@ -1,10 +1,21 @@
|
||||
/* eslint-disable no-undef */
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-unused-vars */
|
||||
let ipc = null
|
||||
let logMessages = new Set()
|
||||
let logHandlers = {
|
||||
log: console.log,
|
||||
warn: console.warn,
|
||||
error: console.error
|
||||
}
|
||||
|
||||
try {
|
||||
ipc = require('electron').ipcRenderer
|
||||
logHandlers.log = message => ipc.send('log', message)
|
||||
logHandlers.warn = message => ipc.send('warn', message)
|
||||
logHandlers.error = message => ipc.send('error', message)
|
||||
} catch (e) {
|
||||
console.log("Cannot use electron logging.")
|
||||
console.log('Cannot use electron logging.')
|
||||
}
|
||||
|
||||
/** Basic class for app specific logging requirements.
|
||||
@ -12,6 +23,9 @@ try {
|
||||
* Uses a logMessage cache to prevent error overflows. This is
|
||||
* needed since errors may occur very frequently
|
||||
* (e.g. display update loops at 60fps, programmatic loops, ...).
|
||||
*
|
||||
* The logging handlers can be overwritten by calling the static
|
||||
* setup method.
|
||||
*/
|
||||
export default class Logging {
|
||||
|
||||
@ -19,12 +33,7 @@ export default class Logging {
|
||||
* @param {*} message
|
||||
*/
|
||||
static log(message) {
|
||||
|
||||
if (ipc) {
|
||||
ipc.send('log', message)
|
||||
} else {
|
||||
console.log(message)
|
||||
}
|
||||
logHandlers.log(message)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,11 +44,7 @@ export default class Logging {
|
||||
static warn(message) {
|
||||
if (!logMessages.has(message)) {
|
||||
logMessages.add(message)
|
||||
if (ipc) {
|
||||
ipc.send('warn', message)
|
||||
} else {
|
||||
console.warn(message)
|
||||
}
|
||||
logHandlers.warn(message)
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,11 +56,13 @@ export default class Logging {
|
||||
static error(message) {
|
||||
if (!logMessages.has(message)) {
|
||||
logMessages.add(message)
|
||||
if (ipc) {
|
||||
ipc.send('error', message)
|
||||
} else {
|
||||
console.error(message)
|
||||
}
|
||||
logHandlers.error(message)
|
||||
}
|
||||
}
|
||||
|
||||
static setup({log=console.log, warn=console.warn, error=console.error} = {}) {
|
||||
logHandlers.log = log
|
||||
logHandlers.warn = warn
|
||||
logHandlers.error = error
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user