Added Logging Options to Improve Performance (#529)

* Added Logging Options to Improve Performance

* Requested Changes

Co-authored-by: Onyx Azryn <brycekabat@onyxazryn.com>
This commit is contained in:
Bryce Kabat 2020-10-21 17:32:57 -05:00 committed by GitHub
parent e480c1c8e5
commit f4efedcf9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 192 additions and 186 deletions

100
main.js
View file

@ -10,6 +10,12 @@
const version = "1.4"; // generator version
document.title += " v" + version;
// Switches to disable/enable logging features
const INFO = 0;
const TIME = 0;
const WARN = 1;
const ERROR = 1;
// if map version is not stored, clear localStorage and show a message
if (rn(localStorage.getItem("version"), 2) !== rn(version, 2)) {
localStorage.clear();
@ -142,7 +148,7 @@ void function checkLoadParameters() {
// of there is a valid maplink, try to load .map file from URL
if (params.get("maplink")) {
console.warn("Load map from URL");
WARN && console.warn("Load map from URL");
const maplink = params.get("maplink");
const pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
const valid = pattern.test(maplink);
@ -152,7 +158,7 @@ void function checkLoadParameters() {
// if there is a seed (user of MFCG provided), generate map for it
if (params.get("seed")) {
console.warn("Generate map for seed");
WARN && console.warn("Generate map for seed");
generateMapOnLoad();
return;
}
@ -161,24 +167,24 @@ void function checkLoadParameters() {
if (onloadMap.value === "saved") {
ldb.get("lastMap", blob => {
if (blob) {
console.warn("Load last saved map");
WARN && console.warn("Load last saved map");
try {
uploadMap(blob);
}
catch(error) {
console.error(error);
console.warn("Cannot load stored map, random map to be generated");
ERROR && console.error(error);
WARN && console.warn("Cannot load stored map, random map to be generated");
generateMapOnLoad();
}
} else {
console.error("No map stored, random map to be generated");
ERROR && console.error("No map stored, random map to be generated");
generateMapOnLoad();
}
});
return;
}
console.warn("Generate random map");
WARN && console.warn("Generate random map");
generateMapOnLoad();
}()
@ -197,7 +203,7 @@ function loadMapFromURL(maplink, random) {
}
function showUploadErrorMessage(error, URL, random) {
console.error(error);
ERROR && console.error(error);
alertMessage.innerHTML = `Cannot load map from the ${link(URL, "link provided")}.
${random?`A new random map is generated. `:''}
Please ensure the linked file is reachable and CORS is allowed on server side`;
@ -249,7 +255,7 @@ function focusOn() {
// find burg for MFCG and focus on it
function findBurgForMFCG(params) {
const cells = pack.cells, burgs = pack.burgs;
if (pack.burgs.length < 2) {console.error("Cannot select a burg for MFCG"); return;}
if (pack.burgs.length < 2) {ERROR && console.error("Cannot select a burg for MFCG"); return;}
// used for selection
const size = +params.get("size");
@ -274,7 +280,7 @@ function findBurgForMFCG(params) {
// select a burg with closest population from selection
const selected = d3.scan(selection, (a, b) => Math.abs(a.population - size) - Math.abs(b.population - size));
const burgId = selection[selected].i;
if (!burgId) {console.error("Cannot select a burg for MFCG"); return;}
if (!burgId) {ERROR && console.error("Cannot select a burg for MFCG"); return;}
const b = burgs[burgId];
const referrer = new URL(document.referrer);
@ -507,7 +513,7 @@ function generate() {
const timeStart = performance.now();
invokeActiveZooming();
generateSeed();
console.group("Generated Map " + seed);
INFO && console.group("Generated Map " + seed);
applyMapSize();
randomizeOptions();
placePoints();
@ -548,12 +554,12 @@ function generate() {
addZones();
Names.getMapName();
console.warn(`TOTAL: ${rn((performance.now()-timeStart)/1000,2)}s`);
WARN && console.warn(`TOTAL: ${rn((performance.now()-timeStart)/1000,2)}s`);
showStatistics();
console.groupEnd("Generated Map " + seed);
INFO && console.groupEnd("Generated Map " + seed);
}
catch(error) {
console.error(error);
ERROR && console.error(error);
clearMainTip();
alertMessage.innerHTML = `An error is occured on map generation. Please retry.
@ -586,35 +592,35 @@ function generateSeed() {
// Place points to calculate Voronoi diagram
function placePoints() {
console.time("placePoints");
TIME && console.time("placePoints");
const cellsDesired = 10000 * densityInput.value; // generate 10k points for each densityInput point
const spacing = grid.spacing = rn(Math.sqrt(graphWidth * graphHeight / cellsDesired), 2); // spacing between points before jirrering
grid.boundary = getBoundaryPoints(graphWidth, graphHeight, spacing);
grid.points = getJitteredGrid(graphWidth, graphHeight, spacing); // jittered square grid
grid.cellsX = Math.floor((graphWidth + 0.5 * spacing) / spacing);
grid.cellsY = Math.floor((graphHeight + 0.5 * spacing) / spacing);
console.timeEnd("placePoints");
TIME && console.timeEnd("placePoints");
}
// calculate Delaunay and then Voronoi diagram
function calculateVoronoi(graph, points) {
console.time("calculateDelaunay");
TIME && console.time("calculateDelaunay");
const n = points.length;
const allPoints = points.concat(grid.boundary);
const delaunay = Delaunator.from(allPoints);
console.timeEnd("calculateDelaunay");
TIME && console.timeEnd("calculateDelaunay");
console.time("calculateVoronoi");
TIME && console.time("calculateVoronoi");
const voronoi = Voronoi(delaunay, allPoints, n);
graph.cells = voronoi.cells;
graph.cells.i = n < 65535 ? Uint16Array.from(d3.range(n)) : Uint32Array.from(d3.range(n)); // array of indexes
graph.vertices = voronoi.vertices;
console.timeEnd("calculateVoronoi");
TIME && console.timeEnd("calculateVoronoi");
}
// Mark features (ocean, lakes, islands)
function markFeatures() {
console.time("markFeatures");
TIME && console.time("markFeatures");
Math.seedrandom(seed); // restart Math.random() to get the same result on heightmap edit in Erase mode
const cells = grid.cells, heights = grid.cells.h;
cells.f = new Uint16Array(cells.i.length); // cell feature number
@ -648,7 +654,7 @@ function markFeatures() {
queue[0] = cells.f.findIndex(f => !f); // find unmarked cell
}
console.timeEnd("markFeatures");
TIME && console.timeEnd("markFeatures");
}
// How to handle lakes generated near seas? They can be both open or closed.
@ -658,7 +664,7 @@ function openNearSeaLakes() {
if (templateInput.value === "Atoll") return; // no need for Atolls
const cells = grid.cells, features = grid.features;
if (!features.find(f => f.type === "lake")) return; // no lakes
console.time("openLakes");
TIME && console.time("openLakes");
const limit = 50; // max height that can be breached by water
for (let t = 0, removed = true; t < 5 && removed; t++) {
@ -694,7 +700,7 @@ function openNearSeaLakes() {
return true;
}
console.timeEnd("openLakes");
TIME && console.timeEnd("openLakes");
}
// define map size and position based on template and random factor
@ -745,7 +751,7 @@ function calculateMapCoordinates() {
// temperature model
function calculateTemperatures() {
console.time('calculateTemperatures');
TIME && console.time('calculateTemperatures');
const cells = grid.cells;
cells.temp = new Int8Array(cells.i.length); // temperature array
@ -771,12 +777,12 @@ function calculateTemperatures() {
return rn(height / 1000 * 6.5);
}
console.timeEnd('calculateTemperatures');
TIME && console.timeEnd('calculateTemperatures');
}
// simplest precipitation model
function generatePrecipitation() {
console.time('generatePrecipitation');
TIME && console.time('generatePrecipitation');
prec.selectAll("*").remove();
const cells = grid.cells;
cells.prec = new Uint8Array(cells.i.length); // precipitation array
@ -887,12 +893,12 @@ function generatePrecipitation() {
if (southerly) wind.append("text").attr("x", graphWidth / 2).attr("y", graphHeight - 20).text("\u21C8");
}();
console.timeEnd('generatePrecipitation');
TIME && console.timeEnd('generatePrecipitation');
}
// recalculate Voronoi Graph to pack cells
function reGraph() {
console.time("reGraph");
TIME && console.time("reGraph");
let cells = grid.cells, points = grid.points, features = grid.features;
const newCells = {p:[], g:[], h:[], t:[], f:[], r:[], biome:[]}; // to store new data
const spacing2 = grid.spacing ** 2;
@ -936,12 +942,12 @@ function reGraph() {
cells.area = new Uint16Array(cells.i.length); // cell area
cells.i.forEach(i => cells.area[i] = Math.abs(d3.polygonArea(getPackPolygon(i))));
console.timeEnd("reGraph");
TIME && console.timeEnd("reGraph");
}
// Detect and draw the coasline
function drawCoastline() {
console.time('drawCoastline');
TIME && console.time('drawCoastline');
reMarkFeatures();
const cells = pack.cells, vertices = pack.vertices, n = cells.i.length, features = pack.features;
const used = new Uint8Array(features.length); // store conneted features
@ -1016,7 +1022,7 @@ function drawCoastline() {
if (v[0] !== prev && c0 !== c1) current = v[0]; else
if (v[1] !== prev && c1 !== c2) current = v[1]; else
if (v[2] !== prev && c0 !== c2) current = v[2];
if (current === chain[chain.length-1]) {console.error("Next vertex is not found"); break;}
if (current === chain[chain.length-1]) {ERROR && console.error("Next vertex is not found"); break;}
}
//chain.push(chain[0]); // push first vertex as the last one
return chain;
@ -1040,12 +1046,12 @@ function drawCoastline() {
}
}
console.timeEnd('drawCoastline');
TIME && console.timeEnd('drawCoastline');
}
// Re-mark features (ocean, lakes, islands)
function reMarkFeatures() {
console.time("reMarkFeatures");
TIME && console.time("reMarkFeatures");
const cells = pack.cells, features = pack.features = [0], temp = grid.cells.temp;
cells.f = new Uint16Array(cells.i.length); // cell feature number
cells.t = new Int16Array(cells.i.length); // cell type: 1 = land along coast; -1 = water along coast;
@ -1113,13 +1119,13 @@ function reMarkFeatures() {
return "isle";
}
console.timeEnd("reMarkFeatures");
TIME && console.timeEnd("reMarkFeatures");
}
// temporary elevate some lakes to resolve depressions and flux the water to form an open (exorheic) lake
function elevateLakes() {
if (templateInput.value === "Atoll") return; // no need for Atolls
console.time('elevateLakes');
TIME && console.time('elevateLakes');
const cells = pack.cells, features = pack.features;
const maxCells = cells.i.length / 100; // size limit; let big lakes be closed (endorheic)
cells.i.forEach(i => {
@ -1129,12 +1135,12 @@ function elevateLakes() {
//debug.append("circle").attr("cx", cells.p[i][0]).attr("cy", cells.p[i][1]).attr("r", .5).attr("fill", "blue");
});
console.timeEnd('elevateLakes');
TIME && console.timeEnd('elevateLakes');
}
// assign biome id for each cell
function defineBiomes() {
console.time("defineBiomes");
TIME && console.time("defineBiomes");
const cells = pack.cells, f = pack.features, temp = grid.cells.temp, prec = grid.cells.prec;
cells.biome = new Uint8Array(cells.i.length); // biomes array
@ -1153,7 +1159,7 @@ function defineBiomes() {
return rn(4 + d3.mean(n));
}
console.timeEnd("defineBiomes");
TIME && console.timeEnd("defineBiomes");
}
// assign biome id to a cell
@ -1168,7 +1174,7 @@ function getBiomeId(moisture, temperature, height) {
// assess cells suitability to calculate population and rand cells for culture center and burgs placement
function rankCells() {
console.time('rankCells');
TIME && console.time('rankCells');
const cells = pack.cells, f = pack.features;
cells.s = new Int16Array(cells.i.length); // cell suitability array
cells.pop = new Float32Array(cells.i.length); // cell population array
@ -1202,13 +1208,13 @@ function rankCells() {
cells.pop[i] = cells.s[i] > 0 ? cells.s[i] * cells.area[i] / areaMean : 0;
}
console.timeEnd('rankCells');
TIME && console.timeEnd('rankCells');
}
// generate some markers
function addMarkers(number = 1) {
if (!number) return;
console.time("addMarkers");
TIME && console.time("addMarkers");
const cells = pack.cells, states = pack.states;
void function addVolcanoes() {
@ -1374,12 +1380,12 @@ function addMarkers(number = 1) {
return id;
}
console.timeEnd("addMarkers");
TIME && console.timeEnd("addMarkers");
}
// regenerate some zones
function addZones(number = 1) {
console.time("addZones");
TIME && console.time("addZones");
const data = [], cells = pack.cells, states = pack.states, burgs = pack.burgs;
const used = new Uint8Array(cells.i.length); // to store used cells
@ -1690,7 +1696,7 @@ function addZones(number = 1) {
.attr("points", d => getPackPolygon(d)).attr("id", function(d) {return this.parentNode.id+"_"+d});
}()
console.timeEnd("addZones");
TIME && console.timeEnd("addZones");
}
// show map stats on generation complete
@ -1712,11 +1718,11 @@ function showStatistics() {
mapId = Date.now(); // unique map id is it's creation date number
mapHistory.push({seed, width:graphWidth, height:graphHeight, template, created:mapId});
console.log(stats);
INFO && console.log(stats);
}
const regenerateMap = debounce(function() {
console.warn("Generate new random map");
WARN && console.warn("Generate new random map");
closeDialogs("#worldConfigurator, #options3d");
customization = 0;
undraw();