Logging handlers can now be adapted to special needs
This commit is contained in:
parent
9042579518
commit
1480ad8145
57
dist/iwmlib.js
vendored
57
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 ipc = null;
|
||||||
|
let logMessages = new Set();
|
||||||
|
let logHandlers = {
|
||||||
|
log: console.log,
|
||||||
|
warn: console.warn,
|
||||||
|
error: console.error
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ipc = require('electron').ipcRenderer;
|
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.
|
/** Basic class for app specific logging requirements.
|
||||||
* Can be used to implement persistent logging in electron apps.
|
* 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 {
|
||||||
|
|
||||||
@ -1560,12 +1580,37 @@
|
|||||||
* @param {*} message
|
* @param {*} message
|
||||||
*/
|
*/
|
||||||
static log(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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
200
dist/iwmlib.pixi.js
vendored
200
dist/iwmlib.pixi.js
vendored
@ -4709,27 +4709,72 @@
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
let ipc = null;
|
let ipc = null;
|
||||||
|
let logMessages = new Set();
|
||||||
|
let logHandlers = {
|
||||||
|
log: console.log,
|
||||||
|
warn: console.warn,
|
||||||
|
error: console.error
|
||||||
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ipc = require('electron').ipcRenderer;
|
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.
|
/** Basic class for app specific logging requirements.
|
||||||
* Can be used to implement persistent logging in electron apps.
|
* 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.
|
/** Static log function.
|
||||||
* @param {*} message
|
* @param {*} message
|
||||||
*/
|
*/
|
||||||
static log(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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5676,7 +5721,7 @@
|
|||||||
let size = this.interaction.current.size;
|
let size = this.interaction.current.size;
|
||||||
let limit = this.logInteractionsAbove;
|
let limit = this.logInteractionsAbove;
|
||||||
if (size > limit) {
|
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*/
|
/* globals PIXI, console*/
|
||||||
|
|
||||||
const registeredTiles = new Map();
|
const registeredTiles = new Map();
|
||||||
// const pendingTiles = new Map()
|
|
||||||
/** Implements a baseTexture cache. The last textures are kept for reuse */
|
/** Implements a baseTexture cache. The last textures are kept for reuse */
|
||||||
let keepTextures = 0;
|
let keepTextures = 0;
|
||||||
const keptTextures = [];
|
const keptTextures = [];
|
||||||
|
const lateTextures = new Map();
|
||||||
|
let lastSweepTime = 0;
|
||||||
|
let sweepInterval = 2000.0;
|
||||||
|
|
||||||
/** The current Tile implementation simply uses PIXI.Sprites.
|
/** The current Tile implementation simply uses PIXI.Sprites.
|
||||||
*
|
*
|
||||||
@ -7833,43 +7880,6 @@
|
|||||||
keepTextures = value;
|
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
|
* Returns true iff the url is pending
|
||||||
*
|
*
|
||||||
@ -8001,14 +8011,60 @@
|
|||||||
return null
|
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.
|
* Texture received too late. We do not need it.
|
||||||
* @param {*} url
|
* @param {*} url
|
||||||
* @param {*} texture
|
* @param {*} texture
|
||||||
*/
|
*/
|
||||||
static lateTexture(url, texture) {
|
static lateTexture(url, texture) {
|
||||||
let destroyBase = !registeredTiles.has(url);
|
lateTextures.set(url, texture);
|
||||||
texture.destroy(destroyBase);
|
//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() {
|
static printInfos() {
|
||||||
@ -11811,6 +11867,10 @@
|
|||||||
return ['decade', 'year', 'month', 'day', 'hour', 'minute', 'second']
|
return ['decade', 'year', 'month', 'day', 'hour', 'minute', 'second']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get largeTickSize() {
|
||||||
|
return 4.2
|
||||||
|
}
|
||||||
|
|
||||||
get minWidth() {
|
get minWidth() {
|
||||||
return 10
|
return 10
|
||||||
}
|
}
|
||||||
@ -11885,7 +11945,7 @@
|
|||||||
return date.toLocaleDateString('de', format)
|
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 first = null;
|
||||||
let last = null;
|
let last = null;
|
||||||
let keyedFormat = (format) ? format[this.formatKey] : null;
|
let keyedFormat = (format) ? format[this.formatKey] : null;
|
||||||
@ -11893,7 +11953,6 @@
|
|||||||
let redundant = (nextFormat) ? this.formatKey in nextFormat : false;
|
let redundant = (nextFormat) ? this.formatKey in nextFormat : false;
|
||||||
let fullyRedundant = keyedFormat != null && keyedFormat == keyedNextFormat;
|
let fullyRedundant = keyedFormat != null && keyedFormat == keyedNextFormat;
|
||||||
let y = timeline.getY();
|
let y = timeline.getY();
|
||||||
|
|
||||||
for (let { start, end } of this.iterRanges(range)) {
|
for (let { start, end } of this.iterRanges(range)) {
|
||||||
let x = timeline.toX(start);
|
let x = timeline.toX(start);
|
||||||
let xx = x;
|
let xx = x;
|
||||||
@ -11902,11 +11961,10 @@
|
|||||||
let key = this.dateKey(start);
|
let key = this.dateKey(start);
|
||||||
let text = this.toLocaleString(start, format);
|
let text = this.toLocaleString(start, format);
|
||||||
let align = 'center';
|
let align = 'center';
|
||||||
let downTick = false;
|
|
||||||
if (nextFormat) {
|
if (nextFormat) {
|
||||||
yy = y + timeline.tickLabelOffset(-1, 1);
|
yy = y + timeline.tickLabelOffset(-1, 1);
|
||||||
align = 'left';
|
align = 'left';
|
||||||
timeline.drawTick(x, 4.2);
|
timeline.drawTick(x, Ticks.largeTickSize);
|
||||||
let nextX = timeline.toX(end) - 100;
|
let nextX = timeline.toX(end) - 100;
|
||||||
if (x < 0 && nextX > -100 && !redundant) {
|
if (x < 0 && nextX > -100 && !redundant) {
|
||||||
xx = Math.min(4, nextX);
|
xx = Math.min(4, nextX);
|
||||||
@ -11914,20 +11972,18 @@
|
|||||||
else {
|
else {
|
||||||
xx -= 2;
|
xx -= 2;
|
||||||
}
|
}
|
||||||
downTick = true;
|
|
||||||
}
|
}
|
||||||
else if (level > 0) {
|
else if (level > 0) {
|
||||||
xx = x + available / 2;
|
xx = x + available / 2;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
downTick = true;
|
|
||||||
}
|
|
||||||
if (!fullyRedundant) {
|
if (!fullyRedundant) {
|
||||||
timeline.ensureLabel(key, text,
|
timeline.ensureLabel(key, text,
|
||||||
{ x: xx, y: yy, align },
|
{ x: xx, y: yy, align },
|
||||||
FontInfo.small);
|
FontInfo.small);
|
||||||
}
|
}
|
||||||
if (downTick) timeline.drawTick(x, -1);
|
if (extraTicks)
|
||||||
|
timeline.drawTick(x, -level);
|
||||||
}
|
}
|
||||||
if (timeline.visibleRange(start, end)) {
|
if (timeline.visibleRange(start, end)) {
|
||||||
if (first == null)
|
if (first == null)
|
||||||
@ -11939,6 +11995,15 @@
|
|||||||
return null
|
return null
|
||||||
return { start: first, end: last }
|
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 {
|
class DecadeTicks extends Ticks {
|
||||||
@ -12125,15 +12190,34 @@
|
|||||||
visible.push(ticks);
|
visible.push(ticks);
|
||||||
}
|
}
|
||||||
let level = 0;
|
let level = 0;
|
||||||
|
let ranges = [];
|
||||||
for (let ticks of visible) {
|
for (let ticks of visible) {
|
||||||
if (range == null)
|
if (range == null)
|
||||||
return
|
continue
|
||||||
range = ticks.draw(timeline, range, width, height,
|
range = ticks.draw(timeline, range, width, height,
|
||||||
availables.get(ticks),
|
availables.get(ticks),
|
||||||
formats.get(ticks),
|
formats.get(ticks),
|
||||||
nextFormats.get(ticks), level);
|
nextFormats.get(ticks), level);
|
||||||
|
if (range) {
|
||||||
|
ranges.push({ticks, range});
|
||||||
|
}
|
||||||
level += 1;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,19 @@
|
|||||||
<h1>
|
<h1>
|
||||||
Logging
|
Logging
|
||||||
</h1>
|
</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">
|
<script class="doctest">
|
||||||
Logging.log('app started')
|
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>
|
</script>
|
||||||
</body>
|
</body>
|
@ -1,10 +1,21 @@
|
|||||||
|
/* eslint-disable no-undef */
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
let ipc = null
|
let ipc = null
|
||||||
let logMessages = new Set()
|
let logMessages = new Set()
|
||||||
|
let logHandlers = {
|
||||||
|
log: console.log,
|
||||||
|
warn: console.warn,
|
||||||
|
error: console.error
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ipc = require('electron').ipcRenderer
|
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) {
|
} catch (e) {
|
||||||
console.log("Cannot use electron logging.")
|
console.log('Cannot use electron logging.')
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Basic class for app specific logging requirements.
|
/** Basic class for app specific logging requirements.
|
||||||
@ -12,6 +23,9 @@ try {
|
|||||||
* Uses a logMessage cache to prevent error overflows. This is
|
* Uses a logMessage cache to prevent error overflows. This is
|
||||||
* needed since errors may occur very frequently
|
* needed since errors may occur very frequently
|
||||||
* (e.g. display update loops at 60fps, programmatic loops, ...).
|
* (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 {
|
export default class Logging {
|
||||||
|
|
||||||
@ -19,12 +33,7 @@ export default class Logging {
|
|||||||
* @param {*} message
|
* @param {*} message
|
||||||
*/
|
*/
|
||||||
static log(message) {
|
static log(message) {
|
||||||
|
logHandlers.log(message)
|
||||||
if (ipc) {
|
|
||||||
ipc.send('log', message)
|
|
||||||
} else {
|
|
||||||
console.log(message)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,11 +44,7 @@ export default class Logging {
|
|||||||
static warn(message) {
|
static warn(message) {
|
||||||
if (!logMessages.has(message)) {
|
if (!logMessages.has(message)) {
|
||||||
logMessages.add(message)
|
logMessages.add(message)
|
||||||
if (ipc) {
|
logHandlers.warn(message)
|
||||||
ipc.send('warn', message)
|
|
||||||
} else {
|
|
||||||
console.warn(message)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,11 +56,13 @@ export default class Logging {
|
|||||||
static error(message) {
|
static error(message) {
|
||||||
if (!logMessages.has(message)) {
|
if (!logMessages.has(message)) {
|
||||||
logMessages.add(message)
|
logMessages.add(message)
|
||||||
if (ipc) {
|
logHandlers.error(message)
|
||||||
ipc.send('error', message)
|
|
||||||
} else {
|
|
||||||
console.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