mirror of
https://github.com/wisplite/BLE-mesh-sim.git
synced 2026-10-30 13:32:21 -05:00
Merge pull request #1 from wisplite/sim-rewrite-1
Complete sim rewrite !!
This commit is contained in:
+3
-6
@@ -28,10 +28,8 @@
|
|||||||
<details id="hardwareConstraints">
|
<details id="hardwareConstraints">
|
||||||
<summary>Hardware Constraints</summary>
|
<summary>Hardware Constraints</summary>
|
||||||
<div id="hardwareConstraintsContent">
|
<div id="hardwareConstraintsContent">
|
||||||
<label for="maxOutgoingConnections">Max Outgoing Connections</label>
|
<label for="maxConnections">Max Connections</label>
|
||||||
<input type="number" id="maxOutgoingConnections" value="3" autocomplete="off">
|
<input type="number" id="maxConnections" value="6" autocomplete="off">
|
||||||
<label for="maxIncomingConnections">Max Incoming Connections</label>
|
|
||||||
<input type="number" id="maxIncomingConnections" value="3" autocomplete="off">
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
<details id="engineSettings">
|
<details id="engineSettings">
|
||||||
@@ -85,8 +83,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="connectionViewer">
|
<div id="connectionViewer">
|
||||||
<details id="incomingConnections"><summary>Incoming Connections</summary></details>
|
<details id="connections"><summary>Connections</summary></details>
|
||||||
<details id="outgoingConnections"><summary>Outgoing Connections</summary></details>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="randomGraphModal">
|
<div id="randomGraphModal">
|
||||||
<div id="randomGraphModalContent">
|
<div id="randomGraphModalContent">
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ var UPDATE_INTERVAL = 10;
|
|||||||
var CONNECTION_DISTANCE = 250;
|
var CONNECTION_DISTANCE = 250;
|
||||||
var DROP_PENALTY = 1.2;
|
var DROP_PENALTY = 1.2;
|
||||||
var TTL = 5;
|
var TTL = 5;
|
||||||
var MAX_OUTGOING_CONNECTIONS = 3;
|
var MAX_CONNECTIONS = 6;
|
||||||
var MAX_INCOMING_CONNECTIONS = 3;
|
|
||||||
var warningModalShown = false;
|
var warningModalShown = false;
|
||||||
var displayWarningWhenDone = false;
|
var displayWarningWhenDone = false;
|
||||||
var stillRouting = false;
|
var stillRouting = false;
|
||||||
@@ -109,8 +108,10 @@ onEdgeEngine.setArrivalCallback(async ({ from, to, dot }) => {
|
|||||||
}
|
}
|
||||||
if (document.getElementById('showTTL').checked) {
|
if (document.getElementById('showTTL').checked) {
|
||||||
edges.update({id: `${from}->${to}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1)}});
|
edges.update({id: `${from}->${to}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1)}});
|
||||||
|
edges.update({id: `${to}->${from}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1)}});
|
||||||
} else {
|
} else {
|
||||||
edges.update({id: `${from}->${to}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
edges.update({id: `${from}->${to}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
||||||
|
edges.update({id: `${to}->${from}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
||||||
}
|
}
|
||||||
if (nodeTable[to].packetCache.includes(dot.id.split('-')[0])) {
|
if (nodeTable[to].packetCache.includes(dot.id.split('-')[0])) {
|
||||||
return;
|
return;
|
||||||
@@ -126,7 +127,7 @@ onEdgeEngine.setArrivalCallback(async ({ from, to, dot }) => {
|
|||||||
nodes.update({id: to, color: {background: '#97c2fc'}});
|
nodes.update({id: to, color: {background: '#97c2fc'}});
|
||||||
}
|
}
|
||||||
if (ttl > 0) {
|
if (ttl > 0) {
|
||||||
const neighborsSnapshot = nodeTable[to].outgoing.slice();
|
const neighborsSnapshot = nodeTable[to].connections.slice();
|
||||||
for (let neighbor of neighborsSnapshot) {
|
for (let neighbor of neighborsSnapshot) {
|
||||||
if (neighbor === from || neighbor === originNode) {
|
if (neighbor === from || neighbor === originNode) {
|
||||||
continue;
|
continue;
|
||||||
@@ -174,12 +175,14 @@ function quickPacket(startNode, packetInfo, fromNode) {
|
|||||||
if (document.getElementById('showTTL').checked) {
|
if (document.getElementById('showTTL').checked) {
|
||||||
nodes.update({id: nodeId, color: {background: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
nodes.update({id: nodeId, color: {background: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
||||||
edges.update({id: `${from}->${nodeId}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
edges.update({id: `${from}->${nodeId}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
||||||
|
edges.update({id: `${nodeId}->${from}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
||||||
} else {
|
} else {
|
||||||
nodes.update({id: nodeId, color: {background: '#97c2fc'}});
|
nodes.update({id: nodeId, color: {background: '#97c2fc'}});
|
||||||
edges.update({id: `${from}->${nodeId}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
edges.update({id: `${from}->${nodeId}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
||||||
|
edges.update({id: `${nodeId}->${from}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
||||||
}
|
}
|
||||||
|
|
||||||
const neighborsSnapshot = (nodeTable[nodeId]?.outgoing?.slice()) || [];
|
const neighborsSnapshot = (nodeTable[nodeId]?.connections?.slice()) || [];
|
||||||
|
|
||||||
for (let neighbor of neighborsSnapshot) {
|
for (let neighbor of neighborsSnapshot) {
|
||||||
if (neighbor === originNode || neighbor === from) {
|
if (neighbor === originNode || neighbor === from) {
|
||||||
@@ -217,12 +220,14 @@ function quickRoute(startNode, packetInfo, fromNode) {
|
|||||||
if (document.getElementById('showTTL').checked) {
|
if (document.getElementById('showTTL').checked) {
|
||||||
nodes.update({id: nodeId, color: {background: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
nodes.update({id: nodeId, color: {background: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
||||||
edges.update({id: `${from}->${nodeId}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
edges.update({id: `${from}->${nodeId}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
||||||
|
edges.update({id: `${nodeId}->${from}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
||||||
} else {
|
} else {
|
||||||
nodes.update({id: nodeId, color: {background: '#97c2fc'}});
|
nodes.update({id: nodeId, color: {background: '#97c2fc'}});
|
||||||
edges.update({id: `${from}->${nodeId}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
edges.update({id: `${from}->${nodeId}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
||||||
|
edges.update({id: `${nodeId}->${from}`, color: {color: '#2b7ce9', highlight: '#2b7ce9'}});
|
||||||
}
|
}
|
||||||
|
|
||||||
const neighborsSnapshot = (nodeTable[nodeId]?.outgoing?.slice()) || [];
|
const neighborsSnapshot = (nodeTable[nodeId]?.connections?.slice()) || [];
|
||||||
|
|
||||||
for (let neighbor of neighborsSnapshot) {
|
for (let neighbor of neighborsSnapshot) {
|
||||||
if (neighbor === originNode || neighbor === from) {
|
if (neighbor === originNode || neighbor === from) {
|
||||||
@@ -246,11 +251,6 @@ async function routePacket(currentNode, goalNode, packetInfo, first=false) {
|
|||||||
consoleLog(`Node ${goalNode} not found. Dropping packet.`);
|
consoleLog(`Node ${goalNode} not found. Dropping packet.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (nodeTable[currentNode].emergencyIncoming.length > 0) {
|
|
||||||
nodeTable[currentNode].emergencyIncoming = []
|
|
||||||
nodeTable[packetInfo.split('-')[3]].emergencyOutgoing = []
|
|
||||||
edges.remove({'id': `${packetInfo.split('-')[3]}->${currentNode}`})
|
|
||||||
}
|
|
||||||
stillRouting = true;
|
stillRouting = true;
|
||||||
const packetId = packetInfo.split('-')[0];
|
const packetId = packetInfo.split('-')[0];
|
||||||
var packetShift = generateRealisticLabel();
|
var packetShift = generateRealisticLabel();
|
||||||
@@ -278,15 +278,8 @@ async function routePacket(currentNode, goalNode, packetInfo, first=false) {
|
|||||||
}
|
}
|
||||||
ttl--;
|
ttl--;
|
||||||
let nextNode = nodeTable[currentNode].routingTable[goalNode];
|
let nextNode = nodeTable[currentNode].routingTable[goalNode];
|
||||||
if (!nodeTable[currentNode].outgoing.includes(nextNode) && nodeTable[currentNode].emergencyOutgoing.length == 0 && nodeTable[nextNode].emergencyIncoming.length == 0) {
|
if (!nodeTable[currentNode].connections.includes(nextNode)) {
|
||||||
// use emergency connection slot
|
consoleLog(`No route found from ${currentNode} to ${goalNode}. Dropping packet.`);
|
||||||
nodeTable[currentNode].emergencyOutgoing.push(nextNode);
|
|
||||||
nodeTable[nextNode].emergencyIncoming.push(currentNode);
|
|
||||||
await sleep(1000);
|
|
||||||
connectNodes(currentNode, nextNode);
|
|
||||||
} else if (nodeTable[currentNode].emergencyOutgoing.length != 0 || nodeTable[nextNode].emergencyIncoming.length != 0) {
|
|
||||||
consoleLog(`Couldn't connect to ${nextNode}. Dropping packet.`);
|
|
||||||
console.log(nodeTable[currentNode])
|
|
||||||
stillRouting = false;
|
stillRouting = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -305,8 +298,10 @@ async function routePacket(currentNode, goalNode, packetInfo, first=false) {
|
|||||||
onEdgeEngine.createDotNode(movingNode, currentNode, nextNode);
|
onEdgeEngine.createDotNode(movingNode, currentNode, nextNode);
|
||||||
if (document.getElementById('showTTL').checked) {
|
if (document.getElementById('showTTL').checked) {
|
||||||
edges.update({id: `${currentNode}->${nextNode}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
edges.update({id: `${currentNode}->${nextNode}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
||||||
|
edges.update({id: `${nextNode}->${currentNode}`, color: {color: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl+1), highlight: smoothColorTransition('#eb4034', '#40eb34', 0, TTL, ttl)}});
|
||||||
} else {
|
} else {
|
||||||
edges.update({id: `${currentNode}->${nextNode}`, color: {color: 'yellow', highlight: 'yellow'}});
|
edges.update({id: `${currentNode}->${nextNode}`, color: {color: 'yellow', highlight: 'yellow'}});
|
||||||
|
edges.update({id: `${nextNode}->${currentNode}`, color: {color: 'yellow', highlight: 'yellow'}});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
consoleLog(`No route found from ${currentNode} to ${goalNode} via ${nextNode}. Dropping packet.`);
|
consoleLog(`No route found from ${currentNode} to ${goalNode} via ${nextNode}. Dropping packet.`);
|
||||||
@@ -323,7 +318,7 @@ const markNeighborsAsFailed = (nodeId, from, packetId, visited = new Set()) => {
|
|||||||
|
|
||||||
if (warningModalShown) {
|
if (warningModalShown) {
|
||||||
// enable walkthrough mode to prevent browser from freezing
|
// enable walkthrough mode to prevent browser from freezing
|
||||||
const neighborsSnapshot = (nodeTable[nodeId]?.outgoing?.slice()) || [];
|
const neighborsSnapshot = (nodeTable[nodeId]?.connections?.slice()) || [];
|
||||||
const neighborsLength = neighborsSnapshot.length;
|
const neighborsLength = neighborsSnapshot.length;
|
||||||
let currentIdx = 0;
|
let currentIdx = 0;
|
||||||
const intervalId = setInterval(() => {
|
const intervalId = setInterval(() => {
|
||||||
@@ -334,6 +329,7 @@ const markNeighborsAsFailed = (nodeId, from, packetId, visited = new Set()) => {
|
|||||||
neighbor !== from) {
|
neighbor !== from) {
|
||||||
nodes.update({id: neighbor, color: {background: 'white'}});
|
nodes.update({id: neighbor, color: {background: 'white'}});
|
||||||
edges.update({id: `${nodeId}->${neighbor}`, color: {color: 'white', highlight: '#97c2fc'}});
|
edges.update({id: `${nodeId}->${neighbor}`, color: {color: 'white', highlight: '#97c2fc'}});
|
||||||
|
edges.update({id: `${neighbor}->${nodeId}`, color: {color: 'white', highlight: '#97c2fc'}});
|
||||||
markNeighborsAsFailed(neighbor, nodeId, packetId, visited);
|
markNeighborsAsFailed(neighbor, nodeId, packetId, visited);
|
||||||
}
|
}
|
||||||
currentIdx++;
|
currentIdx++;
|
||||||
@@ -344,7 +340,7 @@ const markNeighborsAsFailed = (nodeId, from, packetId, visited = new Set()) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const neighborsSnapshot = (nodeTable[nodeId]?.outgoing?.slice()) || [];
|
const neighborsSnapshot = (nodeTable[nodeId]?.connections?.slice()) || [];
|
||||||
for (let neighbor of neighborsSnapshot) {
|
for (let neighbor of neighborsSnapshot) {
|
||||||
if (visited.has(neighbor)) {
|
if (visited.has(neighbor)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -357,37 +353,27 @@ const markNeighborsAsFailed = (nodeId, from, packetId, visited = new Set()) => {
|
|||||||
}
|
}
|
||||||
nodes.update({id: neighbor, color: {background: 'white'}});
|
nodes.update({id: neighbor, color: {background: 'white'}});
|
||||||
edges.update({id: `${nodeId}->${neighbor}`, color: {color: 'white', highlight: '#97c2fc'}});
|
edges.update({id: `${nodeId}->${neighbor}`, color: {color: 'white', highlight: '#97c2fc'}});
|
||||||
|
edges.update({id: `${neighbor}->${nodeId}`, color: {color: 'white', highlight: '#97c2fc'}});
|
||||||
markNeighborsAsFailed(neighbor, nodeId, packetId, visited);
|
markNeighborsAsFailed(neighbor, nodeId, packetId, visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function nodeSelectUpdateHandler(properties) {
|
function nodeSelectUpdateHandler(properties) {
|
||||||
// get containers
|
// get containers
|
||||||
const incomingTable = document.getElementById('incomingConnections');
|
const connectionsTable = document.getElementById('connections');
|
||||||
const outgoingTable = document.getElementById('outgoingConnections');
|
|
||||||
|
|
||||||
// clear containers
|
// clear containers
|
||||||
let connectionElements = incomingTable.querySelectorAll('.connectionElement');
|
let connectionElements = connectionsTable.querySelectorAll('.connectionElement');
|
||||||
for (let connection of connectionElements) {
|
|
||||||
connection.remove();
|
|
||||||
}
|
|
||||||
connectionElements = outgoingTable.querySelectorAll('.connectionElement');
|
|
||||||
for (let connection of connectionElements) {
|
for (let connection of connectionElements) {
|
||||||
connection.remove();
|
connection.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (let connection of nodeTable[properties.nodes[0]].outgoing) {
|
for (let connection of nodeTable[properties.nodes[0]].connections) {
|
||||||
const connectionElement = document.createElement('div');
|
const connectionElement = document.createElement('div');
|
||||||
connectionElement.classList.add('connectionElement');
|
connectionElement.classList.add('connectionElement');
|
||||||
connectionElement.innerHTML = connection;
|
connectionElement.innerHTML = connection;
|
||||||
outgoingTable.appendChild(connectionElement);
|
connectionsTable.appendChild(connectionElement);
|
||||||
}
|
|
||||||
for (let connection of nodeTable[properties.nodes[0]].incoming) {
|
|
||||||
const connectionElement = document.createElement('div');
|
|
||||||
connectionElement.classList.add('connectionElement');
|
|
||||||
connectionElement.innerHTML = connection;
|
|
||||||
incomingTable.appendChild(connectionElement);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return;
|
return;
|
||||||
@@ -511,13 +497,14 @@ function main() {
|
|||||||
neighbors.push({'node': node2, 'distance': distanceToRSSI(distance), });
|
neighbors.push({'node': node2, 'distance': distanceToRSSI(distance), });
|
||||||
} else {
|
} else {
|
||||||
edges.remove(`${node1}->${node2}`);
|
edges.remove(`${node1}->${node2}`);
|
||||||
const outIdx = nodeTable[node1].outgoing.indexOf(node2);
|
edges.remove(`${node2}->${node1}`);
|
||||||
if (outIdx !== -1) {
|
const node1Idx = nodeTable[node1].connections.indexOf(node2);
|
||||||
nodeTable[node1].outgoing.splice(outIdx, 1);
|
if (node1Idx !== -1) {
|
||||||
|
nodeTable[node1].connections.splice(node1Idx, 1);
|
||||||
}
|
}
|
||||||
const inIdx = nodeTable[node2].incoming.indexOf(node1);
|
const node2Idx = nodeTable[node2].connections.indexOf(node1);
|
||||||
if (inIdx !== -1) {
|
if (node2Idx !== -1) {
|
||||||
nodeTable[node2].incoming.splice(inIdx, 1);
|
nodeTable[node2].connections.splice(node2Idx, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,14 +517,14 @@ function main() {
|
|||||||
let connectionScore = 0;
|
let connectionScore = 0;
|
||||||
let dropScore = 0;
|
let dropScore = 0;
|
||||||
connectionScore += (100 + neighbor.distance);
|
connectionScore += (100 + neighbor.distance);
|
||||||
connectionScore += 100 / (nodeTable[neighbor.node].incoming.length + 1);
|
connectionScore += 100 / (nodeTable[neighbor.node].connections.length + 1);
|
||||||
if (nodeTable[neighbor.node].incoming.length == 0) {
|
if (nodeTable[neighbor.node].connections.length == 0) {
|
||||||
connectionScore += 10000;
|
connectionScore += 10000;
|
||||||
}
|
}
|
||||||
if (nodeTable[neighbor.node].incoming.length >= MAX_INCOMING_CONNECTIONS) {
|
if (nodeTable[neighbor.node].connections.length >= MAX_CONNECTIONS) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (nodeTable[node1].outgoing.includes(neighbor.node)) {
|
if (nodeTable[node1].connections.includes(neighbor.node)) {
|
||||||
dropScore = connectionScore;
|
dropScore = connectionScore;
|
||||||
}
|
}
|
||||||
scores.push({'node': neighbor.node, 'score': connectionScore, 'dropScore': dropScore});
|
scores.push({'node': neighbor.node, 'score': connectionScore, 'dropScore': dropScore});
|
||||||
@@ -546,13 +533,13 @@ function main() {
|
|||||||
const neighborMap = new Map(neighbors.map(n => [n.node, n]));
|
const neighborMap = new Map(neighbors.map(n => [n.node, n]));
|
||||||
const top3 = scores.slice(0, 3);
|
const top3 = scores.slice(0, 3);
|
||||||
for (let score of top3) {
|
for (let score of top3) {
|
||||||
if (nodeTable[node1].outgoing.length >= MAX_OUTGOING_CONNECTIONS) {
|
if (nodeTable[node1].connections.length >= MAX_CONNECTIONS) {
|
||||||
let dropped = false;
|
let dropped = false;
|
||||||
if (nodeTable[node1].outgoing.includes(score.node)) {
|
if (nodeTable[node1].connections.includes(score.node)) {
|
||||||
//console.log(`${score.node} is already in outgoing; skipping drop attempt`);
|
//console.log(`${score.node} is already connected; skipping drop attempt`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (let existingNode of [...nodeTable[node1].outgoing]) {
|
for (let existingNode of [...nodeTable[node1].connections]) {
|
||||||
const neighborInfo = neighborMap.get(existingNode);
|
const neighborInfo = neighborMap.get(existingNode);
|
||||||
if (!neighborInfo) {
|
if (!neighborInfo) {
|
||||||
//console.log(`${existingNode} not a neighbor; skipping`);
|
//console.log(`${existingNode} not a neighbor; skipping`);
|
||||||
@@ -560,21 +547,22 @@ function main() {
|
|||||||
}
|
}
|
||||||
let existingScore = 0;
|
let existingScore = 0;
|
||||||
existingScore += (100 + neighborInfo.distance);
|
existingScore += (100 + neighborInfo.distance);
|
||||||
existingScore += 100 / (nodeTable[existingNode].incoming.length + 1);
|
existingScore += 100 / (nodeTable[existingNode].connections.length + 1);
|
||||||
if (nodeTable[existingNode].incoming.length == 0) {
|
if (nodeTable[existingNode].connections.length == 0) {
|
||||||
existingScore += 10000;
|
existingScore += 10000;
|
||||||
}
|
}
|
||||||
if (existingScore * DROP_PENALTY < score.score) {
|
if (existingScore * DROP_PENALTY < score.score) {
|
||||||
//console.log(`Dropping ${existingNode} from ${node1} for better ${score.node}`);
|
//console.log(`Dropping ${existingNode} from ${node1} for better ${score.node}`);
|
||||||
const outIdx = nodeTable[node1].outgoing.indexOf(existingNode);
|
const node1Idx = nodeTable[node1].connections.indexOf(existingNode);
|
||||||
if (outIdx !== -1) {
|
if (node1Idx !== -1) {
|
||||||
nodeTable[node1].outgoing.splice(outIdx, 1);
|
nodeTable[node1].connections.splice(node1Idx, 1);
|
||||||
}
|
}
|
||||||
const inIdx = nodeTable[existingNode].incoming.indexOf(node1);
|
const node2Idx = nodeTable[existingNode].connections.indexOf(node1);
|
||||||
if (inIdx !== -1) {
|
if (node2Idx !== -1) {
|
||||||
nodeTable[existingNode].incoming.splice(inIdx, 1);
|
nodeTable[existingNode].connections.splice(node2Idx, 1);
|
||||||
}
|
}
|
||||||
edges.remove(`${node1}->${existingNode}`);
|
edges.remove(`${node1}->${existingNode}`);
|
||||||
|
edges.remove(`${existingNode}->${node1}`);
|
||||||
dropped = true;
|
dropped = true;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@@ -583,15 +571,15 @@ function main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// still at capacity and nothing was dropped — skip adding this candidate
|
// still at capacity and nothing was dropped — skip adding this candidate
|
||||||
if (nodeTable[node1].outgoing.length >= MAX_OUTGOING_CONNECTIONS && !dropped) {
|
if (nodeTable[node1].connections.length >= MAX_CONNECTIONS && !dropped) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nodeTable[node1].outgoing.includes(score.node) || nodeTable[score.node].incoming.includes(node1)) {
|
if (nodeTable[node1].connections.includes(score.node) || nodeTable[score.node].connections.includes(node1)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
nodeTable[node1].outgoing.push(score.node);
|
nodeTable[node1].connections.push(score.node);
|
||||||
nodeTable[score.node].incoming.push(node1);
|
nodeTable[score.node].connections.push(node1);
|
||||||
connectNodes(node1, score.node);
|
connectNodes(node1, score.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -623,7 +611,7 @@ function onNodeAdd() {
|
|||||||
document.getElementById('addNode').addEventListener('click', function() {
|
document.getElementById('addNode').addEventListener('click', function() {
|
||||||
const nodeId = generateRealisticLabel();
|
const nodeId = generateRealisticLabel();
|
||||||
nodes.add({id: nodeId, label: nodeId});
|
nodes.add({id: nodeId, label: nodeId});
|
||||||
nodeTable[nodeId] = {'incoming': [], 'outgoing': [], 'emergencyIncoming': [], 'emergencyOutgoing': [], 'packetCache': [], 'routingTable': {}};
|
nodeTable[nodeId] = {'connections': [], 'packetCache': [], 'routingTable': {}};
|
||||||
onNodeAdd();
|
onNodeAdd();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -634,7 +622,7 @@ network.on('click', function(properties) {
|
|||||||
if (document.getElementById('quickPlace').checked) {
|
if (document.getElementById('quickPlace').checked) {
|
||||||
const nodeId = generateRealisticLabel();
|
const nodeId = generateRealisticLabel();
|
||||||
nodes.add({id: nodeId, label: nodeId, x: properties.pointer.canvas.x, y: properties.pointer.canvas.y});
|
nodes.add({id: nodeId, label: nodeId, x: properties.pointer.canvas.x, y: properties.pointer.canvas.y});
|
||||||
nodeTable[nodeId] = {'incoming': [], 'outgoing': [], 'emergencyIncoming': [], 'emergencyOutgoing': [], 'packetCache': [], 'routingTable': {}};
|
nodeTable[nodeId] = {'connections': [], 'packetCache': [], 'routingTable': {}};
|
||||||
onNodeAdd();
|
onNodeAdd();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -649,7 +637,7 @@ network.on('doubleClick', function(properties) {
|
|||||||
}
|
}
|
||||||
const nodeId = generateRealisticLabel();
|
const nodeId = generateRealisticLabel();
|
||||||
nodes.add({id: nodeId, label: nodeId, x: properties.pointer.canvas.x, y: properties.pointer.canvas.y});
|
nodes.add({id: nodeId, label: nodeId, x: properties.pointer.canvas.x, y: properties.pointer.canvas.y});
|
||||||
nodeTable[nodeId] = {'incoming': [], 'outgoing': [], 'emergencyIncoming': [], 'emergencyOutgoing': [], 'packetCache': [], 'routingTable': {}};
|
nodeTable[nodeId] = {'connections': [], 'packetCache': [], 'routingTable': {}};
|
||||||
onNodeAdd();
|
onNodeAdd();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -662,7 +650,7 @@ document.getElementById('sendPacket').addEventListener('click', function() {
|
|||||||
var packetShift = generateRealisticLabel();
|
var packetShift = generateRealisticLabel();
|
||||||
let ttl = TTL;
|
let ttl = TTL;
|
||||||
nodes.update({id: selectedNode, color: {background: '#97c2fc'}});
|
nodes.update({id: selectedNode, color: {background: '#97c2fc'}});
|
||||||
for (let connection of nodeTable[selectedNode].outgoing) {
|
for (let connection of nodeTable[selectedNode].connections) {
|
||||||
var movingNode = {
|
var movingNode = {
|
||||||
id: `${packetId}-${packetShift}-${ttl}-${selectedNode}`,
|
id: `${packetId}-${packetShift}-${ttl}-${selectedNode}`,
|
||||||
label: packetId + `-${ttl}`,
|
label: packetId + `-${ttl}`,
|
||||||
@@ -716,12 +704,8 @@ document.getElementById('ttl').addEventListener('change', function() {
|
|||||||
TTL = parseInt(this.value);
|
TTL = parseInt(this.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('maxOutgoingConnections').addEventListener('change', function() {
|
document.getElementById('maxConnections').addEventListener('change', function() {
|
||||||
MAX_OUTGOING_CONNECTIONS = parseInt(this.value);
|
MAX_CONNECTIONS = parseInt(this.value);
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('maxIncomingConnections').addEventListener('change', function() {
|
|
||||||
MAX_INCOMING_CONNECTIONS = parseInt(this.value);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('createRandomGraph').addEventListener('click', function() {
|
document.getElementById('createRandomGraph').addEventListener('click', function() {
|
||||||
@@ -740,7 +724,7 @@ document.getElementById('createRandomGraphConfirm').addEventListener('click', fu
|
|||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
const nodeId = generateRealisticLabel();
|
const nodeId = generateRealisticLabel();
|
||||||
nodes.add({id: nodeId, label: nodeId, x: Math.random() * 1000, y: Math.random() * 1000});
|
nodes.add({id: nodeId, label: nodeId, x: Math.random() * 1000, y: Math.random() * 1000});
|
||||||
nodeTable[nodeId] = {'incoming': [], 'outgoing': [], 'emergencyIncoming': [], 'emergencyOutgoing': [], 'packetCache': [], 'routingTable': {}};
|
nodeTable[nodeId] = {'connections': [], 'packetCache': [], 'routingTable': {}};
|
||||||
onNodeAdd();
|
onNodeAdd();
|
||||||
nodeCounter++;
|
nodeCounter++;
|
||||||
if (nodeCounter >= nodeCount) {
|
if (nodeCounter >= nodeCount) {
|
||||||
|
|||||||
+6
-2
@@ -7,7 +7,7 @@ function calculateDistance(node1, node2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function connectNodes(node1, node2) {
|
function connectNodes(node1, node2) {
|
||||||
if (edges.get(`${node1}->${node2}`)) {
|
if (edges.get(`${node1}->${node2}`) || edges.get(`${node2}->${node1}`)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const edgeId = `${node1}->${node2}`;
|
const edgeId = `${node1}->${node2}`;
|
||||||
@@ -15,7 +15,11 @@ function connectNodes(node1, node2) {
|
|||||||
id: edgeId,
|
id: edgeId,
|
||||||
from: node1,
|
from: node1,
|
||||||
to: node2,
|
to: node2,
|
||||||
smooth: { enabled: true, type: 'curvedCW', roundness: 0.1 }
|
});
|
||||||
|
edges.add({
|
||||||
|
id: `${node2}->${node1}`,
|
||||||
|
from: node2,
|
||||||
|
to: node1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user