diff --git a/src/index.ts b/src/index.ts index 05704c11..2fc2b51f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,9 +13,7 @@ import { Application, Graphics, EventSystem, Assets } from "pixi.js"; import * as pixi_viewport from "pixi-viewport"; import { ViewGraph } from "./types/graphs/viewgraph"; import { - AddPc, - AddRouter, - AddServer, + AddDevice, loadFromFile, loadFromLocalStorage, saveToFile, @@ -24,6 +22,7 @@ import { } from "./types/viewportManager"; import { DataGraph } from "./types/graphs/datagraph"; import { Packet } from "./types/packet"; +import { DeviceType, Layer } from "./types/devices/device"; const WORLD_WIDTH = 10000; const WORLD_HEIGHT = 10000; @@ -41,10 +40,14 @@ export class GlobalContext { loadFromLocalStorage(this); } - load(datagraph: DataGraph) { + private setNetWork(datagraph: DataGraph, layer: Layer) { this.datagraph = datagraph; this.viewport.clear(); - this.viewgraph = new ViewGraph(this.datagraph, this.viewport); + this.viewgraph = new ViewGraph(this.datagraph, this.viewport, layer); + } + + load(datagraph: DataGraph, layer: Layer = Layer.Link) { + this.setNetWork(datagraph, layer); this.setupAutoSave(); saveToLocalStorage(this); } @@ -82,6 +85,11 @@ export class GlobalContext { this.saveIntervalId = null; } } + + // (!) For layer abstraction functionality + // changeViewGraph(layer: string) { + // this.setNetWork(this.datagraph, layerFromName(layer)); + // } } // > graphics.ts @@ -336,13 +344,21 @@ export class RightBar { RightBar.getInstance(); // Add router button - leftBar.addButton(RouterSvg, () => AddRouter(ctx), "Add Router"); + leftBar.addButton( + RouterSvg, + () => AddDevice(ctx, DeviceType.Router), + "Add Router", + ); // Add server button - leftBar.addButton(ServerSvg, () => AddServer(ctx), "Add Server"); + leftBar.addButton( + ServerSvg, + () => AddDevice(ctx, DeviceType.Server), + "Add Server", + ); // Add PC button - leftBar.addButton(ComputerSvg, () => AddPc(ctx), "Add PC"); + leftBar.addButton(ComputerSvg, () => AddDevice(ctx, DeviceType.Pc), "Add PC"); ctx.initialize(viewport); @@ -401,6 +417,22 @@ export class RightBar { pauseButton.onclick = triggerPause; + // (!) For layer abstraction functionality + // const layerSelect = document.getElementById( + // "layer-select", + // ) as HTMLSelectElement; + + // const selectNewLayer = (event: Event) => { + // const selectedLayer = (event.target as HTMLSelectElement).value; + // console.log(`Layer selected: ${selectedLayer}`); + + // if (selectElement) { + // ctx.changeViewGraph(selectedLayer); + // } + // }; + + // layerSelect.onchange = selectNewLayer; + document.body.onkeyup = function (e) { if (e.key === " " || e.code === "Space") { triggerPause(); diff --git a/src/types/devices/device.ts b/src/types/devices/device.ts index 3f16b66a..2d6334d1 100644 --- a/src/types/devices/device.ts +++ b/src/types/devices/device.ts @@ -20,6 +20,19 @@ export const DEVICE_SIZE = 20; let selectedDeviceId: number | null = null; // Stores only the ID instead of 'this' +export enum Layer { + App = 0, + Transport = 1, + Network = 2, + Link = 3, +} + +export enum DeviceType { + Router = 0, + Server = 1, + Pc = 2, +} + export function setSelectedDeviceId(value: number | null) { selectedDeviceId = value; } @@ -300,6 +313,18 @@ export class Device extends Sprite { this.removeHighlight(); // Calls removeHighlight on deselect setSelectedDeviceId(null); } + + getType(): DeviceType { + // Return the device’s type. + // For the superclass, the type returned is Router. + return DeviceType.Router; + } + + getLayer(): Layer { + // Return the device’s layer. + // For the superclass, the layer returned is Link. + return Layer.Link; + } } function onPointerMove(event: FederatedPointerEvent): void { diff --git a/src/types/devices/index.ts b/src/types/devices/index.ts index 5c4075e7..d9426bd0 100644 --- a/src/types/devices/index.ts +++ b/src/types/devices/index.ts @@ -4,3 +4,4 @@ export { Device } from "./device"; export { Router } from "./router"; export { Server } from "./server"; export { Pc } from "./pc"; +export { createDevice } from "./utils"; diff --git a/src/types/devices/pc.ts b/src/types/devices/pc.ts index 3b133d8d..8fbc30fa 100644 --- a/src/types/devices/pc.ts +++ b/src/types/devices/pc.ts @@ -1,6 +1,6 @@ // src/devices/pc.ts -import { Device } from "./device"; +import { Device, DeviceType, Layer } from "./device"; import { ViewGraph } from "../graphs/viewgraph"; import PcImage from "../../assets/pc.svg"; @@ -8,7 +8,7 @@ export class Pc extends Device { constructor( id: number, viewgraph: ViewGraph, - position: { x: number; y: number }, + position: { x: number; y: number } | null = null, ) { super(id, PcImage, viewgraph, position); } @@ -27,4 +27,12 @@ export class Pc extends Device { this.addCommonButtons(); } + + getLayer(): Layer { + return Layer.App; + } + + getType(): DeviceType { + return DeviceType.Pc; + } } diff --git a/src/types/devices/router.ts b/src/types/devices/router.ts index b45cc7f3..fe003578 100644 --- a/src/types/devices/router.ts +++ b/src/types/devices/router.ts @@ -1,6 +1,6 @@ // src/devices/router.ts -import { Device } from "./device"; +import { Device, DeviceType, Layer } from "./device"; import { ViewGraph } from "../graphs/viewgraph"; import RouterImage from "../../assets/router.svg"; @@ -8,7 +8,7 @@ export class Router extends Device { constructor( id: number, viewgraph: ViewGraph, - position: { x: number; y: number }, + position: { x: number; y: number } | null = null, ) { super(id, RouterImage, viewgraph, position); } @@ -27,4 +27,12 @@ export class Router extends Device { this.addCommonButtons(); } + + getLayer(): Layer { + return Layer.Network; + } + + getType(): DeviceType { + return DeviceType.Router; + } } diff --git a/src/types/devices/server.ts b/src/types/devices/server.ts index 084436be..766acce4 100644 --- a/src/types/devices/server.ts +++ b/src/types/devices/server.ts @@ -1,6 +1,6 @@ // src/devices/server.ts -import { Device } from "./device"; +import { Device, DeviceType, Layer } from "./device"; import { ViewGraph } from "../graphs/viewgraph"; import ServerImage from "../../assets/server.svg"; @@ -8,7 +8,7 @@ export class Server extends Device { constructor( id: number, viewgraph: ViewGraph, - position: { x: number; y: number }, + position: { x: number; y: number } | null = null, ) { super(id, ServerImage, viewgraph, position); } @@ -27,4 +27,12 @@ export class Server extends Device { this.addCommonButtons(); } + + getLayer(): Layer { + return Layer.App; + } + + getType(): DeviceType { + return DeviceType.Server; + } } diff --git a/src/types/devices/utils.ts b/src/types/devices/utils.ts new file mode 100644 index 00000000..3c77545a --- /dev/null +++ b/src/types/devices/utils.ts @@ -0,0 +1,42 @@ +import { ViewGraph } from "../graphs/viewgraph"; +import { Device, DeviceType, Layer } from "./device"; +import { Pc } from "./pc"; +import { Router } from "./router"; +import { Server } from "./server"; + +export function createDevice( + type: DeviceType, + id: number, + viewgraph: ViewGraph, + position: { x: number; y: number } | null = null, +): Device { + switch (type) { + case DeviceType.Router: + return new Router(id, viewgraph, position); + case DeviceType.Server: + return new Server(id, viewgraph, position); + case DeviceType.Pc: + return new Pc(id, viewgraph, position); + } +} + +export function layerFromName(name: string): Layer { + switch (name) { + case "application": + // Lógica específica para la capa de aplicación + console.log("Application Layer selected"); + return Layer.App; + case "transport": + // Lógica específica para la capa de transporte + console.log("Transport Layer selected"); + return Layer.Transport; + case "network": + // Lógica específica para la capa de red + console.log("Network Layer selected"); + return Layer.Network; + case "link": + // Lógica específica para la capa de enlace + console.log("Link Layer selected"); + return Layer.Link; + } +} diff --git a/src/types/graphs/datagraph.ts b/src/types/graphs/datagraph.ts index 03664875..9c4b3f85 100644 --- a/src/types/graphs/datagraph.ts +++ b/src/types/graphs/datagraph.ts @@ -1,7 +1,9 @@ +import { DeviceType } from "../devices/device"; + export interface GraphNode { x: number; y: number; - type: string; + type: DeviceType; connections: Set; } @@ -9,7 +11,7 @@ export interface GraphDataNode { id: number; x: number; y: number; - type: string; + type: DeviceType; connections: number[]; } @@ -54,7 +56,7 @@ export class DataGraph { } // Add a new device to the graph - addNewDevice(deviceInfo: { x: number; y: number; type: string }): number { + addNewDevice(deviceInfo: { x: number; y: number; type: DeviceType }): number { const id = this.idCounter++; const graphnode: GraphNode = { ...deviceInfo, diff --git a/src/types/graphs/viewgraph.ts b/src/types/graphs/viewgraph.ts index 8f25d647..42fb8159 100644 --- a/src/types/graphs/viewgraph.ts +++ b/src/types/graphs/viewgraph.ts @@ -1,18 +1,22 @@ -import { Device, Pc, Router, Server } from "./../devices/index"; // Import the Device class +import { Device } from "./../devices/index"; // Import the Device class import { Edge } from "./../edge"; import { DataGraph } from "./datagraph"; import { Viewport } from "../.."; +import { Layer } from "../devices/device"; +import { createDevice } from "../devices/utils"; export class ViewGraph { private devices: Map = new Map(); private edges: Map = new Map(); private idCounter = 1; private datagraph: DataGraph; + private layer: Layer; viewport: Viewport; - constructor(datagraph: DataGraph, viewport: Viewport) { + constructor(datagraph: DataGraph, viewport: Viewport, layer: Layer) { this.datagraph = datagraph; this.viewport = viewport; + this.layer = layer; this.constructView(); } @@ -22,24 +26,13 @@ export class ViewGraph { const connections = new Set<{ deviceId: number; adyacentId: number }>(); this.datagraph.getDevices().forEach(([deviceId, graphNode]) => { - let device: Device; - switch (graphNode.type) { - case "Router": - device = new Router(deviceId, this, { - x: graphNode.x, - y: graphNode.y, - }); - break; - case "Server": - device = new Server(deviceId, this, { - x: graphNode.x, - y: graphNode.y, - }); - break; - case "Pc": - device = new Pc(deviceId, this, { x: graphNode.x, y: graphNode.y }); - break; - } + const position = { x: graphNode.x, y: graphNode.y }; + const device: Device = createDevice( + graphNode.type, + deviceId, + this, + position, + ); this.viewport.addChild(device); diff --git a/src/types/viewportManager.ts b/src/types/viewportManager.ts index 06b795cc..1bd4cd27 100644 --- a/src/types/viewportManager.ts +++ b/src/types/viewportManager.ts @@ -1,9 +1,11 @@ import { GlobalContext } from "./../index"; -import { DataGraph } from "./graphs/datagraph"; +import { DataGraph, GraphData } from "./graphs/datagraph"; import { Device, Pc, Router, Server } from "./devices/index"; import { Edge } from "./edge"; import { RightBar } from "../index"; // Ensure the path is correct import { Packet } from "./packet"; +import { DeviceType } from "./devices/device"; +import { createDevice } from "./devices/utils"; let selectedElement: Device | Edge | Packet | null = null; // Global variable to store the selected element @@ -58,6 +60,43 @@ document.addEventListener("keydown", (event) => { } }); +// Function to add a device at the center of the viewport +export function AddDevice(ctx: GlobalContext, deviceType: DeviceType) { + console.log(`Entered AddDevice with ${deviceType}`); + deselectElement(); + const viewgraph = ctx.getViewGraph(); + const datagraph = ctx.getDataGraph(); + const viewport = ctx.getViewport(); + + // Get the center coordinates of the world after zoom + const worldCenter = viewport.toWorld( + viewport.screenWidth / 2, + viewport.screenHeight / 2, + ); + const position = { x: worldCenter.x, y: worldCenter.y }; + + const idDevice = datagraph.addNewDevice({ + x: position.x, + y: position.y, + type: deviceType, + }); + + const newDevice: Device = createDevice( + deviceType, + idDevice, + viewgraph, + position, + ); + + // Add the Device to the graph + viewgraph.addDevice(newDevice); + viewport.addChild(newDevice); + + console.log( + `${DeviceType[newDevice.getType().valueOf()] !== undefined ? DeviceType[newDevice.getType().valueOf()] : "Unknown"} added with ID ${newDevice.id} at the center of the screen.`, + ); +} + // Function to add a router at the center of the viewport export function AddRouter(ctx: GlobalContext) { console.log("Entered AddRouter"); @@ -75,7 +114,7 @@ export function AddRouter(ctx: GlobalContext) { const idDevice = datagraph.addNewDevice({ x: worldCenter.x, y: worldCenter.y, - type: "Router", + type: DeviceType.Router, }); const device = datagraph.getDevice(idDevice); @@ -109,7 +148,7 @@ export function AddPc(ctx: GlobalContext) { const idDevice = datagraph.addNewDevice({ x: worldCenter.x, y: worldCenter.y, - type: "Pc", + type: DeviceType.Pc, }); const device = datagraph.getDevice(idDevice); @@ -141,7 +180,7 @@ export function AddServer(ctx: GlobalContext) { const idDevice = datagraph.addNewDevice({ x: worldCenter.x, y: worldCenter.y, - type: "Server", + type: DeviceType.Server, }); const device = datagraph.getDevice(idDevice); @@ -189,7 +228,7 @@ export function loadFromFile(ctx: GlobalContext) { reader.onload = (readerEvent) => { const jsonData = readerEvent.target.result as string; - const graphData = JSON.parse(jsonData); + const graphData: GraphData = JSON.parse(jsonData); ctx.load(DataGraph.fromData(graphData)); console.log("Graph loaded successfully."); @@ -211,7 +250,7 @@ export function saveToLocalStorage(ctx: GlobalContext) { export function loadFromLocalStorage(ctx: GlobalContext) { const jsonData = localStorage.getItem(LOCAL_STORAGE_KEY) || "[]"; - const graphData = JSON.parse(jsonData); + const graphData: GraphData = JSON.parse(jsonData); ctx.load(DataGraph.fromData(graphData)); console.log("Graph loaded from local storage.");