Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Logging Options to Improve Performance #529

Merged
merged 2 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 53 additions & 47 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand All @@ -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();
}()

Expand All @@ -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`;
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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++) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 => {
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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();
Expand Down
Loading