//Import libraries
if (!global.ve) global.ve = {};
if (!global.electron) try { electron = require("electron"); } catch (e) {}
if (!global.file_read) try { file_read = require("../../file/file_read"); } catch (e) {}
if (!global.fs) try { fs = require("fs"); } catch (e) {}
if (!global.os) global.os = require("node:os");
if (!global.path) try { path = require("path"); } catch (e) {}
if (!global.readline) try { readline = require("readline"); } catch (e) {}
if (!global.v8) global.v8 = require("node:v8");
//Math utils - [WIP] - Override at a later date
{
if (!global.Math) global.Math = {};
Math.returnSafeNumber = function (arg0_number, arg1_default) {
//Convert from parameters
let number = parseFloat(arg0_number);
let default_value = (arg1_default !== undefined) ? arg1_default : 0;
//Return statement
return (!isNaN(number) && isFinite(number)) ? number : default_value;
};
}
//Initialise functions
{
/**
* Initialises IPC handlers.
*
* List of valid IPC channels:
* - electron:close-dev-tools
* - electron:is-dev-tools-focused
* - electron:is-dev-tools-open
* - electron:open-dev-tools
* - electron:toggle-dev-tools
* - ndjson - NDJSON handler (arg0_function_key, argn_arguments).
* - ndjson:get-all-functions - Returns all NDJSON functions.
* - ontology:initialise - Initialises Ontology streaming.
* - ontology:stream-batch - DB sends batch to render.
* - ontology:stream-done - Marks all streaming as finished (loaded into memory).
* - ontology:stream-next - Render requests batch from DB.
*
* @param {Object} [arg0_options]
* @param {number} [arg0_options.ontology_stream_size=256] - The stream packet size for Ontologies from DB.
*/
ve.initialiseIPC = function (arg0_options) {
//Convert from parameters
let options = (arg0_options) ? arg0_options : {};
//Initialise options
options.ontology_stream_size = (options.ontology_stream_size > 0) ?
options.ontology_stream_size : 256;
//Declare local instance variables
let ipc_main = electron.ipcMain;
//electron
ipc_main.on("electron:close-dev-tools", async (event) => {
event.sender.closeDevTools();
event.sender.send("electron:close-dev-tools:ready");
});
ipc_main.on("electron:is-dev-tools-focused", async (event) => {
event.sender.send("electron:is-dev-tools-focused:ready", event.sender.isDevToolsFocused());
})
ipc_main.on("electron:is-dev-tools-open", async (event) => {
event.sender.send("electron:is-dev-tools-open:ready", event.sender.isDevToolsOpened());
});
ipc_main.on("electron:open-dev-tools", async (event) => {
event.sender.openDevTools();
event.sender.send("electron:open-dev-tools:ready");
});
ipc_main.on("electron:toggle-dev-tools", async (event) => {
event.sender.toggleDevTools();
event.sender.send("electron:toggle-dev-tools:ready");
});
//ndjson
ipc_main.on("ndjson", async (event, function_key, ...argn_arguments) => {
if (NDJSON[function_key] === undefined) event.sender.send("ndjson:ready", null);
//console.log(`Received`, function_key, argn_arguments);
let result = await NDJSON[function_key](...argn_arguments);
event.sender.send("ndjson:ready", result);
});
//ndjson:get-all-functions
ipc_main.on("ndjson:get-all-functions", async (event) => {
let all_ndjson_function_keys = [];
let all_ndjson_keys = Object.keys(NDJSON);
for (let i = 0; i < all_ndjson_keys.length; i++) {
let local_value = NDJSON[all_ndjson_keys[i]];
if (typeof local_value === "function")
all_ndjson_function_keys.push(all_ndjson_keys[i]);
}
event.sender.send("ndjson:get-all-functions:ready", all_ndjson_function_keys);
});
//ontology
ipc_main.on("ontology:initialise", async (event, folder_path) => {
//Declare local instance variables
if (!fs.existsSync(folder_path)) fs.mkdirSync(folder_path, { recursive: true });
let all_files = fs.readdirSync(folder_path)
.filter((f) => f.endsWith(".ontology"))
.sort((a, b) => b.localeCompare(a));
let web_contents = event.sender;
async function* getOntologyBatches () {
let batch = {};
let count = 0;
for (let local_file of all_files) {
let local_file_path = path.join(folder_path, local_file);
//Process each file backwards line-by-line
for await (let local_line of global.file_read.readLinesBackwards(local_file_path)) {
if (!local_line.trim()) continue;
let json_start = local_line.indexOf("{");
if (json_start === -1) continue;
let id = local_line.substring(0, json_start).trim();
try {
let local_keyframe = JSON.parse(local_line.substring(json_start));
local_keyframe._saved = true;
if (!batch[id]) batch[id] = [];
batch[id].push(local_keyframe);
count++;
//Smaller batch size (256) is better for IPC stability
if (count >= options.ontology_stream_size) {
yield batch;
batch = {};
count = 0;
}
} catch (e) {}
}
}
if (Object.keys(batch).length > 0) yield batch;
}
let currentStream = getOntologyBatches();
let sendNextBatch = async () => {
let { value, done } = await currentStream.next();
if (done) {
web_contents.send('ontology:stream-done');
ipc_main.removeListener('ontology:stream-next', sendNextBatch);
} else {
web_contents.send('ontology:stream-batch', value);
}
};
//Stream in batches
ipc_main.removeAllListeners('ontology:stream-next');
ipc_main.on('ontology:stream-next', sendNextBatch);
await sendNextBatch();
});
//process
ipc_main.on("process", async (event, json) => {
if (proc.IPC_task === undefined) event.sender.send("process:ready", null);
let result = await proc.IPC_task(json);
event.sender.send("process:ready", result);
});
ipc_main.on("process:get-diagnostics", async (event) => {
let result = await proc.IPC_getDiagnostics();
event.sender.send("process:get-diagnostics:ready", result);
});
ipc_main.on("process:get-worker-pool", async (event, max_workers) => {
let pool = proc.IPC_getWorkerPool(max_workers);
let serialised_pool = pool.map((w) => {
return {
threadId: w?.threadId,
resourceLimits: w?.resourceLimits ? {
maxYoungGenerationSizeMb: w.resourceLimits.maxYoungGenerationSizeMb,
maxOldGenerationSizeMb: w.resourceLimits.maxOldGenerationSizeMb,
codeRangeSizeMb: w.resourceLimits.codeRangeSizeMb,
stackSizeMb: w.resourceLimits.stackSizeMb
} : null
};
});
event.sender.send("process:get-worker-pool:ready", serialised_pool);
});
};
try {
require("../db/NDJSON_main.js");
require("../../../../core/process/workers/process_main.js");
} catch (e) {} //NDJSON handling
}
module.exports = {
initialiseIPC: ve.initialiseIPC
};