summaryrefslogtreecommitdiff
path: root/src/scripts/controllers
diff options
context:
space:
mode:
authorGeorgios Andreadis <g.andreadis@student.tudelft.nl>2017-09-23 09:48:38 +0200
committerGeorgios Andreadis <g.andreadis@student.tudelft.nl>2017-09-23 09:48:38 +0200
commit09596c3c5a6a2a44675f170106bb38746229e02a (patch)
tree763d1b710dc5f2fcab920ac6ab2c555cee4d6342 /src/scripts/controllers
parent057952b0bacc6e963c74bb1bbebbcccd6174a75c (diff)
Remove old frontend
Diffstat (limited to 'src/scripts/controllers')
-rw-r--r--src/scripts/controllers/connection/api.ts1738
-rw-r--r--src/scripts/controllers/connection/cache.ts85
-rw-r--r--src/scripts/controllers/connection/socket.ts76
-rw-r--r--src/scripts/controllers/mapcontroller.ts520
-rw-r--r--src/scripts/controllers/modes/building.ts113
-rw-r--r--src/scripts/controllers/modes/node.ts297
-rw-r--r--src/scripts/controllers/modes/object.ts296
-rw-r--r--src/scripts/controllers/modes/room.ts382
-rw-r--r--src/scripts/controllers/scaleindicator.ts45
-rw-r--r--src/scripts/controllers/simulation/chart.ts241
-rw-r--r--src/scripts/controllers/simulation/statecache.ts321
-rw-r--r--src/scripts/controllers/simulation/taskview.ts64
-rw-r--r--src/scripts/controllers/simulation/timeline.ts161
-rw-r--r--src/scripts/controllers/simulationcontroller.ts586
14 files changed, 0 insertions, 4925 deletions
diff --git a/src/scripts/controllers/connection/api.ts b/src/scripts/controllers/connection/api.ts
deleted file mode 100644
index 1a1c122f..00000000
--- a/src/scripts/controllers/connection/api.ts
+++ /dev/null
@@ -1,1738 +0,0 @@
-///<reference path="../../definitions.ts" />
-///<reference path="../../../../typings/index.d.ts" />
-import {Util} from "../../util";
-import {ServerConnection} from "../../serverconnection";
-
-
-export class APIController {
- constructor(onConnect: (api: APIController) => any) {
- ServerConnection.connect(() => {
- onConnect(this);
- });
- }
-
-
- ///
- // PATH: /users
- ///
-
- // METHOD: GET
- public getUserByEmail(email: string): Promise<IUser> {
- return ServerConnection.send({
- path: "/users",
- method: "GET",
- parameters: {
- body: {},
- path: {},
- query: {
- email
- }
- }
- });
- }
-
- // METHOD: POST
- public addUser(user: IUser): Promise<IUser> {
- return ServerConnection.send({
- path: "/users",
- method: "POST",
- parameters: {
- body: {
- user: user
- },
- path: {},
- query: {}
- }
- });
- }
-
- ///
- // PATH: /users/{id}
- ///
-
- // METHOD: GET
- public getUser(userId: number): Promise<IUser> {
- return ServerConnection.send({
- path: "/users/{userId}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- userId
- },
- query: {}
- }
- });
- }
-
- // METHOD: PUT
- public updateUser(userId: number, user: IUser): Promise<IUser> {
- return ServerConnection.send({
- path: "/users/{userId}",
- method: "PUT",
- parameters: {
- body: {
- user: {
- givenName: user.givenName,
- familyName: user.familyName
- }
- },
- path: {
- userId
- },
- query: {}
- }
- });
- }
-
- // METHOD: DELETE
- public deleteUser(userId: number): Promise<IUser> {
- return ServerConnection.send({
- path: "/users/{userId}",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- userId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /users/{userId}/authorizations
- ///
-
- // METHOD: GET
- public getAuthorizationsByUser(userId: number): Promise<IAuthorization[]> {
- let authorizations = [];
- return ServerConnection.send({
- path: "/users/{userId}/authorizations",
- method: "GET",
- parameters: {
- body: {},
- path: {
- userId
- },
- query: {}
- }
- }).then((data: any) => {
- authorizations = data;
- return this.getUser(userId);
- }).then((userData: any) => {
- const promises = [];
- authorizations.forEach((authorization: IAuthorization) => {
- authorization.user = userData;
- promises.push(this.getSimulation(authorization.simulationId).then((simulationData: any) => {
- authorization.simulation = simulationData;
- }));
- });
- return Promise.all(promises);
- }).then((data: any) => {
- return authorizations;
- });
- }
-
- ///
- // PATH: /simulations
- ///
-
- // METHOD: POST
- public addSimulation(simulation: ISimulation): Promise<ISimulation> {
- return ServerConnection.send({
- path: "/simulations",
- method: "POST",
- parameters: {
- body: {
- simulation: Util.packageForSending(simulation)
- },
- path: {},
- query: {}
- }
- }).then((data: any) => {
- this.parseSimulationTimestamps(data);
- return data;
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}
- ///
-
- // METHOD: GET
- public getSimulation(simulationId: number): Promise<ISimulation> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId
- },
- query: {}
- }
- }).then((data: any) => {
- this.parseSimulationTimestamps(data);
- return data;
- });
- }
-
- // METHOD: PUT
- public updateSimulation(simulation: ISimulation): Promise<ISimulation> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}",
- method: "PUT",
- parameters: {
- body: {
- simulation: Util.packageForSending(simulation)
- },
- path: {
- simulationId: simulation.id
- },
- query: {}
- }
- }).then((data: any) => {
- this.parseSimulationTimestamps(data);
- return data;
- });
- }
-
- // METHOD: DELETE
- public deleteSimulation(simulationId: number): Promise<ISimulation> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- simulationId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/authorizations
- ///
-
- // METHOD: GET
- public getAuthorizationsBySimulation(simulationId: number): Promise<IAuthorization[]> {
- let authorizations = [];
- return ServerConnection.send({
- path: "/simulations/{simulationId}/authorizations",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId
- },
- query: {}
- }
- }).then((data: any) => {
- authorizations = data;
- return this.getSimulation(simulationId);
- }).then((simulationData: any) => {
- const promises = [];
- authorizations.forEach((authorization: IAuthorization) => {
- authorization.simulation = simulationData;
- promises.push(this.getUser(authorization.userId).then((userData: any) => {
- authorization.user = userData;
- }));
- });
- return Promise.all(promises);
- }).then((data: any) => {
- return authorizations;
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/authorizations/{userId}
- ///
-
- // METHOD: GET
- // Not needed
-
- // METHOD: POST
- public addAuthorization(authorization: IAuthorization): Promise<IAuthorization> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/authorizations/{userId}",
- method: "POST",
- parameters: {
- body: {
- authorization: {
- authorizationLevel: authorization.authorizationLevel
- }
- },
- path: {
- simulationId: authorization.simulationId,
- userId: authorization.userId
- },
- query: {}
- }
- });
- }
-
- // METHOD: PUT
- public updateAuthorization(authorization: IAuthorization): Promise<IAuthorization> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/authorizations/{userId}",
- method: "PUT",
- parameters: {
- body: {
- authorization: {
- authorizationLevel: authorization.authorizationLevel
- }
- },
- path: {
- simulationId: authorization.simulationId,
- userId: authorization.userId
- },
- query: {}
- }
- });
- }
-
- // METHOD: DELETE
- public deleteAuthorization(authorization: IAuthorization): Promise<IAuthorization> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/authorizations/{userId}",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- simulationId: authorization.simulationId,
- userId: authorization.userId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}
- ///
-
- // METHOD: GET
- public getDatacenter(simulationId: number, datacenterId: number): Promise<IDatacenter> {
- let datacenter;
-
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId
- },
- query: {}
- }
- }).then((data: any) => {
- datacenter = data;
-
- return this.getRoomsByDatacenter(simulationId, datacenterId);
- }).then((data: any) => {
- datacenter.rooms = data;
- return datacenter;
- });
- }
-
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms
- ///
-
- // METHOD: GET
- public getRoomsByDatacenter(simulationId: number, datacenterId: number): Promise<IRoom[]> {
- let rooms;
-
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId
- },
- query: {}
- }
- }).then((data: any) => {
- rooms = data;
-
- const promises = [];
- rooms.forEach((room: IRoom) => {
- promises.push(this.loadRoomTiles(simulationId, datacenterId, room));
- });
- return Promise.all(promises).then((data: any) => {
- return rooms;
- });
- });
- }
-
- // METHOD: POST
- public addRoomToDatacenter(simulationId: number, datacenterId: number): Promise<IRoom> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms",
- method: "POST",
- parameters: {
- body: {
- room: {
- id: -1,
- datacenterId,
- roomType: "SERVER"
- }
- },
- path: {
- simulationId,
- datacenterId
- },
- query: {}
- }
- }).then((data: any) => {
- data.tiles = [];
- return data;
- });
- }
-
- ///
- // PATH: /room-types
- ///
-
- // METHOD: GET
- public getAllRoomTypes(): Promise<string[]> {
- return ServerConnection.send({
- path: "/room-types",
- method: "GET",
- parameters: {
- body: {},
- path: {},
- query: {}
- }
- }).then((data: any) => {
- const result = [];
- data.forEach((roomType: any) => {
- result.push(roomType.name);
- });
- return result;
- });
- }
-
- ///
- // PATH: /room-types/{name}/allowed-objects
- ///
-
- // METHOD: GET
- public getAllowedObjectsByRoomType(name: string): Promise<string[]> {
- return ServerConnection.send({
- path: "/room-types/{name}/allowed-objects",
- method: "GET",
- parameters: {
- body: {},
- path: {
- name
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}
- ///
-
- // METHOD: GET
- public getRoom(simulationId: number, datacenterId: number, roomId: number): Promise<IRoom> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadRoomTiles(simulationId, datacenterId, data);
- });
- }
-
- // METHOD: PUT
- public updateRoom(simulationId: number, datacenterId: number, room: IRoom): Promise<IRoom> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}",
- method: "PUT",
- parameters: {
- body: {
- room: Util.packageForSending(room)
- },
- path: {
- simulationId,
- datacenterId,
- roomId: room.id
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadRoomTiles(simulationId, datacenterId, data);
- });
- }
-
- // METHOD: DELETE
- public deleteRoom(simulationId: number, datacenterId: number, roomId: number): Promise<IRoom> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles
- ///
-
- // METHOD: GET
- public getTilesByRoom(simulationId: number, datacenterId: number, roomId: number): Promise<ITile[]> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId
- },
- query: {}
- }
- }).then((data: any) => {
- const promises = data.map((item) => {
- return this.loadTileObject(simulationId, datacenterId, roomId, item);
- });
-
- return Promise.all(promises).then(() => {
- return data;
- })
- });
- }
-
- // METHOD: POST
- public addTileToRoom(simulationId: number, datacenterId: number, roomId: number, tile: ITile): Promise<ITile> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles",
- method: "POST",
- parameters: {
- body: {
- tile: Util.packageForSending(tile)
- },
- path: {
- simulationId,
- datacenterId,
- roomId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadTileObject(simulationId, datacenterId, roomId, data);
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}
- ///
-
- // METHOD: GET
- // Not needed (yet)
-
- // METHOD: DELETE
- public deleteTile(simulationId: number, datacenterId: number, roomId: number, tileId: number): Promise<ITile> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/cooling-item
- ///
-
- // METHOD: GET
- public getCoolingItem(simulationId: number, datacenterId: number, roomId: number,
- tileId: number): Promise<ICoolingItem> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/cooling-item",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadFailureModel(data);
- });
- }
-
- // METHOD: POST
- public addCoolingItem(simulationId: number, datacenterId: number, roomId: number, tileId: number,
- coolingItem: ICoolingItem): Promise<ICoolingItem> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/cooling-item",
- method: "POST",
- parameters: {
- body: {
- coolingItem: Util.packageForSending(coolingItem)
- },
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadFailureModel(data);
- });
- }
-
- // METHOD: PUT
- // Not needed (yet)
-
- // METHOD: DELETE
- public deleteCoolingItem(simulationId: number, datacenterId: number, roomId: number,
- tileId: number): Promise<ICoolingItem> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/cooling-item",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/psu
- ///
-
- // METHOD: GET
- public getPSU(simulationId: number, datacenterId: number, roomId: number, tileId: number): Promise<IPSU> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/psu",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadFailureModel(data);
- });
- }
-
- // METHOD: POST
- public addPSU(simulationId: number, datacenterId: number, roomId: number, tileId: number,
- psu: IPSU): Promise<IPSU> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/psu",
- method: "POST",
- parameters: {
- body: {
- psu: Util.packageForSending(psu)
- },
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadFailureModel(data);
- });
- }
-
- // METHOD: PUT
- // Not needed (yet)
-
- // METHOD: DELETE
- public deletePSU(simulationId: number, datacenterId: number, roomId: number,
- tileId: number): Promise<IPSU> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/psu",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack
- ///
-
- // METHOD: GET
- public getRack(simulationId: number, datacenterId: number, roomId: number,
- tileId: number): Promise<IRack> {
- let rack = {};
-
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- rack = data;
- return this.getMachinesByRack(simulationId, datacenterId, roomId, tileId);
- }).then((machines: any) => {
- const promises = machines.map((machine) => {
- return this.loadMachineUnits(machine);
- });
-
-
- return Promise.all(promises).then(() => {
- rack["machines"] = [];
-
- machines.forEach((machine: IMachine) => {
- rack["machines"][machine.position] = machine;
- });
-
- for (let i = 0; i < rack["capacity"]; i++) {
- if (rack["machines"][i] === undefined) {
- rack["machines"][i] = null;
- }
- }
-
- return <IRack>rack;
- });
- });
- }
-
- // METHOD: POST
- public addRack(simulationId: number, datacenterId: number, roomId: number,
- tileId: number, rack: IRack): Promise<IRack> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack",
- method: "POST",
- parameters: {
- body: {
- rack: Util.packageForSending(rack)
- },
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- data.machines = [];
-
- for (let i = 0; i < data.capacity; i++) {
- data.machines.push(null);
- }
-
- return data;
- });
- }
-
- // METHOD: PUT
- public updateRack(simulationId: number, datacenterId: number, roomId: number,
- tileId: number, rack: IRack): Promise<IRack> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack",
- method: "PUT",
- parameters: {
- body: {
- rack
- },
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- data.machines = rack.machines;
-
- return data;
- });
- }
-
- // METHOD: DELETE
- public deleteRack(simulationId: number, datacenterId: number, roomId: number,
- tileId: number): Promise<IRack> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines
- ///
-
- // METHOD: GET
- public getMachinesByRack(simulationId: number, datacenterId: number, roomId: number,
- tileId: number): Promise<IMachine[]> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- const promises = data.map((machine) => {
- return this.loadMachineUnits(machine);
- });
-
- return Promise.all(promises).then(() => {
- return data;
- });
- });
- }
-
- // METHOD: POST
- public addMachineToRack(simulationId: number, datacenterId: number, roomId: number,
- tileId: number, machine: IMachine): Promise<IMachine> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines",
- method: "POST",
- parameters: {
- body: {
- machine: Util.packageForSending(machine)
- },
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadMachineUnits(data);
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines/{position}
- ///
-
- // METHOD: GET
- // Not needed (yet)
-
- // METHOD: PUT
- public updateMachine(simulationId: number, datacenterId: number, roomId: number,
- tileId: number, machine: IMachine): Promise<IMachine> {
- machine["tags"] = [];
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines/{position}",
- method: "PUT",
- parameters: {
- body: {
- machine: Util.packageForSending(machine)
- },
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId,
- position: machine.position
- },
- query: {}
- }
- }).then((data: any) => {
- return this.loadMachineUnits(data);
- });
- }
-
- // METHOD: DELETE
- public deleteMachine(simulationId: number, datacenterId: number, roomId: number,
- tileId: number, position: number): Promise<any> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines/{position}",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- simulationId,
- datacenterId,
- roomId,
- tileId,
- position
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/experiments
- ///
-
- // METHOD: GET
- public getExperimentsBySimulation(simulationId: number): Promise<IExperiment[]> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId
- },
- query: {}
- }
- }).then((data: any) => {
- const promises = data.map((item: any) => {
- return this.getTrace(item.traceId).then((traceData: any) => {
- item.trace = traceData;
- });
- });
- return Promise.all(promises).then(() => {
- return data;
- });
- });
- }
-
- // METHOD: POST
- public addExperimentToSimulation(simulationId: number, experiment: IExperiment): Promise<IExperiment> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments",
- method: "POST",
- parameters: {
- body: {
- experiment: Util.packageForSending(experiment)
- },
- path: {
- simulationId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.getTrace(data.traceId).then((traceData: any) => {
- data.trace = traceData;
-
- return data;
- });
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/experiments/{experimentId}
- ///
-
- // METHOD: GET
- // Not needed (yet)
-
- // METHOD: PUT
- public updateExperiment(experiment: IExperiment): Promise<IExperiment> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments/{experimentId}",
- method: "PUT",
- parameters: {
- body: {
- experiment: Util.packageForSending(experiment)
- },
- path: {
- experimentId: experiment.id,
- simulationId: experiment.simulationId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.getTrace(data.traceId).then((traceData: any) => {
- data.trace = traceData;
-
- return data;
- });
- });
- }
-
- // METHOD: DELETE
- public deleteExperiment(simulationId: number, experimentId: number): Promise<any> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments/{experimentId}",
- method: "DELETE",
- parameters: {
- body: {},
- path: {
- experimentId,
- simulationId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/experiments/{experimentId}/last-simulated-tick
- ///
-
- // METHOD: GET
- public getLastSimulatedTickByExperiment(simulationId: number, experimentId: number): Promise<number> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments/{experimentId}/last-simulated-tick",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- experimentId
- },
- query: {}
- }
- }).then((data: any) => {
- return data.lastSimulatedTick;
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/experiments/{experimentId}/machine-states
- ///
-
- // METHOD: GET
- public getMachineStates(simulationId: number, experimentId: number, machines: {[keys: number]: IMachine},
- tick?: number): Promise<IMachineState[]> {
- let query;
- if (tick !== undefined) {
- query = {tick};
- } else {
- query = {};
- }
-
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments/{experimentId}/machine-states",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- experimentId
- },
- query
- }
- }).then((data: any) => {
- data.forEach((item: any) => {
- item.machine = machines[item.machineId];
- });
-
- return data;
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/experiments/{experimentId}/rack-states
- ///
-
- // METHOD: GET
- public getRackStates(simulationId: number, experimentId: number, racks: {[keys: number]: IRack},
- tick?: number): Promise<IRackState[]> {
- let query;
- if (tick !== undefined) {
- query = {tick};
- } else {
- query = {};
- }
-
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments/{experimentId}/rack-states",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- experimentId
- },
- query: query
- }
- }).then((data: any) => {
- data.forEach((item: any) => {
- item.rack = racks[item.rackId];
- });
-
- return data;
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/experiments/{experimentId}/room-states
- ///
-
- // METHOD: GET
- public getRoomStates(simulationId: number, experimentId: number, rooms: {[keys: number]: IRoom},
- tick?: number): Promise<IRoomState[]> {
- let query;
- if (tick !== undefined) {
- query = {tick};
- } else {
- query = {};
- }
-
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments/{experimentId}/room-states",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- experimentId
- },
- query
- }
- }).then((data: any) => {
- data.forEach((item: any) => {
- item.room = rooms[item.roomId];
- });
-
- return data;
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/experiments/{experimentId}/task-states
- ///
-
- // METHOD: GET
- public getTaskStates(simulationId: number, experimentId: number, tasks: {[keys: number]: ITask},
- tick?: number): Promise<ITaskState[]> {
- let query;
- if (tick === undefined) {
- query = {tick};
- } else {
- query = {};
- }
-
- return ServerConnection.send({
- path: "/simulations/{simulationId}/experiments/{experimentId}/task-states",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- experimentId
- },
- query
- }
- }).then((data: any) => {
- data.forEach((item: any) => {
- item.task = tasks[item.taskId];
- });
-
- return data;
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/paths
- ///
-
- // METHOD: GET
- public getPathsBySimulation(simulationId: number): Promise<IPath[]> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/paths",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId
- },
- query: {}
- }
- }).then((data: any) => {
- const promises = data.map((item: any) => {
- return this.getSectionsByPath(simulationId, item.id).then((sectionsData: any) => {
- item.sections = sectionsData;
- });
- });
- return Promise.all(promises).then(() => {
- return data;
- });
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/paths/{pathId}
- ///
-
- // METHOD: GET
- public getPath(simulationId: number, pathId: number): Promise<IPath> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/paths/{pathId}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- pathId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.getSectionsByPath(simulationId, pathId).then((sectionsData: any) => {
- data.sections = sectionsData;
- return data;
- });
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/paths/{pathId}/branches
- ///
-
- // METHOD: GET
- public getBranchesByPath(simulationId: number, pathId: number): Promise<IPath[]> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/paths/{pathId}/branches",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- pathId
- },
- query: {}
- }
- }).then((data: any) => {
- const promises = data.map((item: any) => {
- return this.getSectionsByPath(simulationId, item.id).then((sectionsData: any) => {
- item.sections = sectionsData;
- });
- });
- return Promise.all(promises).then(() => {
- return data;
- });
- });
- }
-
- // METHOD: POST
- public branchFromPath(simulationId: number, pathId: number, startTick: number): Promise<IPath> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/paths/{pathId}/branches",
- method: "POST",
- parameters: {
- body: {
- section: {
- startTick
- }
- },
- path: {
- simulationId,
- pathId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.getSectionsByPath(simulationId, data.id).then((sectionsData: any) => {
- data.sections = sectionsData;
- return data;
- });
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/paths/{pathId}/sections
- ///
-
- // METHOD: GET
- public getSectionsByPath(simulationId: number, pathId: number): Promise<IPath[]> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/paths/{pathId}/sections",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- pathId
- },
- query: {}
- }
- }).then((data: any) => {
- const promises = data.map((path: ISection) => {
- return this.getDatacenter(simulationId, path.datacenterId).then((datacenter: any) => {
- path.datacenter = datacenter;
- });
- });
- return Promise.all(promises).then(() => {
- return data;
- });
- });
- }
-
- ///
- // PATH: /simulations/{simulationId}/paths/{pathId}/sections/{sectionId}
- ///
-
- // METHOD: GET
- public getSection(simulationId: number, pathId: number, sectionId: number): Promise<ISection> {
- return ServerConnection.send({
- path: "/simulations/{simulationId}/paths/{pathId}/sections/{sectionId}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- simulationId,
- pathId,
- sectionId
- },
- query: {}
- }
- }).then((data: any) => {
- return this.getDatacenter(simulationId, data.datacenterId).then((datacenter: any) => {
- data.datacenter = datacenter;
- return data;
- });
- });
- }
-
- ///
- // PATH: /specifications/psus
- ///
-
- // METHOD: GET
- public getAllPSUSpecs(): Promise<IPSU[]> {
- let psus;
- return ServerConnection.send({
- path: "/specifications/psus",
- method: "GET",
- parameters: {
- body: {},
- path: {},
- query: {}
- }
- }).then((data: any) => {
- psus = data;
-
- const promises = [];
- data.forEach((psu: IPSU) => {
- promises.push(this.getFailureModel(psu.failureModelId));
- });
- return Promise.all(promises);
- }).then((data: any) => {
- return psus;
- });
- }
-
- ///
- // PATH: /specifications/psus/{id}
- ///
-
- // METHOD: GET
- public getPSUSpec(id: number): Promise<IPSU> {
- let psu;
-
- return ServerConnection.send({
- path: "/specifications/psus/{id}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- id
- },
- query: {}
- }
- }).then((data: any) => {
- psu = data;
- return this.getFailureModel(data.failureModelId);
- }).then((data: any) => {
- psu.failureModel = data;
- return psu;
- });
- }
-
- ///
- // PATH: /specifications/cooling-items
- ///
-
- // METHOD: GET
- public getAllCoolingItemSpecs(): Promise<ICoolingItem[]> {
- let coolingItems;
-
- return ServerConnection.send({
- path: "/specifications/cooling-items",
- method: "GET",
- parameters: {
- body: {},
- path: {},
- query: {}
- }
- }).then((data: any) => {
- coolingItems = data;
-
- const promises = [];
- data.forEach((item: ICoolingItem) => {
- promises.push(this.getFailureModel(item.failureModelId));
- });
- return Promise.all(promises);
- }).then((data: any) => {
- return coolingItems;
- });
- }
-
- ///
- // PATH: /specifications/cooling-items/{id}
- ///
-
- // METHOD: GET
- public getCoolingItemSpec(id: number): Promise<IPSU> {
- let coolingItem;
-
- return ServerConnection.send({
- path: "/specifications/cooling-items/{id}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- id
- },
- query: {}
- }
- }).then((data: any) => {
- coolingItem = data;
- return this.getFailureModel(data.failureModelId);
- }).then((data: any) => {
- coolingItem.failureModel = data;
- return coolingItem;
- });
- }
-
- ///
- // PATH: /schedulers
- ///
-
- // METHOD: GET
- public getAllSchedulers(): Promise<IScheduler[]> {
- return ServerConnection.send({
- path: "/schedulers",
- method: "GET",
- parameters: {
- body: {},
- path: {},
- query: {}
- }
- });
- }
-
- ///
- // PATH: /traces
- ///
-
- // METHOD: GET
- public getAllTraces(): Promise<ITrace[]> {
- return ServerConnection.send({
- path: "/traces",
- method: "GET",
- parameters: {
- body: {},
- path: {},
- query: {}
- }
- });
- }
-
- ///
- // PATH: /traces/{traceId}
- ///
-
- // METHOD: GET
- public getTrace(traceId: number): Promise<ITrace> {
- let trace;
-
- return ServerConnection.send({
- path: "/traces/{traceId}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- traceId
- },
- query: {}
- }
- }).then((data: any) => {
- trace = data;
- return this.getTasksByTrace(traceId);
- }).then((data: any) => {
- trace.tasks = data;
- return trace;
- });
- }
-
- ///
- // PATH: /traces/{traceId}/tasks
- ///
-
- // METHOD: GET
- public getTasksByTrace(traceId: number): Promise<ITask[]> {
- return ServerConnection.send({
- path: "/traces/{traceId}/tasks",
- method: "GET",
- parameters: {
- body: {},
- path: {
- traceId
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /specifications/failure-models
- ///
-
- // METHOD: GET
- public getAllFailureModels(): Promise<IFailureModel[]> {
- return ServerConnection.send({
- path: "/specifications/failure-models",
- method: "GET",
- parameters: {
- body: {},
- path: {},
- query: {}
- }
- });
- }
-
- ///
- // PATH: /specifications/failure-models/{id}
- ///
-
- // METHOD: GET
- public getFailureModel(id: number): Promise<IFailureModel> {
- return ServerConnection.send({
- path: "/specifications/failure-models/{id}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- id
- },
- query: {}
- }
- });
- }
-
- ///
- // PATH: /specifications/[units]
- ///
-
- // METHOD: GET
- public getAllSpecificationsOfType(typePlural: string): Promise<INodeUnit> {
- let specs: any;
- return ServerConnection.send({
- path: "/specifications/" + typePlural,
- method: "GET",
- parameters: {
- body: {},
- path: {},
- query: {}
- }
- }).then((data: any) => {
- specs = data;
-
- const promises = [];
- data.forEach((unit: INodeUnit) => {
- promises.push(this.getFailureModel(unit.failureModelId));
- });
- return Promise.all(promises);
- }).then((data: any) => {
- return specs;
- });
- }
-
- ///
- // PATH: /specifications/[units]/{id}
- ///
-
- // METHOD: GET
- public getSpecificationOfType(typePlural: string, id: number): Promise<INodeUnit> {
- let spec;
-
- return ServerConnection.send({
- path: "/specifications/" + typePlural + "/{id}",
- method: "GET",
- parameters: {
- body: {},
- path: {
- id
- },
- query: {}
- }
- }).then((data: any) => {
- spec = data;
- return this.getFailureModel(data.failureModelId);
- }).then((data: any) => {
- spec.failureModel = data;
- return spec;
- });
- }
-
-
- ///
- // HELPER METHODS
- ///
-
- private loadRoomTiles(simulationId: number, datacenterId: number, room: IRoom): Promise<IRoom> {
- return this.getTilesByRoom(simulationId, datacenterId, room.id).then((data: any) => {
- room.tiles = data;
- return room;
- });
- }
-
- private loadTileObject(simulationId: number, datacenterId: number, roomId: number, tile: ITile): Promise<ITile> {
- let promise;
-
- switch (tile.objectType) {
- case "RACK":
- promise = this.getRack(simulationId, datacenterId, roomId, tile.id).then((data: IRack) => {
- tile.object = data;
- });
- break;
- case "PSU":
- promise = this.getPSU(simulationId, datacenterId, roomId, tile.id).then((data: IPSU) => {
- tile.object = data;
- });
- break;
- case "COOLING_ITEM":
- promise = this.getCoolingItem(simulationId, datacenterId, roomId, tile.id).then((data: ICoolingItem) => {
- tile.object = data;
- });
- break;
- default:
- promise = new Promise((resolve, reject) => {
- resolve(undefined);
- });
- }
-
- return promise.then(() => {
- return tile;
- })
- }
-
- private parseSimulationTimestamps(simulation: ISimulation): void {
- simulation.datetimeCreatedParsed = Util.parseDateTime(simulation.datetimeCreated);
- simulation.datetimeLastEditedParsed = Util.parseDateTime(simulation.datetimeLastEdited);
- }
-
- private loadFailureModel(data: any): Promise<any> {
- return this.getFailureModel(data.failureModelId).then((failureModel: IFailureModel) => {
- data.failureModel = failureModel;
- return data;
- });
- }
-
- private loadUnitsOfType(idListName: string, objectListName: string, machine: IMachine): Promise<IMachine> {
- machine[objectListName] = [];
-
- const promises = machine[idListName].map((item) => {
- return this.getSpecificationOfType(objectListName, item).then((data) => {
- machine[objectListName].push(data);
- });
- });
-
- return Promise.all(promises).then(() => {
- return machine;
- })
- }
-
- private loadMachineUnits(machine: IMachine): Promise<IMachine> {
- const listNames = [
- {
- idListName: "cpuIds",
- objectListName: "cpus"
- }, {
- idListName: "gpuIds",
- objectListName: "gpus"
- }, {
- idListName: "memoryIds",
- objectListName: "memories"
- }, {
- idListName: "storageIds",
- objectListName: "storages"
- }
- ];
-
- const promises = listNames.map((item: any) => {
- return this.loadUnitsOfType(item.idListName, item.objectListName, machine);
- });
-
- return Promise.all(promises).then(() => {
- return machine;
- });
- }
-}
diff --git a/src/scripts/controllers/connection/cache.ts b/src/scripts/controllers/connection/cache.ts
deleted file mode 100644
index c1c47c2d..00000000
--- a/src/scripts/controllers/connection/cache.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-export enum CacheStatus {
- MISS,
- FETCHING,
- HIT,
- NOT_CACHABLE
-}
-
-
-interface ICachableObject {
- status: CacheStatus;
- object: any;
- callbacks: any[];
-}
-
-
-export class CacheController {
- private static CACHABLE_ROUTES = [
- "/specifications/psus/{id}",
- "/specifications/cooling-items/{id}",
- "/specifications/cpus/{id}",
- "/specifications/gpus/{id}",
- "/specifications/memories/{id}",
- "/specifications/storages/{id}",
- "/specifications/failure-models/{id}",
- ];
-
- // Maps every route name to a map of IDs => objects
- private routeCaches: { [keys: string]: { [keys: number]: ICachableObject } };
-
-
- constructor() {
- this.routeCaches = {};
-
- CacheController.CACHABLE_ROUTES.forEach((routeName: string) => {
- this.routeCaches[routeName] = {};
- })
- }
-
- public checkCache(request: IRequest): CacheStatus {
- if (request.method === "GET" && CacheController.CACHABLE_ROUTES.indexOf(request.path) !== -1) {
- if (this.routeCaches[request.path][request.parameters.path["id"]] === undefined) {
- this.routeCaches[request.path][request.parameters.path["id"]] = {
- status: CacheStatus.MISS,
- object: null,
- callbacks: []
- };
- return CacheStatus.MISS;
- } else {
- return this.routeCaches[request.path][request.parameters.path["id"]].status;
- }
- } else {
- return CacheStatus.NOT_CACHABLE;
- }
- }
-
- public fetchFromCache(request: IRequest): any {
- return this.routeCaches[request.path][request.parameters.path["id"]].object;
- }
-
- public setToFetching(request: IRequest): void {
- this.routeCaches[request.path][request.parameters.path["id"]].status = CacheStatus.FETCHING;
- }
-
- public onFetch(request: IRequest, response: IResponse): any {
- const pathWithoutVersion = request.path.replace(/\/v\d+/, "");
- this.routeCaches[pathWithoutVersion][request.parameters.path["id"]].status = CacheStatus.HIT;
- this.routeCaches[pathWithoutVersion][request.parameters.path["id"]].object = response.content;
-
- this.routeCaches[pathWithoutVersion][request.parameters.path["id"]].callbacks.forEach((callback) => {
- callback({
- status: {
- code: 200
- },
- content: response.content,
- id: request.id
- });
- });
-
- this.routeCaches[pathWithoutVersion][request.parameters.path["id"]].callbacks = [];
- }
-
- public registerCallback(request: IRequest, callback): any {
- this.routeCaches[request.path][request.parameters.path["id"]].callbacks.push(callback);
- }
-}
diff --git a/src/scripts/controllers/connection/socket.ts b/src/scripts/controllers/connection/socket.ts
deleted file mode 100644
index 91a0f9e4..00000000
--- a/src/scripts/controllers/connection/socket.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import {CacheController, CacheStatus} from "./cache";
-import * as io from "socket.io-client";
-
-
-export class SocketController {
- private static id = 1;
- private _socket: SocketIOClient.Socket;
- private _cacheController: CacheController;
-
- // Mapping from request IDs to their registered callbacks
- private callbacks: { [keys: number]: (response: IResponse) => any };
-
-
- constructor(onConnect: () => any) {
- this.callbacks = {};
- this._cacheController = new CacheController();
-
- this._socket = io.connect('SERVER_BASE_URL');
- this._socket.on('connect', onConnect);
-
- this._socket.on('response', (jsonResponse: string) => {
- const response: IResponse = JSON.parse(jsonResponse);
- console.log("Response, ID:", response.id, response);
- this.callbacks[response.id](response);
- delete this.callbacks[response.id];
- });
- }
-
- /**
- * Sends a request to the server socket and registers the callback to be triggered on response.
- *
- * @param request The request instance to be sent
- * @param callback A function to be called with the response object once the socket has received a response
- */
- public sendRequest(request: IRequest, callback: (response: IResponse) => any): void {
- // Check local cache, in case request is for cachable GET route
- const cacheStatus = this._cacheController.checkCache(request);
-
- if (cacheStatus === CacheStatus.HIT) {
- callback({
- status: {
- code: 200
- },
- content: this._cacheController.fetchFromCache(request),
- id: -1
- });
- } else if (cacheStatus === CacheStatus.FETCHING) {
- this._cacheController.registerCallback(request, callback);
- } else if (cacheStatus === CacheStatus.MISS || cacheStatus === CacheStatus.NOT_CACHABLE) {
- if (!this._socket.connected) {
- console.error("Socket not connected, sending request failed");
- }
-
- if (cacheStatus === CacheStatus.MISS) {
- this._cacheController.setToFetching(request);
-
- this.callbacks[SocketController.id] = (response: IResponse) => {
- this._cacheController.onFetch(request, response);
- callback(response);
- };
- } else {
- this.callbacks[SocketController.id] = callback;
- }
-
- // Setup request object
- request.id = SocketController.id;
- request.token = localStorage.getItem("googleToken");
- request.path = "/v1" + request.path;
-
- console.log("Request, ID:", request.id, request);
- this._socket.emit("request", request);
-
- SocketController.id++;
- }
- }
-}
diff --git a/src/scripts/controllers/mapcontroller.ts b/src/scripts/controllers/mapcontroller.ts
deleted file mode 100644
index 4ad1b20b..00000000
--- a/src/scripts/controllers/mapcontroller.ts
+++ /dev/null
@@ -1,520 +0,0 @@
-///<reference path="../../../typings/index.d.ts" />
-///<reference path="../views/mapview.ts" />
-import * as $ from "jquery";
-import {Colors} from "../colors";
-import {Util} from "../util";
-import {SimulationController} from "./simulationcontroller";
-import {MapView} from "../views/mapview";
-import {APIController} from "./connection/api";
-import {BuildingModeController} from "./modes/building";
-import {RoomModeController, RoomInteractionMode} from "./modes/room";
-import {ObjectModeController} from "./modes/object";
-import {NodeModeController} from "./modes/node";
-import {ScaleIndicatorController} from "./scaleindicator";
-
-export const CELL_SIZE = 50;
-
-
-export enum AppMode {
- CONSTRUCTION,
- SIMULATION
-}
-
-
-/**
- * The current level of datacenter hierarchy that is selected
- */
-export enum InteractionLevel {
- BUILDING,
- ROOM,
- OBJECT,
- NODE
-}
-
-
-/**
- * Possible states that the application can be in, in terms of interaction
- */
-export enum InteractionMode {
- DEFAULT,
- SELECT_ROOM
-}
-
-
-/**
- * Class responsible for handling user input in the map.
- */
-export class MapController {
- public stage: createjs.Stage;
- public mapView: MapView;
-
- public appMode: AppMode;
- public interactionLevel: InteractionLevel;
- public interactionMode: InteractionMode;
-
- public buildingModeController: BuildingModeController;
- public roomModeController: RoomModeController;
- public objectModeController: ObjectModeController;
- public nodeModeController: NodeModeController;
-
- public simulationController: SimulationController;
- public api: APIController;
- private scaleIndicatorController: ScaleIndicatorController;
-
- private canvas: JQuery;
- private gridDragging: boolean;
-
- private infoTimeOut: any;
- // Current mouse coordinates on the stage canvas (mainly for zooming purposes)
- private currentStageMouseX: number;
-
- private currentStageMouseY: number;
- // Keep start coordinates relative to the grid to compute dragging offset later
- private gridDragBeginX: number;
-
- private gridDragBeginY: number;
- // Keep start coordinates on stage to compute delta values
- private stageDragBeginX: number;
- private stageDragBeginY: number;
-
- private MAX_DELTA = 5;
-
-
- /**
- * Hides all side menus except for the active one.
- *
- * @param activeMenu An identifier (e.g. #room-menu) for the menu container
- */
- public static hideAndShowMenus(activeMenu: string): void {
- $(".menu-container.level-menu").each((index: number, elem: Element) => {
- if ($(elem).is(activeMenu)) {
- $(elem).removeClass("hidden");
- } else {
- $(elem).addClass("hidden");
- }
- });
- }
-
- constructor(mapView: MapView) {
- this.mapView = mapView;
- this.stage = this.mapView.stage;
-
- new APIController((apiInstance: APIController) => {
- this.api = apiInstance;
-
- this.buildingModeController = new BuildingModeController(this);
- this.roomModeController = new RoomModeController(this);
- this.objectModeController = new ObjectModeController(this);
- this.nodeModeController = new NodeModeController(this);
- this.simulationController = new SimulationController(this);
-
- this.scaleIndicatorController = new ScaleIndicatorController(this);
-
- this.canvas = $("#main-canvas");
-
- $(window).on("resize", () => {
- this.onWindowResize();
- });
-
- this.gridDragging = false;
-
- this.appMode = AppMode.CONSTRUCTION;
- this.interactionLevel = InteractionLevel.BUILDING;
- this.interactionMode = InteractionMode.DEFAULT;
-
- this.setAllMenuModes();
-
- this.setupMapInteractionHandlers();
- this.setupEventListeners();
- this.buildingModeController.setupEventListeners();
- this.roomModeController.setupEventListeners();
- this.objectModeController.setupEventListeners();
- this.nodeModeController.setupEventListeners();
-
- this.scaleIndicatorController.init($(".scale-indicator"));
- this.scaleIndicatorController.update();
-
- this.mapView.roomLayer.setClickable(true);
-
- this.matchUserAuthLevel();
- });
- }
-
- /**
- * Hides and shows the menu bodies corresponding to the current mode (construction or simulation).
- */
- public setAllMenuModes(): void {
- $(".menu-body" + (this.appMode === AppMode.CONSTRUCTION ? ".construction" : ".simulation")).show();
- $(".menu-body" + (this.appMode === AppMode.CONSTRUCTION ? ".simulation" : ".construction")).hide();
- }
-
- /**
- * Checks whether the mapContainer is still within its legal bounds.
- *
- * Resets, if necessary, to the most similar still legal position.
- */
- public checkAndResetCanvasMovement(): void {
- if (this.mapView.mapContainer.x + this.mapView.gridLayer.gridPixelSize *
- this.mapView.mapContainer.scaleX < this.mapView.canvasWidth) {
- this.mapView.mapContainer.x = this.mapView.canvasWidth - this.mapView.gridLayer.gridPixelSize *
- this.mapView.mapContainer.scaleX;
- }
- if (this.mapView.mapContainer.x > 0) {
- this.mapView.mapContainer.x = 0;
- }
- if (this.mapView.mapContainer.y + this.mapView.gridLayer.gridPixelSize *
- this.mapView.mapContainer.scaleX < this.mapView.canvasHeight) {
- this.mapView.mapContainer.y = this.mapView.canvasHeight - this.mapView.gridLayer.gridPixelSize *
- this.mapView.mapContainer.scaleX;
- }
- if (this.mapView.mapContainer.y > 0) {
- this.mapView.mapContainer.y = 0;
- }
- }
-
- /**
- * Checks whether the mapContainer is still within its legal bounds and generates corrections if needed.
- *
- * Does not change the x and y coordinates, only returns.
- */
- public checkCanvasMovement(x: number, y: number, scale: number): IGridPosition {
- const result: IGridPosition = {x: x, y: y};
- if (x + this.mapView.gridLayer.gridPixelSize * scale < this.mapView.canvasWidth) {
- result.x = this.mapView.canvasWidth - this.mapView.gridLayer.gridPixelSize *
- this.mapView.mapContainer.scaleX;
- }
- if (x > 0) {
- result.x = 0;
- }
- if (y + this.mapView.gridLayer.gridPixelSize * scale < this.mapView.canvasHeight) {
- result.y = this.mapView.canvasHeight - this.mapView.gridLayer.gridPixelSize *
- this.mapView.mapContainer.scaleX;
- }
- if (y > 0) {
- result.y = 0;
- }
-
- return result;
- }
-
- /**
- * Checks whether the current interaction mode is a hover mode (meaning that there is a hover item present).
- *
- * @returns {boolean} Whether it is in hover mode.
- */
- public isInHoverMode(): boolean {
- return this.roomModeController !== undefined &&
- (this.interactionMode === InteractionMode.SELECT_ROOM ||
- this.roomModeController.roomInteractionMode === RoomInteractionMode.ADD_RACK ||
- this.roomModeController.roomInteractionMode === RoomInteractionMode.ADD_PSU ||
- this.roomModeController.roomInteractionMode === RoomInteractionMode.ADD_COOLING_ITEM);
- }
-
- public static showConfirmDeleteDialog(itemType: string, onConfirm: () => void): void {
- const modalDialog = <any>$("#confirm-delete");
- modalDialog.find(".modal-body").text("Are you sure you want to delete this " + itemType + "?");
-
- const callback = () => {
- onConfirm();
- modalDialog.modal("hide");
- modalDialog.find("button.confirm").first().off("click");
- $(document).off("keypress");
- };
-
- $(document).on("keypress", (event: JQueryEventObject) => {
- if (event.which === 13) {
- callback();
- } else if (event.which === 27) {
- modalDialog.modal("hide");
- $(document).off("keypress");
- modalDialog.find("button.confirm").first().off("click");
- }
- });
- modalDialog.find("button.confirm").first().on("click", callback);
- modalDialog.modal("show");
- }
-
- /**
- * Shows an informational popup in a corner of the screen, communicating a certain event.
- *
- * @param message The message to be displayed in the body of the popup
- * @param type The severity of the message; Currently supported: "info" and "warning"
- */
- public showInfoBalloon(message: string, type: string): void {
- const balloon = $(".info-balloon");
- balloon.html('<span></span>' + message);
- const callback = () => {
- balloon.fadeOut(300);
-
- this.infoTimeOut = undefined;
- };
- const DISPLAY_TIME = 3000;
-
- const balloonIcon = balloon.find("span").first();
- balloonIcon.removeClass();
-
- balloon.css("background", Colors.INFO_BALLOON_MAP[type]);
- balloonIcon.addClass("glyphicon");
- if (type === "info") {
- balloonIcon.addClass("glyphicon-info-sign");
- } else if (type === "warning") {
- balloonIcon.addClass("glyphicon-exclamation-sign");
- }
-
- if (this.infoTimeOut === undefined) {
- balloon.fadeIn(300);
- this.infoTimeOut = setTimeout(callback, DISPLAY_TIME);
- } else {
- clearTimeout(this.infoTimeOut);
- this.infoTimeOut = setTimeout(callback, DISPLAY_TIME);
- }
- }
-
- private setupMapInteractionHandlers(): void {
- this.stage.enableMouseOver(20);
-
- // Listen for mouse movement events to update hover positions
- this.stage.on("stagemousemove", (event: createjs.MouseEvent) => {
- this.currentStageMouseX = event.stageX;
- this.currentStageMouseY = event.stageY;
-
- const gridPos = this.convertScreenCoordsToGridCoords([event.stageX, event.stageY]);
- const tileX = gridPos.x;
- const tileY = gridPos.y;
-
- // Check whether the coordinates of the hover location have changed since the last draw
- if (this.mapView.hoverLayer.hoverTilePosition.x !== tileX) {
- this.mapView.hoverLayer.hoverTilePosition.x = tileX;
- this.mapView.updateScene = true;
- }
- if (this.mapView.hoverLayer.hoverTilePosition.y !== tileY) {
- this.mapView.hoverLayer.hoverTilePosition.y = tileY;
- this.mapView.updateScene = true;
- }
- });
-
- // Handle mousedown interaction
- this.stage.on("mousedown", (e: createjs.MouseEvent) => {
- this.stageDragBeginX = e.stageX;
- this.stageDragBeginY = e.stageY;
- });
-
- // Handle map dragging interaction
- // Drag begin and progress handlers
- this.mapView.mapContainer.on("pressmove", (e: createjs.MouseEvent) => {
- if (!this.gridDragging) {
- this.gridDragBeginX = e.stageX - this.mapView.mapContainer.x;
- this.gridDragBeginY = e.stageY - this.mapView.mapContainer.y;
- this.stageDragBeginX = e.stageX;
- this.stageDragBeginY = e.stageY;
- this.gridDragging = true;
- } else {
- this.mapView.mapContainer.x = e.stageX - this.gridDragBeginX;
- this.mapView.mapContainer.y = e.stageY - this.gridDragBeginY;
-
- this.checkAndResetCanvasMovement();
-
- this.mapView.updateScene = true;
- }
- });
-
- // Drag exit handlers
- this.mapView.mapContainer.on("pressup", (e: createjs.MouseEvent) => {
- if (this.gridDragging) {
- this.gridDragging = false;
- }
-
- if (Math.abs(e.stageX - this.stageDragBeginX) < this.MAX_DELTA &&
- Math.abs(e.stageY - this.stageDragBeginY) < this.MAX_DELTA) {
- this.handleCanvasMouseClick(e.stageX, e.stageY);
- }
- });
-
- // Disable an ongoing drag action if the mouse leaves the canvas
- this.mapView.stage.on("mouseleave", () => {
- if (this.gridDragging) {
- this.gridDragging = false;
- }
- });
-
- // Relay scroll events to the MapView zoom handler
- $("#main-canvas").on("mousewheel", (event: JQueryEventObject) => {
- const originalEvent = (<any>event.originalEvent);
- this.mapView.zoom([this.currentStageMouseX, this.currentStageMouseY], -0.7 * originalEvent.deltaY);
- this.scaleIndicatorController.update();
- });
- }
-
- /**
- * Connects clickable UI elements to their respective event listeners.
- */
- private setupEventListeners(): void {
- // Zooming elements
- $("#zoom-plus").on("click", () => {
- this.mapView.zoom([
- this.mapView.canvasWidth / 2,
- this.mapView.canvasHeight / 2
- ], 20);
- });
- $("#zoom-minus").on("click", () => {
- this.mapView.zoom([
- this.mapView.canvasWidth / 2,
- this.mapView.canvasHeight / 2
- ], -20);
- });
-
- $(".export-canvas").click(() => {
- this.exportCanvasToImage();
- });
-
- // Menu panels
- $(".menu-header-bar .menu-collapse").on("click", (event: JQueryEventObject) => {
- const container = $(event.target).closest(".menu-container");
- if (this.appMode === AppMode.CONSTRUCTION) {
- container.children(".menu-body.construction").first().slideToggle(300);
- } else if (this.appMode === AppMode.SIMULATION) {
- container.children(".menu-body.simulation").first().slideToggle(300);
- }
-
- });
-
- // Menu close button
- $(".menu-header-bar .menu-exit").on("click", (event: JQueryEventObject) => {
- const nearestMenuContainer = $(event.target).closest(".menu-container");
- if (nearestMenuContainer.is("#node-menu")) {
- this.interactionLevel = InteractionLevel.OBJECT;
- $(".node-element-overlay").addClass("hidden");
- }
- nearestMenuContainer.addClass("hidden");
- });
-
- // Handler for the construction mode switch
- $("#construction-mode-switch").on("click", () => {
- this.simulationController.exitMode();
- });
-
- // Handler for the simulation mode switch
- $("#simulation-mode-switch").on("click", () => {
- this.simulationController.enterMode();
- });
-
- // Handler for the version-save button
- $("#save-version-btn").on("click", (event: JQueryEventObject) => {
- const target = $(event.target);
-
- target.attr("data-saved", "false");
- const lastPath = this.mapView.simulation.paths[this.mapView.simulation.paths.length - 1];
- this.api.branchFromPath(
- this.mapView.simulation.id, lastPath.id, lastPath.sections[lastPath.sections.length - 1].startTick + 1
- ).then((data: IPath) => {
- this.mapView.simulation.paths.push(data);
- this.mapView.currentDatacenter = data.sections[data.sections.length - 1].datacenter;
- target.attr("data-saved", "true");
- });
- });
-
- $(document).on("keydown", (event: JQueryKeyEventObject) => {
- if ($(event.target).is('input')) {
- return;
- }
-
- if (event.which === 83) {
- this.simulationController.enterMode();
- } else if (event.which === 67) {
- this.simulationController.exitMode();
- } else if (event.which == 32) {
- if (this.appMode === AppMode.SIMULATION) {
- this.simulationController.timelineController.togglePlayback();
- }
- }
- });
- }
-
- /**
- * Handles a simple mouse click (without drag) on the canvas.
- *
- * @param stageX The x coordinate of the location in pixels on the stage
- * @param stageY The y coordinate of the location in pixels on the stage
- */
- private handleCanvasMouseClick(stageX: number, stageY: number): void {
- const gridPos = this.convertScreenCoordsToGridCoords([stageX, stageY]);
-
- if (this.interactionLevel === InteractionLevel.BUILDING) {
- if (this.interactionMode === InteractionMode.DEFAULT) {
- const roomIndex = Util.roomCollisionIndexOf(this.mapView.currentDatacenter.rooms, gridPos);
-
- if (roomIndex !== -1) {
- this.interactionLevel = InteractionLevel.ROOM;
- this.roomModeController.enterMode(this.mapView.currentDatacenter.rooms[roomIndex]);
- }
- } else if (this.interactionMode === InteractionMode.SELECT_ROOM) {
- if (this.mapView.roomLayer.checkHoverTileValidity(gridPos)) {
- this.buildingModeController.addSelectedTile(this.mapView.hoverLayer.hoverTilePosition);
- } else if (Util.tileListContainsPosition(this.mapView.roomLayer.selectedTiles, gridPos)) {
- this.buildingModeController.removeSelectedTile(this.mapView.hoverLayer.hoverTilePosition);
- }
- }
- } else if (this.interactionLevel === InteractionLevel.ROOM) {
- this.roomModeController.handleCanvasMouseClick(gridPos);
- } else if (this.interactionLevel === InteractionLevel.OBJECT) {
- if (gridPos.x !== this.mapView.grayLayer.currentObjectTile.position.x ||
- gridPos.y !== this.mapView.grayLayer.currentObjectTile.position.y) {
- this.objectModeController.goToRoomMode();
- }
- } else if (this.interactionLevel === InteractionLevel.NODE) {
- this.interactionLevel = InteractionLevel.OBJECT;
- this.nodeModeController.goToObjectMode();
- }
- }
-
- /**
- * Takes screen (stage) coordinates and returns the grid cell position they belong to.
- *
- * @param stagePosition The raw x and y coordinates of the wanted position
- * @returns {Array} The corresponding grid cell coordinates
- */
- private convertScreenCoordsToGridCoords(stagePosition: number[]): IGridPosition {
- const result = {x: 0, y: 0};
- result.x = Math.floor((stagePosition[0] - this.mapView.mapContainer.x) /
- (this.mapView.mapContainer.scaleX * CELL_SIZE));
- result.y = Math.floor((stagePosition[1] - this.mapView.mapContainer.y) /
- (this.mapView.mapContainer.scaleY * CELL_SIZE));
- return result;
- }
-
- /**
- * Adjusts the canvas size to fit the window perfectly.
- */
- private onWindowResize() {
- const parent = this.canvas.parent(".app-content");
- parent.height($(window).height() - 50);
- this.canvas.attr("width", parent.width());
- this.canvas.attr("height", parent.height());
- this.mapView.canvasWidth = parent.width();
- this.mapView.canvasHeight = parent.height();
-
- if (this.interactionLevel === InteractionLevel.BUILDING) {
- this.mapView.zoomOutOnDC();
- } else if (this.interactionLevel === InteractionLevel.ROOM) {
- this.mapView.zoomInOnRoom(this.roomModeController.currentRoom);
- } else {
- this.mapView.zoomInOnRoom(this.roomModeController.currentRoom, true);
- }
-
- this.mapView.updateScene = true;
- }
-
- private matchUserAuthLevel() {
- const authLevel = localStorage.getItem("simulationAuthLevel");
- if (authLevel === "VIEW") {
- $(".side-menu-container.right-middle-side, .side-menu-container.right-side").hide();
- }
- }
-
- private exportCanvasToImage() {
- const canvasData = (<HTMLCanvasElement>this.canvas.get(0)).toDataURL("image/png");
- const newWindow = window.open('about:blank', 'OpenDC Canvas Export');
- newWindow.document.write("<img src='" + canvasData + "' alt='Canvas Image Export'/>");
- newWindow.document.title = "OpenDC Canvas Export";
- }
-}
diff --git a/src/scripts/controllers/modes/building.ts b/src/scripts/controllers/modes/building.ts
deleted file mode 100644
index 217f5935..00000000
--- a/src/scripts/controllers/modes/building.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import {InteractionMode, MapController} from "../mapcontroller";
-import {MapView} from "../../views/mapview";
-import * as $ from "jquery";
-
-
-/**
- * Class responsible for handling building mode interactions.
- */
-export class BuildingModeController {
- public newRoomId: number;
-
- private mapController: MapController;
- private mapView: MapView;
-
-
- constructor(mapController: MapController) {
- this.mapController = mapController;
- this.mapView = this.mapController.mapView;
- }
-
- /**
- * Connects all DOM event listeners to their respective element targets.
- */
- public setupEventListeners() {
- const resetConstructionButtons = () => {
- this.mapController.interactionMode = InteractionMode.DEFAULT;
- this.mapView.hoverLayer.setHoverTileVisibility(false);
- $("#room-construction").text("Construct new room");
- $("#room-construction-cancel").slideToggle(300);
- };
-
- // Room construction button
- $("#room-construction").on("click", (event: JQueryEventObject) => {
- if (this.mapController.interactionMode === InteractionMode.DEFAULT) {
- this.mapController.interactionMode = InteractionMode.SELECT_ROOM;
- this.mapView.hoverLayer.setHoverTileVisibility(true);
- this.mapController.api.addRoomToDatacenter(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id).then((room: IRoom) => {
- this.newRoomId = room.id;
- });
- $(event.target).text("Finalize room");
- $("#room-construction-cancel").slideToggle(300);
- } else if (this.mapController.interactionMode === InteractionMode.SELECT_ROOM) {
- resetConstructionButtons();
- this.finalizeRoom();
- }
- });
-
- // Cancel button for room construction
- $("#room-construction-cancel").on("click", () => {
- resetConstructionButtons();
- this.cancelRoomConstruction();
- });
- }
-
- /**
- * Cancels room construction and deletes the temporary room created previously.
- */
- public cancelRoomConstruction() {
- this.mapController.api.deleteRoom(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.newRoomId).then(() => {
- this.mapView.roomLayer.cancelRoomConstruction();
- });
- }
-
- /**
- * Finalizes room construction by triggering a redraw of the room layer with the new room added.
- */
- public finalizeRoom() {
- this.mapController.api.getRoom(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.newRoomId).then((room: IRoom) => {
- this.mapView.roomLayer.finalizeRoom(room);
- });
- }
-
- /**
- * Adds a newly selected tile to the list of selected tiles.
- *
- * @param position The new tile position to be added
- */
- public addSelectedTile(position: IGridPosition): void {
- const tile = {
- id: -1,
- roomId: this.newRoomId,
- position: {x: position.x, y: position.y}
- };
- this.mapController.api.addTileToRoom(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.newRoomId, tile).then((tile: ITile) => {
- this.mapView.roomLayer.addSelectedTile(tile);
- });
- }
-
- /**
- * Removes a previously selected tile.
- *
- * @param position The position of the tile to be removed
- */
- public removeSelectedTile(position: IGridPosition): void {
- let objectIndex = -1;
-
- for (let i = 0; i < this.mapView.roomLayer.selectedTileObjects.length; i++) {
- const tile = this.mapView.roomLayer.selectedTileObjects[i];
- if (tile.position.x === position.x && tile.position.y === position.y) {
- objectIndex = i;
- }
- }
- this.mapController.api.deleteTile(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.newRoomId,
- this.mapView.roomLayer.selectedTileObjects[objectIndex].tileObject.id).then(() => {
- this.mapView.roomLayer.removeSelectedTile(position, objectIndex);
- });
- }
-}
diff --git a/src/scripts/controllers/modes/node.ts b/src/scripts/controllers/modes/node.ts
deleted file mode 100644
index cef61bba..00000000
--- a/src/scripts/controllers/modes/node.ts
+++ /dev/null
@@ -1,297 +0,0 @@
-import {MapController, AppMode, InteractionLevel} from "../mapcontroller";
-import {MapView} from "../../views/mapview";
-import * as $ from "jquery";
-
-
-/**
- * Class responsible for rendering node mode and handling UI interactions within it.
- */
-export class NodeModeController {
- public currentMachine: IMachine;
-
- private mapController: MapController;
- private mapView: MapView;
-
-
- constructor(mapController: MapController) {
- this.mapController = mapController;
- this.mapView = this.mapController.mapView;
-
- this.loadAddDropdowns();
- }
-
- /**
- * Moves the UI model into node mode.
- *
- * @param machine The machine that was selected in rack mode
- */
- public enterMode(machine: IMachine): void {
- this.currentMachine = machine;
- this.populateUnitLists();
- $("#node-menu").removeClass("hidden");
-
- if (this.mapController.appMode === AppMode.SIMULATION) {
- this.mapController.simulationController.transitionFromRackToNode();
- }
- }
-
- /**
- * Performs cleanup and closing actions before allowing transferal to rack mode.
- */
- public goToObjectMode(): void {
- $("#node-menu").addClass("hidden");
- $(".node-element-overlay").addClass("hidden");
- this.currentMachine = undefined;
- this.mapController.interactionLevel = InteractionLevel.OBJECT;
-
- if (this.mapController.appMode === AppMode.SIMULATION) {
- this.mapController.simulationController.transitionFromNodeToRack();
- }
- }
-
- /**
- * Connects all DOM event listeners to their respective element targets.
- */
- public setupEventListeners(): void {
- const nodeMenu = $("#node-menu");
-
- nodeMenu.find(".panel-group").on("click", ".remove-unit", (event: JQueryEventObject) => {
- MapController.showConfirmDeleteDialog("unit", () => {
- const index = $(event.target).closest(".panel").index();
-
- if (index === -1) {
- return;
- }
-
- const closestTabPane = $(event.target).closest(".panel-group");
-
- let objectList, idList;
- if (closestTabPane.is("#cpu-accordion")) {
- objectList = this.currentMachine.cpus;
- idList = this.currentMachine.cpuIds;
- } else if (closestTabPane.is("#gpu-accordion")) {
- objectList = this.currentMachine.gpus;
- idList = this.currentMachine.gpuIds;
- } else if (closestTabPane.is("#memory-accordion")) {
- objectList = this.currentMachine.memories;
- idList = this.currentMachine.memoryIds;
- } else if (closestTabPane.is("#storage-accordion")) {
- objectList = this.currentMachine.storages;
- idList = this.currentMachine.storageIds;
- }
-
- idList.splice(idList.indexOf(objectList[index]).id, 1);
- objectList.splice(index, 1);
-
- this.mapController.api.updateMachine(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id,
- this.mapController.objectModeController.currentObjectTile.id, this.currentMachine).then(
- () => {
- this.populateUnitLists();
- this.mapController.objectModeController.updateNodeComponentOverlays();
- });
- });
- });
-
- nodeMenu.find(".add-unit").on("click", (event: JQueryEventObject) => {
- const dropdown = $(event.target).closest(".input-group-btn").siblings("select").first();
-
- const closestTabPane = $(event.target).closest(".input-group").siblings(".panel-group").first();
- let objectList, idList, typePlural;
- if (closestTabPane.is("#cpu-accordion")) {
- objectList = this.currentMachine.cpus;
- idList = this.currentMachine.cpuIds;
- typePlural = "cpus";
- } else if (closestTabPane.is("#gpu-accordion")) {
- objectList = this.currentMachine.gpus;
- idList = this.currentMachine.gpuIds;
- typePlural = "gpus";
- } else if (closestTabPane.is("#memory-accordion")) {
- objectList = this.currentMachine.memories;
- idList = this.currentMachine.memoryIds;
- typePlural = "memories";
- } else if (closestTabPane.is("#storage-accordion")) {
- objectList = this.currentMachine.storages;
- idList = this.currentMachine.storageIds;
- typePlural = "storages";
- }
-
- if (idList.length + 1 > 4) {
- this.mapController.showInfoBalloon("Machine has only 4 slots", "warning");
- return;
- }
-
- const id = parseInt(dropdown.val());
- idList.push(id);
- this.mapController.api.getSpecificationOfType(typePlural, id).then((spec: INodeUnit) => {
- objectList.push(spec);
-
- this.mapController.api.updateMachine(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id,
- this.mapController.objectModeController.currentObjectTile.id, this.currentMachine).then(
- () => {
- this.populateUnitLists();
- this.mapController.objectModeController.updateNodeComponentOverlays();
- });
- });
- });
- }
-
- /**
- * Populates the "add" dropdowns with all available unit options.
- */
- private loadAddDropdowns(): void {
- const unitTypes = [
- "cpus", "gpus", "memories", "storages"
- ];
- const dropdowns = [
- $("#add-cpu-form").find("select"),
- $("#add-gpu-form").find("select"),
- $("#add-memory-form").find("select"),
- $("#add-storage-form").find("select"),
- ];
-
- unitTypes.forEach((type: string, index: number) => {
- this.mapController.api.getAllSpecificationsOfType(type).then((data: any) => {
- data.forEach((option: INodeUnit) => {
- dropdowns[index].append($("<option>").val(option.id).text(option.manufacturer + " " + option.family +
- " " + option.model + " (" + option.generation + ")"));
- });
- });
- });
- }
-
- /**
- * Generates and inserts dynamically HTML code concerning all units of a machine.
- */
- private populateUnitLists(): void {
- // Contains the skeleton of a unit element and inserts the given data into it
- const generatePanel = (type: string, index: number, list: any, specSection: string): string => {
- return '<div class="panel panel-default">' +
- ' <div class="panel-heading">' +
- ' <h4 class="panel-title">' +
- ' <a class="glyphicon glyphicon-remove remove-unit" href="javascript:void(0)"></a>' +
- ' <a class="accordion-toggle collapsed" data-toggle="collapse" data-parent="#' + type + '-accordion"' +
- ' href="#' + type + '-' + index + '">' +
- list[index].manufacturer + ' ' + list[index].family + ' ' + list[index].model +
- ' </a>' +
- ' </h4>' +
- ' </div>' +
- ' <div id="' + type + '-' + index + '" class="panel-collapse collapse">' +
- ' <table class="spec-table">' +
- ' <tbody>' +
- specSection +
- ' </tbody>' +
- ' </table>' +
- ' </div>' +
- '</div>';
- };
-
- // Generates the structure of the specification list of a processing unit
- const generateProcessingUnitHtml = (element: IProcessingUnit) => {
- return ' <tr>' +
- ' <td class="glyphicon glyphicon-tasks"></td>' +
- ' <td>Number of Cores</td>' +
- ' <td>' + element.numberOfCores + '</td>' +
- ' </tr>' +
- ' <tr>' +
- ' <td class="glyphicon glyphicon-dashboard"></td>' +
- ' <td>Clockspeed (MHz)</td>' +
- ' <td>' + element.clockRateMhz + '</td>' +
- ' </tr>' +
- ' <tr>' +
- ' <td class="glyphicon glyphicon-flash"></td>' +
- ' <td>Energy Consumption (W)</td>' +
- ' <td>' + element.energyConsumptionW + '</td>' +
- ' </tr>' +
- ' <tr>' +
- ' <td class="glyphicon glyphicon-alert"></td>' +
- ' <td>Failure Rate (%)</td>' +
- ' <td>' + element.failureModel.rate + '</td>' +
- ' </tr>';
- };
-
- // Generates the structure of the spec list of a storage unit
- const generateStorageUnitHtml = (element: IStorageUnit) => {
- return ' <tr>' +
- ' <td class="glyphicon glyphicon-floppy-disk"></td>' +
- ' <td>Size (Mb)</td>' +
- ' <td>' + element.sizeMb + '</td>' +
- ' </tr>' +
- ' <tr>' +
- ' <td class="glyphicon glyphicon-dashboard"></td>' +
- ' <td>Speed (Mb/s)</td>' +
- ' <td>' + element.speedMbPerS + '</td>' +
- ' </tr>' +
- ' <tr>' +
- ' <td class="glyphicon glyphicon-flash"></td>' +
- ' <td>Energy Consumption (W)</td>' +
- ' <td>' + element.energyConsumptionW + '</td>' +
- ' </tr>' +
- ' <tr>' +
- ' <td class="glyphicon glyphicon-alert"></td>' +
- ' <td>Failure Rate (%)</td>' +
- ' <td>' + element.failureModel.rate + '</td>' +
- ' </tr>';
- };
-
- // Inserts a "No units" message into the container of the given unit type
- const addNoUnitsMessage = (type: string) => {
- $("#" + type + "-accordion").append("<p>There are currently no units present here. " +
- "<em>Add some with the dropdown below!</em></p>");
- };
-
- let container = $("#cpu-accordion");
- container.children().remove(".panel");
- container.children().remove("p");
-
- if (this.currentMachine.cpus.length === 0) {
- addNoUnitsMessage("cpu");
- } else {
- this.currentMachine.cpus.forEach((element: ICPU, i: number) => {
- const specSection = generateProcessingUnitHtml(element);
- const content = generatePanel("cpu", i, this.currentMachine.cpus, specSection);
- container.append(content);
- });
- }
-
- container = $("#gpu-accordion");
- container.children().remove(".panel");
- container.children().remove("p");
- if (this.currentMachine.gpus.length === 0) {
- addNoUnitsMessage("gpu");
- } else {
- this.currentMachine.gpus.forEach((element: IGPU, i: number) => {
- const specSection = generateProcessingUnitHtml(element);
- const content = generatePanel("gpu", i, this.currentMachine.gpus, specSection);
- container.append(content);
- });
- }
-
- container = $("#memory-accordion");
- container.children().remove(".panel");
- container.children().remove("p");
- if (this.currentMachine.memories.length === 0) {
- addNoUnitsMessage("memory");
- } else {
- this.currentMachine.memories.forEach((element: IMemory, i: number) => {
- const specSection = generateStorageUnitHtml(element);
- const content = generatePanel("memory", i, this.currentMachine.memories, specSection);
- container.append(content);
- });
- }
-
- container = $("#storage-accordion");
- container.children().remove(".panel");
- container.children().remove("p");
- if (this.currentMachine.storages.length === 0) {
- addNoUnitsMessage("storage");
- } else {
- this.currentMachine.storages.forEach((element: IMemory, i: number) => {
- const specSection = generateStorageUnitHtml(element);
- const content = generatePanel("storage", i, this.currentMachine.storages, specSection);
- container.append(content);
- });
- }
- }
-}
diff --git a/src/scripts/controllers/modes/object.ts b/src/scripts/controllers/modes/object.ts
deleted file mode 100644
index bc358d71..00000000
--- a/src/scripts/controllers/modes/object.ts
+++ /dev/null
@@ -1,296 +0,0 @@
-import {AppMode, InteractionLevel, MapController} from "../mapcontroller";
-import {MapView} from "../../views/mapview";
-import * as $ from "jquery";
-
-
-/**
- * Class responsible for rendering object mode and handling its UI interactions.
- */
-export class ObjectModeController {
- public currentObject: IDCObject;
- public objectType: string;
- public currentRack: IRack;
- public currentPSU: IPSU;
- public currentCoolingItem: ICoolingItem;
- public currentObjectTile: ITile;
-
- private mapController: MapController;
- private mapView: MapView;
-
-
- constructor(mapController: MapController) {
- this.mapController = mapController;
- this.mapView = this.mapController.mapView;
- }
-
- /**
- * Performs the necessary setup actions and enters object mode.
- *
- * @param tile A reference to the tile containing the rack that was selected.
- */
- public enterMode(tile: ITile) {
- this.currentObjectTile = tile;
- this.mapView.grayLayer.currentObjectTile = tile;
- this.currentObject = tile.object;
- this.objectType = tile.objectType;
-
- // Show the corresponding sub-menu of object mode
- $(".object-sub-menu").hide();
-
- switch (this.objectType) {
- case "RACK":
- $("#rack-sub-menu").show();
- this.currentRack = <IRack>this.currentObject;
- $("#rack-name-input").val(this.currentRack.name);
- this.populateNodeList();
-
- break;
-
- case "PSU":
- $("#psu-sub-menu").show();
- this.currentPSU = <IPSU>this.currentObject;
-
- break;
-
- case "COOLING_ITEM":
- $("#cooling-item-sub-menu").show();
- this.currentCoolingItem = <ICoolingItem>this.currentObject;
-
- break;
- }
-
- this.mapView.grayLayer.drawRackLevel();
- MapController.hideAndShowMenus("#object-menu");
- this.scrollToBottom();
-
- if (this.mapController.appMode === AppMode.SIMULATION) {
- this.mapController.simulationController.transitionFromRoomToRack();
- }
- }
-
- /**
- * Leaves object mode and transfers to room mode.
- */
- public goToRoomMode() {
- this.mapController.interactionLevel = InteractionLevel.ROOM;
- this.mapView.grayLayer.hideRackLevel();
- MapController.hideAndShowMenus("#room-menu");
- this.mapController.roomModeController.enterMode(this.mapController.roomModeController.currentRoom);
-
- if (this.mapController.appMode === AppMode.SIMULATION) {
- this.mapController.simulationController.transitionFromRackToRoom();
- }
- }
-
- /**
- * Connects all DOM event listeners to their respective element targets.
- */
- public setupEventListeners() {
- // Handler for saving a new rack name
- $("#rack-name-save").on("click", () => {
- this.currentRack.name = $("#rack-name-input").text();
- this.mapController.api.updateRack(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id,
- this.mapController.objectModeController.currentObjectTile.id, this.currentRack).then(
- () => {
- this.mapController.showInfoBalloon("Rack name saved", "info");
- });
- });
-
- const nodeListContainer = $(".node-list-container");
-
- // Handler for the 'add' button of each machine slot of the rack
- nodeListContainer.on("click", ".add-node", (event: JQueryEventObject) => {
- // Convert the DOM element index to a JS array index
- const index = this.currentRack.machines.length - $(event.target).closest(".node-element").index() - 1;
-
- // Insert an empty machine at the selected position
- this.mapController.api.addMachineToRack(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id,
- this.mapController.objectModeController.currentObjectTile.id, {
- id: -1,
- rackId: this.currentRack.id,
- position: index,
- tags: [],
- cpuIds: [],
- gpuIds: [],
- memoryIds: [],
- storageIds: []
- }).then((data: IMachine) => {
- this.currentRack.machines[index] = data;
- this.populateNodeList();
- this.mapView.dcObjectLayer.draw();
- });
-
- event.stopPropagation();
- });
-
- // Handler for the 'remove' button of each machine slot of the rack
- nodeListContainer.on("click", ".remove-node", (event: JQueryEventObject) => {
- const target = $(event.target);
- MapController.showConfirmDeleteDialog("machine", () => {
- // Convert the DOM element index to a JS array index
- const index = this.currentRack.machines.length - target.closest(".node-element").index() - 1;
-
- this.mapController.api.deleteMachine(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id,
- this.mapController.objectModeController.currentObjectTile.id,
- index).then(() => {
- this.currentRack.machines[index] = null;
- this.populateNodeList();
- this.mapView.dcObjectLayer.draw();
- });
- });
- event.stopPropagation();
- });
-
- // Handler for every node element, triggering node mode
- nodeListContainer.on("click", ".node-element", (event: JQueryEventObject) => {
- const domIndex = $(event.target).closest(".node-element").index();
- const index = this.currentRack.machines.length - domIndex - 1;
- const machine = this.currentRack.machines[index];
-
- if (machine != null) {
- this.mapController.interactionLevel = InteractionLevel.NODE;
-
- // Gray out the other nodes
- $(event.target).closest(".node-list-container").children(".node-element").each((nodeIndex: number, element: Element) => {
- if (nodeIndex !== domIndex) {
- $(element).children(".node-element-overlay").removeClass("hidden");
- } else {
- $(element).children(".node-element-overlay").addClass("hidden");
- }
- });
-
- this.mapController.nodeModeController.enterMode(machine);
- }
- });
-
- // Handler for rack deletion button
- $("#rack-deletion").on("click", () => {
- MapController.showConfirmDeleteDialog("rack", () => {
- this.mapController.api.deleteRack(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id,
- this.mapController.objectModeController.currentObjectTile.id).then(() => {
- this.currentObjectTile.object = undefined;
- this.currentObjectTile.objectType = undefined;
- this.currentObjectTile.objectId = undefined;
- this.mapView.redrawMap();
- this.goToRoomMode();
- });
- });
- });
-
- // Handler for PSU deletion button
- $("#psu-deletion").on("click", () => {
- MapController.showConfirmDeleteDialog("PSU", () => {
- this.mapController.api.deletePSU(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id,
- this.mapController.objectModeController.currentObjectTile.id).then(() => {
- this.mapView.redrawMap();
- this.goToRoomMode();
- });
- this.currentObjectTile.object = undefined;
- this.currentObjectTile.objectType = undefined;
- this.currentObjectTile.objectId = undefined;
- });
- });
-
- // Handler for Cooling Item deletion button
- $("#cooling-item-deletion").on("click", () => {
- MapController.showConfirmDeleteDialog("cooling item", () => {
- this.mapController.api.deleteCoolingItem(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.mapController.roomModeController.currentRoom.id,
- this.mapController.objectModeController.currentObjectTile.id).then(() => {
- this.mapView.redrawMap();
- this.goToRoomMode();
- });
- this.currentObjectTile.object = undefined;
- this.currentObjectTile.objectType = undefined;
- this.currentObjectTile.objectId = undefined;
- });
- });
- }
-
- public updateNodeComponentOverlays(): void {
- if (this.currentRack === undefined || this.currentRack.machines === undefined) {
- return;
- }
-
- for (let i = 0; i < this.currentRack.machines.length; i++) {
- if (this.currentRack.machines[i] === null) {
- continue;
- }
-
- const container = this.mapController.appMode === AppMode.CONSTRUCTION ? ".construction" : ".simulation";
- const element = $(container + " .node-element").eq(this.currentRack.machines.length - i - 1);
- if (this.currentRack.machines[i].cpus.length !== 0) {
- element.find(".overlay-cpu").addClass("hidden");
- } else {
- element.find(".overlay-cpu").removeClass("hidden");
- }
- if (this.currentRack.machines[i].gpus.length !== 0) {
- element.find(".overlay-gpu").addClass("hidden");
- } else {
- element.find(".overlay-gpu").removeClass("hidden");
- }
- if (this.currentRack.machines[i].memories.length !== 0) {
- element.find(".overlay-memory").addClass("hidden");
- } else {
- element.find(".overlay-memory").removeClass("hidden");
- }
- if (this.currentRack.machines[i].storages.length !== 0) {
- element.find(".overlay-storage").addClass("hidden");
- } else {
- element.find(".overlay-storage").removeClass("hidden");
- }
- }
- }
-
- /**
- * Dynamically generates and inserts HTML code for every node in the current rack.
- */
- private populateNodeList(): void {
- const container = $(".node-list-container");
-
- // Remove any previously present node elements
- container.children().remove(".node-element");
-
- for (let i = 0; i < this.currentRack.machines.length; i++) {
- // Depending on whether the current machine slot is filled, allow removing or adding a new machine by adding
- // the appropriate button next to the machine slot
- const type = (this.currentRack.machines[i] == null ? "glyphicon-plus add-node" : "glyphicon-remove remove-node");
- let content =
- '<div class="node-element" data-id="' + (this.currentRack.machines[i] === null ?
- "" : this.currentRack.machines[i].id) + '">' +
- ' <div class="node-element-overlay hidden"></div>' +
- ' <a class="node-element-btn glyphicon ' + type + '" href="javascript:void(0)"></a>' +
- ' <div class="node-element-number">' + (i + 1) + '</div>';
- if (this.currentRack.machines[i] !== null) {
- content +=
- '<div class="node-element-content">' +
- ' <img src="img/app/node-cpu.png">' +
- ' <img src="img/app/node-gpu.png">' +
- ' <img src="img/app/node-memory.png">' +
- ' <img src="img/app/node-storage.png">' +
- ' <img src="img/app/node-network.png">' +
- ' <div class="icon-overlay overlay-cpu hidden"></div>' +
- ' <div class="icon-overlay overlay-gpu hidden"></div>' +
- ' <div class="icon-overlay overlay-memory hidden"></div>' +
- ' <div class="icon-overlay overlay-storage hidden"></div>' +
- ' <div class="icon-overlay overlay-network"></div>' +
- '</div>';
- }
- content += '</div>';
- // Insert the generated machine slot into the DOM
- container.prepend(content);
- }
-
- this.updateNodeComponentOverlays();
- }
-
- private scrollToBottom(): void {
- const scrollContainer = $('.node-list-container');
- scrollContainer.scrollTop(scrollContainer[0].scrollHeight);
- }
-}
diff --git a/src/scripts/controllers/modes/room.ts b/src/scripts/controllers/modes/room.ts
deleted file mode 100644
index dc7f4a41..00000000
--- a/src/scripts/controllers/modes/room.ts
+++ /dev/null
@@ -1,382 +0,0 @@
-import {Util} from "../../util";
-import {AppMode, InteractionLevel, MapController} from "../mapcontroller";
-import {MapView} from "../../views/mapview";
-import * as $ from "jquery";
-
-
-export enum RoomInteractionMode {
- DEFAULT,
- ADD_RACK,
- ADD_PSU,
- ADD_COOLING_ITEM
-}
-
-
-export class RoomModeController {
- public currentRoom: IRoom;
- public roomInteractionMode: RoomInteractionMode;
-
- private mapController: MapController;
- private mapView: MapView;
- private roomTypes: string[];
- private roomTypeMap: IRoomTypeMap;
- private availablePSUs: IPSU[];
- private availableCoolingItems: ICoolingItem[];
-
-
- constructor(mapController: MapController) {
- this.mapController = mapController;
- this.mapView = this.mapController.mapView;
-
- this.mapController.api.getAllRoomTypes().then((roomTypes: string[]) => {
- this.roomTypes = roomTypes;
- this.roomTypeMap = {};
-
- this.roomTypes.forEach((type: string) => {
- this.mapController.api.getAllowedObjectsByRoomType(type).then((objects: string[]) => {
- this.roomTypeMap[type] = objects;
- });
- });
-
- this.populateRoomTypeDropdown();
- });
-
- // this.mapController.api.getAllPSUSpecs().then((specs: IPSU[]) => {
- // this.availablePSUs = specs;
- // });
- //
- // this.mapController.api.getAllCoolingItemSpecs().then((specs: ICoolingItem[]) => {
- // this.availableCoolingItems = specs;
- // });
-
- this.roomInteractionMode = RoomInteractionMode.DEFAULT;
- }
-
- public enterMode(room: IRoom) {
- this.currentRoom = room;
- this.roomInteractionMode = RoomInteractionMode.DEFAULT;
-
- this.mapView.roomTextLayer.setVisibility(false);
-
- this.mapView.zoomInOnRoom(this.currentRoom);
- $("#room-name-input").val(this.currentRoom.name);
- MapController.hideAndShowMenus("#room-menu");
-
- // Pre-select the type of the current room in the dropdown
- const roomTypeDropdown = $("#roomtype-select");
- roomTypeDropdown.find('option').prop("selected", "false");
- const roomTypeIndex = this.roomTypes.indexOf(this.currentRoom.roomType);
- if (roomTypeIndex !== -1) {
- roomTypeDropdown.find('option[value="' + roomTypeIndex + '"]').prop("selected", "true");
- } else {
- roomTypeDropdown.val([]);
- }
-
- this.populateAllowedObjectTypes();
-
- this.mapView.roomLayer.setClickable(false);
-
- if (this.mapController.appMode === AppMode.SIMULATION) {
- this.mapController.simulationController.transitionFromBuildingToRoom();
- }
- }
-
- public goToBuildingMode() {
- this.mapController.interactionLevel = InteractionLevel.BUILDING;
-
- if (this.roomInteractionMode !== RoomInteractionMode.DEFAULT) {
- this.roomInteractionMode = RoomInteractionMode.DEFAULT;
- this.mapView.hoverLayer.setHoverItemVisibility(false);
- $("#add-rack-btn").attr("data-active", "false");
- $("#add-psu-btn").attr("data-active", "false");
- $("#add-cooling-item-btn").attr("data-active", "false");
- }
-
- this.mapView.roomTextLayer.setVisibility(true);
-
- this.mapView.zoomOutOnDC();
- MapController.hideAndShowMenus("#building-menu");
-
- this.mapView.roomLayer.setClickable(true);
-
- if (this.mapController.appMode === AppMode.SIMULATION) {
- this.mapController.simulationController.transitionFromRoomToBuilding();
- }
- }
-
- public setupEventListeners(): void {
- // Component buttons
- const addRackBtn = $("#add-rack-btn");
- const addPSUBtn = $("#add-psu-btn");
- const addCoolingItemBtn = $("#add-cooling-item-btn");
-
- const roomTypeDropdown = $("#roomtype-select");
-
- addRackBtn.on("click", () => {
- this.handleItemClick("RACK");
- });
- addPSUBtn.on("click", () => {
- this.handleItemClick("PSU");
- });
- addCoolingItemBtn.on("click", () => {
- this.handleItemClick("COOLING_ITEM");
- });
-
- // Handler for saving a new room name
- $("#room-name-save").on("click", () => {
- this.currentRoom.name = $("#room-name-input").text();
- this.mapController.api.updateRoom(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.currentRoom).then(() => {
- this.mapView.roomTextLayer.draw();
- this.mapController.showInfoBalloon("Room name saved", "info");
- });
- });
-
- // Handler for room deletion button
- $("#room-deletion").on("click", () => {
- MapController.showConfirmDeleteDialog("room", () => {
- this.mapController.api.deleteRoom(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.currentRoom.id).then(() => {
- const roomIndex = this.mapView.currentDatacenter.rooms.indexOf(this.currentRoom);
- this.mapView.currentDatacenter.rooms.splice(roomIndex, 1);
-
- this.mapView.redrawMap();
- this.goToBuildingMode();
- });
- });
- });
-
- // Handler for the room type dropdown component
- roomTypeDropdown.on("change", () => {
- const newRoomType = this.roomTypes[roomTypeDropdown.val()];
- if (!this.checkRoomTypeLegality(newRoomType)) {
- roomTypeDropdown.val(this.roomTypes.indexOf(this.currentRoom.roomType));
- this.mapController.showInfoBalloon("Room type couldn't be changed, illegal objects", "warning");
- return;
- }
-
- this.currentRoom.roomType = newRoomType;
- this.mapController.api.updateRoom(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.currentRoom).then(() => {
- this.populateAllowedObjectTypes();
- this.mapView.roomTextLayer.draw();
- this.mapController.showInfoBalloon("Room type changed", "info");
- });
- });
- }
-
- public handleCanvasMouseClick(gridPos: IGridPosition): void {
- if (this.roomInteractionMode === RoomInteractionMode.DEFAULT) {
- const tileIndex = Util.tileListPositionIndexOf(this.currentRoom.tiles, gridPos);
-
- if (tileIndex !== -1) {
- const tile = this.currentRoom.tiles[tileIndex];
-
- if (tile.object !== undefined) {
- this.mapController.interactionLevel = InteractionLevel.OBJECT;
- this.mapController.objectModeController.enterMode(tile);
- }
- } else {
- this.goToBuildingMode();
- }
- } else if (this.roomInteractionMode === RoomInteractionMode.ADD_RACK) {
- this.addObject(this.mapView.hoverLayer.hoverTilePosition, "RACK");
-
- } else if (this.roomInteractionMode === RoomInteractionMode.ADD_PSU) {
- this.addObject(this.mapView.hoverLayer.hoverTilePosition, "PSU");
-
- } else if (this.roomInteractionMode === RoomInteractionMode.ADD_COOLING_ITEM) {
- this.addObject(this.mapView.hoverLayer.hoverTilePosition, "COOLING_ITEM");
-
- }
- }
-
- private handleItemClick(type: string): void {
- const addRackBtn = $("#add-rack-btn");
- const addPSUBtn = $("#add-psu-btn");
- const addCoolingItemBtn = $("#add-cooling-item-btn");
- const allObjectContainers = $(".dc-component-container");
- const objectTypes = [
- {
- type: "RACK",
- mode: RoomInteractionMode.ADD_RACK,
- btn: addRackBtn
- },
- {
- type: "PSU",
- mode: RoomInteractionMode.ADD_PSU,
- btn: addPSUBtn
- },
- {
- type: "COOLING_ITEM",
- mode: RoomInteractionMode.ADD_COOLING_ITEM,
- btn: addCoolingItemBtn
- }
- ];
-
- allObjectContainers.attr("data-active", "false");
-
- if (this.roomInteractionMode === RoomInteractionMode.DEFAULT) {
- this.mapView.hoverLayer.setHoverItemVisibility(true, type);
-
- if (type === "RACK") {
- this.roomInteractionMode = RoomInteractionMode.ADD_RACK;
- addRackBtn.attr("data-active", "true");
- } else if (type === "PSU") {
- this.roomInteractionMode = RoomInteractionMode.ADD_PSU;
- addPSUBtn.attr("data-active", "true");
- } else if (type === "COOLING_ITEM") {
- this.roomInteractionMode = RoomInteractionMode.ADD_COOLING_ITEM;
- addCoolingItemBtn.attr("data-active", "true");
- }
-
- return;
- }
-
- let changed = false;
- objectTypes.forEach((objectType: any, index: number) => {
- if (this.roomInteractionMode === objectType.mode) {
- if (changed) {
- return;
- }
- if (type === objectType.type) {
- this.roomInteractionMode = RoomInteractionMode.DEFAULT;
- this.mapView.hoverLayer.setHoverItemVisibility(false);
- objectType.btn.attr("data-active", "false");
- } else {
- objectTypes.forEach((otherObjectType, otherIndex: number) => {
- if (index !== otherIndex) {
- if (type === otherObjectType.type) {
- this.mapView.hoverLayer.setHoverItemVisibility(true, type);
- otherObjectType.btn.attr("data-active", "true");
- this.roomInteractionMode = otherObjectType.mode;
- }
- }
- });
- }
- changed = true;
- }
- });
- }
-
- private addObject(position: IGridPosition, type: string): void {
- if (!this.mapView.roomLayer.checkHoverTileValidity(position)) {
- return;
- }
-
- const tileList = this.mapView.mapController.roomModeController.currentRoom.tiles;
-
- for (let i = 0; i < tileList.length; i++) {
- if (tileList[i].position.x === position.x && tileList[i].position.y === position.y) {
- if (type === "RACK") {
- this.mapController.api.addRack(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.currentRoom.id, tileList[i].id, {
- id: -1,
- objectType: "RACK",
- name: "",
- capacity: 42,
- powerCapacityW: 5000
- }).then((rack: IRack) => {
- tileList[i].object = rack;
- tileList[i].objectId = rack.id;
- tileList[i].objectType = type;
- this.mapView.dcObjectLayer.populateObjectList();
- this.mapView.dcObjectLayer.draw();
-
- this.mapView.updateScene = true;
- });
- } else if (type === "PSU") {
- this.mapController.api.addPSU(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.currentRoom.id, tileList[i].id, this.availablePSUs[0])
- .then((psu: IPSU) => {
- tileList[i].object = psu;
- tileList[i].objectId = psu.id;
- tileList[i].objectType = type;
- this.mapView.dcObjectLayer.populateObjectList();
- this.mapView.dcObjectLayer.draw();
-
- this.mapView.updateScene = true;
- });
- } else if (type === "COOLING_ITEM") {
- this.mapController.api.addCoolingItem(this.mapView.simulation.id,
- this.mapView.currentDatacenter.id, this.currentRoom.id, tileList[i].id,
- this.availableCoolingItems[0]).then((coolingItem: ICoolingItem) => {
- tileList[i].object = coolingItem;
- tileList[i].objectId = coolingItem.id;
- tileList[i].objectType = type;
- this.mapView.dcObjectLayer.populateObjectList();
- this.mapView.dcObjectLayer.draw();
-
- this.mapView.updateScene = true;
- });
- }
-
- break;
- }
- }
- }
-
- /**
- * Populates the room-type dropdown element with all available room types
- */
- private populateRoomTypeDropdown(): void {
- const dropdown = $("#roomtype-select");
-
- this.roomTypes.forEach((type: string, index: number) => {
- dropdown.append($('<option>').text(Util.toSentenceCase(type)).val(index));
- });
- }
-
- /**
- * Loads all object types that are allowed in the current room into the menu.
- */
- private populateAllowedObjectTypes(): void {
- const addObjectsLabel = $("#add-objects-label");
- const noObjectsInfo = $("#no-objects-info");
- const allowedObjectTypes = this.roomTypeMap[this.currentRoom.roomType];
-
- $(".dc-component-container").addClass("hidden");
-
- if (allowedObjectTypes === undefined || allowedObjectTypes === null || allowedObjectTypes.length === 0) {
- addObjectsLabel.addClass("hidden");
- noObjectsInfo.removeClass("hidden");
-
- return;
- }
-
- addObjectsLabel.removeClass("hidden");
- noObjectsInfo.addClass("hidden");
- allowedObjectTypes.forEach((type: string) => {
- switch (type) {
- case "RACK":
- $("#add-rack-btn").removeClass("hidden");
- break;
- case "PSU":
- $("#add-psu-btn").removeClass("hidden");
- break;
- case "COOLING_ITEM":
- $("#add-cooling-item-btn").removeClass("hidden");
- break;
- }
- });
- }
-
- /**
- * Checks whether a given room type can be assigned to the current room based on units already present.
- *
- * @param newRoomType The new room type to be validated
- * @returns {boolean} Whether it is allowed to change the room's type to the new type
- */
- private checkRoomTypeLegality(newRoomType: string): boolean {
- let legality = true;
-
- this.currentRoom.tiles.forEach((tile: ITile) => {
- if (tile.objectType !== undefined && tile.objectType !== null && tile.objectType !== "" &&
- this.roomTypeMap[newRoomType].indexOf(tile.objectType) === -1) {
- legality = false;
- }
- });
-
- return legality;
- }
-}
diff --git a/src/scripts/controllers/scaleindicator.ts b/src/scripts/controllers/scaleindicator.ts
deleted file mode 100644
index 789f2cc7..00000000
--- a/src/scripts/controllers/scaleindicator.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import {MapController, CELL_SIZE} from "./mapcontroller";
-import {MapView} from "../views/mapview";
-
-
-export class ScaleIndicatorController {
- private static MIN_WIDTH = 50;
- private static MAX_WIDTH = 100;
-
- private mapController: MapController;
- private mapView: MapView;
-
- private jqueryObject: JQuery;
- private currentDivisor: number;
-
-
- constructor(mapController: MapController) {
- this.mapController = mapController;
- this.mapView = mapController.mapView;
- }
-
- public init(jqueryObject: JQuery): void {
- this.jqueryObject = jqueryObject;
- this.currentDivisor = 1;
- }
-
- public update(): void {
- const currentZoom = this.mapView.mapContainer.scaleX;
- let newWidth;
- do {
- newWidth = (currentZoom * CELL_SIZE) / this.currentDivisor;
-
- if (newWidth < ScaleIndicatorController.MIN_WIDTH) {
- this.currentDivisor /= 2;
- } else if (newWidth > ScaleIndicatorController.MAX_WIDTH) {
- this.currentDivisor *= 2;
- } else {
- break;
- }
- } while (true);
-
-
- this.jqueryObject.text(MapView.CELL_SIZE_METERS / this.currentDivisor + "m");
- this.jqueryObject.width(newWidth);
- }
-}
diff --git a/src/scripts/controllers/simulation/chart.ts b/src/scripts/controllers/simulation/chart.ts
deleted file mode 100644
index 1b67934b..00000000
--- a/src/scripts/controllers/simulation/chart.ts
+++ /dev/null
@@ -1,241 +0,0 @@
-import * as c3 from "c3";
-import {InteractionLevel, MapController} from "../mapcontroller";
-import {ColorRepresentation, SimulationController} from "../simulationcontroller";
-import {Util} from "../../util";
-
-
-export interface IStateColumn {
- loadFractions: string[] | number[];
- inUseMemoryMb: string[] | number[];
- temperatureC: string[] | number[];
-}
-
-
-export class ChartController {
- public roomSeries: { [key: number]: IStateColumn };
- public rackSeries: { [key: number]: IStateColumn };
- public machineSeries: { [key: number]: IStateColumn };
- public chart: c3.ChartAPI;
- public machineChart: c3.ChartAPI;
-
- private simulationController: SimulationController;
- private mapController: MapController;
- private chartData: (string | number)[][];
- private xSeries: (string | number)[];
- private names: { [key: string]: string };
-
-
- constructor(simulationController: SimulationController) {
- this.simulationController = simulationController;
- this.mapController = simulationController.mapController;
- }
-
- public setup(): void {
- this.names = {};
-
- this.roomSeries = {};
- this.rackSeries = {};
- this.machineSeries = {};
-
- this.simulationController.sections.forEach((simulationSection: ISection) => {
- simulationSection.datacenter.rooms.forEach((room: IRoom) => {
- if (room.roomType === "SERVER" && this.roomSeries[room.id] === undefined) {
- this.names["ro" + room.id] = (room.name === "" || room.name === undefined) ?
- "Unnamed room" : room.name;
-
- this.roomSeries[room.id] = {
- loadFractions: ["ro" + room.id],
- inUseMemoryMb: ["ro" + room.id],
- temperatureC: ["ro" + room.id]
- };
- }
-
- room.tiles.forEach((tile: ITile) => {
- if (tile.object !== undefined && tile.objectType === "RACK" && this.rackSeries[tile.objectId] === undefined) {
- const objectName = (<IRack>tile.object).name;
- this.names["ra" + tile.objectId] = objectName === "" || objectName === undefined ?
- "Unnamed rack" : objectName;
-
- this.rackSeries[tile.objectId] = {
- loadFractions: ["ra" + tile.objectId],
- inUseMemoryMb: ["ra" + tile.objectId],
- temperatureC: ["ra" + tile.objectId]
- };
-
- (<IRack>tile.object).machines.forEach((machine: IMachine) => {
- if (machine === null || this.machineSeries[machine.id] !== undefined) {
- return;
- }
-
- this.names["ma" + machine.id] = "Machine at position " + (machine.position + 1).toString();
-
- this.machineSeries[machine.id] = {
- loadFractions: ["ma" + machine.id],
- inUseMemoryMb: ["ma" + machine.id],
- temperatureC: ["ma" + machine.id]
- };
- });
- }
- });
- });
- });
-
-
- this.xSeries = ["time"];
- this.chartData = [this.xSeries];
-
- this.chart = this.chartSetup("#statistics-chart");
- this.machineChart = this.chartSetup("#machine-statistics-chart");
- }
-
- public chartSetup(chartId: string): c3.ChartAPI {
- return c3.generate({
- bindto: chartId,
- data: {
- // xFormat: '%S',
- x: "time",
- columns: this.chartData,
- names: this.names
- },
- axis: {
- x: {
- type: "timeseries",
- tick: {
- format: function (time: Date) {
- let formattedTime = time.getSeconds() + "s";
-
- if (time.getMinutes() > 0) {
- formattedTime = time.getMinutes() + "m" + formattedTime;
- }
- if (time.getHours() > 0) {
- formattedTime = time.getHours() + "h" + formattedTime;
- }
-
- return formattedTime;
- },
- culling: {
- max: 5
- },
- count: 8
- },
- padding: {
- left: 0,
- right: 10
- }
- },
- y: {
- min: 0,
- max: 1,
- padding: {
- top: 0,
- bottom: 0
- },
- tick: {
- format: function (d) {
- return (Math.round(d * 100) / 100).toString();
- }
- }
- }
- }
- });
- }
-
- public update(): void {
- this.xSeries = (<(number|string)[]>["time"]).concat(<any[]> Util.timeRange(this.simulationController.currentTick));
-
- this.chartData = [this.xSeries];
-
- let prefix = "";
- let machineId = -1;
- if (this.mapController.interactionLevel === InteractionLevel.BUILDING) {
- for (let roomId in this.roomSeries) {
- if (this.roomSeries.hasOwnProperty(roomId)) {
- if (this.simulationController.colorRepresentation === ColorRepresentation.LOAD) {
- this.chartData.push(this.roomSeries[roomId].loadFractions);
- }
- }
- }
- prefix = "ro";
- } else if (this.mapController.interactionLevel === InteractionLevel.ROOM) {
- for (let rackId in this.rackSeries) {
- if (this.rackSeries.hasOwnProperty(rackId) &&
- this.simulationController.rackToRoomMap[rackId] ===
- this.mapController.roomModeController.currentRoom.id) {
- if (this.simulationController.colorRepresentation === ColorRepresentation.LOAD) {
- this.chartData.push(this.rackSeries[rackId].loadFractions);
- }
- }
- }
- prefix = "ra";
- } else if (this.mapController.interactionLevel === InteractionLevel.NODE) {
- if (this.simulationController.colorRepresentation === ColorRepresentation.LOAD) {
- this.chartData.push(
- this.machineSeries[this.mapController.nodeModeController.currentMachine.id].loadFractions
- );
- }
- prefix = "ma";
- machineId = this.mapController.nodeModeController.currentMachine.id;
- }
-
- const unloads: string[] = [];
- for (let id in this.names) {
- if (this.names.hasOwnProperty(id)) {
- if (machineId === -1) {
- if (id.substr(0, 2) !== prefix ||
- (this.mapController.interactionLevel === InteractionLevel.ROOM &&
- this.simulationController.rackToRoomMap[parseInt(id.substr(2))] !==
- this.mapController.roomModeController.currentRoom.id)) {
- unloads.push(id);
- }
- }
- else {
- if (id !== prefix + machineId) {
- unloads.push(id);
- }
- }
- }
- }
-
- let targetChart: c3.ChartAPI;
- if (this.mapController.interactionLevel === InteractionLevel.NODE) {
- targetChart = this.machineChart;
- } else {
- targetChart = this.chart;
- }
-
- targetChart.load({
- columns: this.chartData,
- unload: unloads
- });
-
- }
-
- public tickUpdated(tick: number): void {
- const roomStates: IRoomState[] = this.simulationController.stateCache.stateList[tick].roomStates;
- roomStates.forEach((roomState: IRoomState) => {
- ChartController.insertAtIndex(this.roomSeries[roomState.roomId].loadFractions, tick + 1, roomState.loadFraction);
- });
-
- const rackStates: IRackState[] = this.simulationController.stateCache.stateList[tick].rackStates;
- rackStates.forEach((rackState: IRackState) => {
- ChartController.insertAtIndex(this.rackSeries[rackState.rackId].loadFractions, tick + 1, rackState.loadFraction);
- });
-
- const machineStates: IMachineState[] = this.simulationController.stateCache.stateList[tick].machineStates;
- machineStates.forEach((machineState: IMachineState) => {
- ChartController.insertAtIndex(this.machineSeries[machineState.machineId].loadFractions, tick + 1, machineState.loadFraction);
- });
- }
-
- private static insertAtIndex(list: any[], index: number, data: any): void {
- if (index > list.length) {
- let i = list.length;
- while (i < index) {
- list[i] = null;
- i++;
- }
- }
-
- list[index] = data;
- }
-}
diff --git a/src/scripts/controllers/simulation/statecache.ts b/src/scripts/controllers/simulation/statecache.ts
deleted file mode 100644
index 0a7767fa..00000000
--- a/src/scripts/controllers/simulation/statecache.ts
+++ /dev/null
@@ -1,321 +0,0 @@
-import {SimulationController} from "../simulationcontroller";
-
-
-export class StateCache {
- public static CACHE_INTERVAL = 10000;
- private static PREFERRED_CACHE_ADVANCE = 5;
-
- public stateList: {[key: number]: ITickState};
- public lastCachedTick: number;
- public cacheBlock: boolean;
-
- private simulationController: SimulationController;
- private intervalId: any;
- private caching: boolean;
-
- // Item caches
- private machineCache: {[keys: number]: IMachine};
- private rackCache: {[keys: number]: IRack};
- private roomCache: {[keys: number]: IRoom};
- private taskCache: {[keys: number]: ITask};
-
-
- constructor(simulationController: SimulationController) {
- this.stateList = {};
- this.lastCachedTick = 0;
- this.cacheBlock = true;
- this.simulationController = simulationController;
- this.caching = false;
- }
-
- public startCaching(): void {
- this.machineCache = {};
- this.rackCache = {};
- this.roomCache = {};
- this.taskCache = {};
-
- this.simulationController.mapView.currentDatacenter.rooms.forEach((room: IRoom) => {
- this.addRoomToCache(room);
- });
- this.simulationController.currentExperiment.trace.tasks.forEach((task: ITask) => {
- this.taskCache[task.id] = task;
- });
-
- this.caching = true;
-
- this.cache();
- this.intervalId = setInterval(() => {
- this.cache();
- }, StateCache.CACHE_INTERVAL);
- }
-
- private addRoomToCache(room: IRoom) {
- this.roomCache[room.id] = room;
-
- room.tiles.forEach((tile: ITile) => {
- if (tile.objectType === "RACK") {
- this.rackCache[tile.objectId] = <IRack>tile.object;
-
- (<IRack> tile.object).machines.forEach((machine: IMachine) => {
- if (machine !== null) {
- this.machineCache[machine.id] = machine;
- }
- });
- }
- });
- }
-
- public stopCaching(): void {
- if (this.caching) {
- this.caching = false;
- clearInterval(this.intervalId);
- }
- }
-
- private cache(): void {
- const tick = this.lastCachedTick + 1;
-
- this.updateLastTick().then(() => {
- // Check if end of simulated region has been reached
- if (this.lastCachedTick > this.simulationController.lastSimulatedTick) {
- return;
- }
-
- this.fetchAllAvailableStates().then((data) => {
- this.stateList = data;
-
- // Determine last cached tick
- const ticks = Object.keys(this.stateList).sort((a, b) => {
- return parseInt(a) - parseInt(b);
- });
- if (ticks.length > 0) {
- this.lastCachedTick = parseInt(ticks[ticks.length - 1]);
- }
-
- for (let i = 1; i <= this.lastCachedTick; i++) {
- this.updateTasksForNewTick(i);
-
- // Update chart cache
- this.simulationController.chartController.tickUpdated(i);
- }
-
- if (!this.cacheBlock && this.lastCachedTick - this.simulationController.currentTick <= 0) {
- this.cacheBlock = true;
- return;
- }
-
- if (this.cacheBlock) {
- if (this.lastCachedTick - this.simulationController.currentTick >= StateCache.PREFERRED_CACHE_ADVANCE) {
- this.cacheBlock = false;
- }
- }
- });
- });
- }
-
- private updateTasksForNewTick(tick: number): void {
- const taskIDsInTick = [];
-
- this.stateList[tick].taskStates.forEach((taskState: ITaskState) => {
- taskIDsInTick.push(taskState.taskId);
- if (this.stateList[tick - 1] !== undefined) {
- let previousFlops = 0;
- const previousStates = this.stateList[tick - 1].taskStates;
-
- for (let i = 0; i < previousStates.length; i++) {
- if (previousStates[i].taskId === taskState.taskId) {
- previousFlops = previousStates[i].flopsLeft;
- break;
- }
- }
-
- if (previousFlops > 0 && taskState.flopsLeft === 0) {
- taskState.task.finishedTick = tick;
- }
- }
- });
-
- // Generate pseudo-task-states for tasks that haven't started yet or have already finished
- const traceTasks = this.simulationController.currentExperiment.trace.tasks;
- if (taskIDsInTick.length !== traceTasks.length) {
- traceTasks
- .filter((task: ITask) => {
- return taskIDsInTick.indexOf(task.id) === -1;
- })
- .forEach((task: ITask) => {
- const flopStateCount = task.startTick >= tick ? task.totalFlopCount : 0;
-
- this.stateList[tick].taskStates.push({
- id: -1,
- taskId: task.id,
- task: task,
- experimentId: this.simulationController.currentExperiment.id,
- tick,
- flopsLeft: flopStateCount
- });
- });
- }
-
- this.stateList[tick].taskStates.sort((a: ITaskState, b: ITaskState) => {
- return a.task.startTick - b.task.startTick;
- });
- }
-
- private updateLastTick(): Promise<void> {
- return this.simulationController.mapController.api.getLastSimulatedTickByExperiment(
- this.simulationController.simulation.id, this.simulationController.currentExperiment.id).then((data) => {
- this.simulationController.lastSimulatedTick = data;
- });
- }
-
- private fetchAllAvailableStates(): Promise<{[key: number]: ITickState}> {
- let machineStates, rackStates, roomStates, taskStates;
- const promises = [];
-
- promises.push(
- this.simulationController.mapController.api.getMachineStates(
- this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id,
- this.machineCache
- ).then((states: IMachineState[]) => {
- machineStates = states;
- })
- );
-
- promises.push(
- this.simulationController.mapController.api.getRackStates(
- this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id,
- this.rackCache
- ).then((states: IRackState[]) => {
- rackStates = states;
- })
- );
-
- promises.push(
- this.simulationController.mapController.api.getRoomStates(
- this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id,
- this.roomCache
- ).then((states: IRoomState[]) => {
- roomStates = states;
- })
- );
-
- promises.push(
- this.simulationController.mapController.api.getTaskStates(
- this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id,
- this.taskCache
- ).then((states: ITaskState[]) => {
- taskStates = states;
- })
- );
-
- return Promise.all(promises).then(() => {
- const tickStates: {[key: number]: ITickState} = {};
-
- machineStates.forEach((machineState: IMachineState) => {
- if (tickStates[machineState.tick] === undefined) {
- tickStates[machineState.tick] = {
- tick: machineState.tick,
- machineStates: [machineState],
- rackStates: [],
- roomStates: [],
- taskStates: []
- };
- } else {
- tickStates[machineState.tick].machineStates.push(machineState);
- }
- });
- rackStates.forEach((rackState: IRackState) => {
- if (tickStates[rackState.tick] === undefined) {
- tickStates[rackState.tick] = {
- tick: rackState.tick,
- machineStates: [],
- rackStates: [rackState],
- roomStates: [],
- taskStates: []
- };
- } else {
- tickStates[rackState.tick].rackStates.push(rackState);
- }
- });
- roomStates.forEach((roomState: IRoomState) => {
- if (tickStates[roomState.tick] === undefined) {
- tickStates[roomState.tick] = {
- tick: roomState.tick,
- machineStates: [],
- rackStates: [],
- roomStates: [roomState],
- taskStates: []
- };
- } else {
- tickStates[roomState.tick].roomStates.push(roomState);
- }
- });
- taskStates.forEach((taskState: ITaskState) => {
- if (tickStates[taskState.tick] === undefined) {
- tickStates[taskState.tick] = {
- tick: taskState.tick,
- machineStates: [],
- rackStates: [],
- roomStates: [],
- taskStates: [taskState]
- };
- } else {
- tickStates[taskState.tick].taskStates.push(taskState);
- }
- });
-
- return tickStates;
- });
- }
-
- private fetchAllStatesOfTick(tick: number): Promise<ITickState> {
- const tickState: ITickState = {
- tick,
- machineStates: [],
- rackStates: [],
- roomStates: [],
- taskStates: []
- };
- const promises = [];
-
- promises.push(
- this.simulationController.mapController.api.getMachineStates(
- this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id,
- this.machineCache, tick
- ).then((states: IMachineState[]) => {
- tickState.machineStates = states;
- })
- );
-
- promises.push(
- this.simulationController.mapController.api.getRackStates(
- this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id,
- this.rackCache, tick
- ).then((states: IRackState[]) => {
- tickState.rackStates = states;
- })
- );
-
- promises.push(
- this.simulationController.mapController.api.getRoomStates(
- this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id,
- this.roomCache, tick
- ).then((states: IRoomState[]) => {
- tickState.roomStates = states;
- })
- );
-
- promises.push(
- this.simulationController.mapController.api.getTaskStates(
- this.simulationController.mapView.simulation.id, this.simulationController.currentExperiment.id,
- this.taskCache, tick
- ).then((states: ITaskState[]) => {
- tickState.taskStates = states;
- })
- );
-
- return Promise.all(promises).then(() => {
- return tickState;
- });
- }
-}
diff --git a/src/scripts/controllers/simulation/taskview.ts b/src/scripts/controllers/simulation/taskview.ts
deleted file mode 100644
index d989e103..00000000
--- a/src/scripts/controllers/simulation/taskview.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import * as $ from "jquery";
-import {SimulationController} from "../simulationcontroller";
-import {Util} from "../../util";
-
-
-export class TaskViewController {
- private simulationController: SimulationController;
-
-
- constructor(simulationController: SimulationController) {
- this.simulationController = simulationController;
- }
-
- /**
- * Populates and displays the list of tasks with their current state.
- */
- public update() {
- const container = $(".task-list");
- container.children().remove(".task-element");
-
- this.simulationController.stateCache.stateList[this.simulationController.currentTick].taskStates
- .forEach((taskState: ITaskState) => {
- const html = this.generateTaskElementHTML(taskState);
- container.append(html);
- });
- }
-
- private generateTaskElementHTML(taskState: ITaskState) {
- let iconType, timeInfo;
-
- if (taskState.task.startTick > this.simulationController.currentTick) {
- iconType = "glyphicon-time";
- timeInfo = "Not started yet";
- } else if (taskState.task.startTick <= this.simulationController.currentTick && taskState.flopsLeft > 0) {
- iconType = "glyphicon-refresh";
- timeInfo = "Started at " + Util.convertSecondsToFormattedTime(taskState.task.startTick);
- } else if (taskState.flopsLeft === 0) {
- iconType = "glyphicon-ok";
- timeInfo = "Started at " + Util.convertSecondsToFormattedTime(taskState.task.startTick);
- }
-
- // Calculate progression ratio
- const progress = 1 - (taskState.flopsLeft / taskState.task.totalFlopCount);
-
- // Generate completion text
- const flopsCompleted = taskState.task.totalFlopCount - taskState.flopsLeft;
- const completionInfo = "Completed: " + flopsCompleted + " / " + taskState.task.totalFlopCount + " FLOPS";
-
- return '<div class="task-element">' +
- ' <div class="task-icon glyphicon ' + iconType + '"></div>' +
- ' <div class="task-info">' +
- ' <div class="task-time">' + timeInfo +
- ' </div>' +
- ' <div class="progress">' +
- ' <div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="' +
- progress * 100 + '%"' +
- ' aria-valuemin="0" aria-valuemax="100" style="width: ' + progress * 100 + '%">' +
- ' </div>' +
- ' </div>' +
- ' <div class="task-flops">' + completionInfo + '</div>' +
- ' </div>' +
- '</div>';
- }
-}
diff --git a/src/scripts/controllers/simulation/timeline.ts b/src/scripts/controllers/simulation/timeline.ts
deleted file mode 100644
index ec3d8cb4..00000000
--- a/src/scripts/controllers/simulation/timeline.ts
+++ /dev/null
@@ -1,161 +0,0 @@
-import {SimulationController} from "../simulationcontroller";
-import {Util} from "../../util";
-import * as $ from "jquery";
-
-
-export class TimelineController {
- private simulationController: SimulationController;
- private startLabel: JQuery;
- private endLabel: JQuery;
- private playButton: JQuery;
- private loadingIcon: JQuery;
- private cacheSection: JQuery;
- private timeMarker: JQuery;
- private timeline: JQuery;
- private timeUnitFraction: number;
- private timeMarkerWidth: number;
- private timelineWidth: number;
-
-
- constructor(simulationController: SimulationController) {
- this.simulationController = simulationController;
- this.startLabel = $(".timeline-container .labels .start-time-label");
- this.endLabel = $(".timeline-container .labels .end-time-label");
- this.playButton = $(".timeline-container .play-btn");
- this.loadingIcon = this.playButton.find("img");
- this.cacheSection = $(".timeline-container .timeline .cache-section");
- this.timeMarker = $(".timeline-container .timeline .time-marker");
- this.timeline = $(".timeline-container .timeline");
- this.timeMarkerWidth = this.timeMarker.width();
- this.timelineWidth = this.timeline.width();
- }
-
- public togglePlayback(): void {
- if (this.simulationController.stateCache.cacheBlock) {
- this.simulationController.playing = false;
- return;
- }
- this.simulationController.playing = !this.simulationController.playing;
- this.setButtonIcon();
- }
-
- public setupListeners(): void {
- this.playButton.on("click", () => {
- this.togglePlayback();
- });
-
- $(".timeline-container .timeline").on("click", (event: JQueryEventObject) => {
- const parentOffset = $(event.target).closest(".timeline").offset();
- const clickX = event.pageX - parentOffset.left;
-
- let newTick = Math.round(clickX / (this.timelineWidth * this.timeUnitFraction));
-
- if (newTick > this.simulationController.stateCache.lastCachedTick) {
- newTick = this.simulationController.stateCache.lastCachedTick;
- }
- this.simulationController.currentTick = newTick;
- this.simulationController.checkCurrentSimulationSection();
- this.simulationController.update();
- });
- }
-
- public setButtonIcon(): void {
- if (this.simulationController.playing && !this.playButton.hasClass("glyphicon-pause")) {
- this.playButton.removeClass("glyphicon-play").addClass("glyphicon-pause");
- } else if (!this.simulationController.playing && !this.playButton.hasClass("glyphicon-play")) {
- this.playButton.removeClass("glyphicon-pause").addClass("glyphicon-play");
- }
- }
-
- public update(): void {
- this.timeUnitFraction = 1 / (this.simulationController.lastSimulatedTick + 1);
- this.timelineWidth = $(".timeline-container .timeline").width();
-
- this.updateTimeLabels();
-
- this.cacheSection.css("width", this.calculateTickPosition(this.simulationController.stateCache.lastCachedTick));
- this.timeMarker.css("left", this.calculateTickPosition(this.simulationController.currentTick));
-
- this.updateTaskIndicators();
- this.updateSectionMarkers();
-
- if (this.simulationController.stateCache.cacheBlock) {
- this.playButton.removeClass("glyphicon-pause").removeClass("glyphicon-play");
- this.loadingIcon.show();
- } else {
- this.loadingIcon.hide();
- this.setButtonIcon();
- }
- }
-
- private updateTimeLabels(): void {
- this.startLabel.text(Util.convertSecondsToFormattedTime(this.simulationController.currentTick));
- this.endLabel.text(Util.convertSecondsToFormattedTime(this.simulationController.lastSimulatedTick));
- }
-
- private updateSectionMarkers(): void {
- $(".section-marker").remove();
-
- this.simulationController.sections.forEach((simulationSection: ISection) => {
- if (simulationSection.startTick === 0) {
- return;
- }
-
- this.timeline.append(
- $('<div class="section-marker">')
- .css("left", this.calculateTickPosition(simulationSection.startTick))
- );
- });
- }
-
- private updateTaskIndicators(): void {
- $(".task-indicator").remove();
-
- const tickStateTypes = {
- "queueEntryTick": "task-queued",
- "startTick": "task-started",
- "finishedTick": "task-finished"
- };
-
- if (this.simulationController.stateCache.lastCachedTick === -1) {
- return;
- }
-
- const indicatorCountList = new Array(this.simulationController.stateCache.lastCachedTick);
- let indicator;
- this.simulationController.currentExperiment.trace.tasks.forEach((task: ITask) => {
- for (let tickStateType in tickStateTypes) {
- if (!tickStateTypes.hasOwnProperty(tickStateType)) {
- continue;
- }
-
- if (task[tickStateType] !== undefined &&
- task[tickStateType] <= this.simulationController.stateCache.lastCachedTick) {
-
- let bottomOffset;
- if (indicatorCountList[task[tickStateType]] === undefined) {
- indicatorCountList[task[tickStateType]] = 1;
- bottomOffset = 0;
- } else {
- bottomOffset = indicatorCountList[task[tickStateType]] * 10;
- indicatorCountList[task[tickStateType]]++;
- }
- indicator = $('<div class="task-indicator ' + tickStateTypes[tickStateType] + '">')
- .css("left", this.calculateTickPosition(task[tickStateType]))
- .css("bottom", bottomOffset);
- this.timeline.append(indicator);
- }
- }
- });
- }
-
- private calculateTickPosition(tick: number): string {
- let correction = 0;
- if (this.timeUnitFraction * this.timelineWidth > this.timeMarkerWidth) {
- correction = (this.timeUnitFraction * this.timelineWidth - this.timeMarkerWidth) *
- ((tick - 1) / this.simulationController.lastSimulatedTick);
- }
-
- return (100 * (this.timeUnitFraction * (tick - 1) + correction / this.timelineWidth)) + "%";
- }
-}
diff --git a/src/scripts/controllers/simulationcontroller.ts b/src/scripts/controllers/simulationcontroller.ts
deleted file mode 100644
index 1185087d..00000000
--- a/src/scripts/controllers/simulationcontroller.ts
+++ /dev/null
@@ -1,586 +0,0 @@
-///<reference path="../../../typings/index.d.ts" />
-///<reference path="mapcontroller.ts" />
-import * as $ from "jquery";
-import {MapView} from "../views/mapview";
-import {AppMode, InteractionLevel, MapController} from "./mapcontroller";
-import {Util} from "../util";
-import {StateCache} from "./simulation/statecache";
-import {ChartController} from "./simulation/chart";
-import {TaskViewController} from "./simulation/taskview";
-import {TimelineController} from "./simulation/timeline";
-
-
-export enum ColorRepresentation {
- LOAD,
- TEMPERATURE,
- MEMORY
-}
-
-
-export class SimulationController {
- public mapView: MapView;
- public mapController: MapController;
-
- public playing: boolean;
- public currentTick: number;
- public stateCache: StateCache;
- public lastSimulatedTick: number;
- public simulation: ISimulation;
- public experiments: IExperiment[];
- public currentExperiment: IExperiment;
- public currentPath: IPath;
- public sections: ISection[];
- public currentSection: ISection;
- public experimentSelectionMode: boolean;
- public traces: ITrace[];
- public schedulers: IScheduler[];
- public sectionIndex: number;
- public chartController: ChartController;
- public timelineController: TimelineController;
-
- public colorRepresentation: ColorRepresentation;
- public rackToRoomMap: {[key: number]: number;};
-
- private taskViewController: TaskViewController;
- private tickerId: any;
-
-
- public static showOrHideSimComponents(visibility: boolean): void {
- if (visibility) {
- $("#statistics-menu").removeClass("hidden");
- $("#experiment-menu").removeClass("hidden");
- $("#tasks-menu").removeClass("hidden");
- $(".timeline-container").removeClass("hidden");
- } else {
- $("#statistics-menu").addClass("hidden");
- $("#experiment-menu").addClass("hidden");
- $("#tasks-menu").addClass("hidden");
- $(".timeline-container").addClass("hidden");
- }
- }
-
- constructor(mapController: MapController) {
- this.mapController = mapController;
- this.mapView = this.mapController.mapView;
- this.simulation = this.mapController.mapView.simulation;
- this.experiments = this.simulation.experiments;
- this.taskViewController = new TaskViewController(this);
- this.timelineController = new TimelineController(this);
- this.chartController = new ChartController(this);
-
- this.timelineController.setupListeners();
- this.experimentSelectionMode = true;
- this.sectionIndex = 0;
-
- this.currentTick = 1;
- this.playing = false;
- this.stateCache = new StateCache(this);
- this.colorRepresentation = ColorRepresentation.LOAD;
-
- this.traces = [];
- this.schedulers = [];
-
- this.mapController.api.getAllTraces().then((data) => {
- this.traces = data;
- });
-
- this.mapController.api.getAllSchedulers().then((data) => {
- this.schedulers = data;
- });
- }
-
- public enterMode() {
- this.experimentSelectionMode = true;
-
- if (this.mapController.interactionLevel === InteractionLevel.BUILDING) {
- this.mapView.roomLayer.coloringMode = true;
- this.mapView.dcObjectLayer.coloringMode = false;
- } else if (this.mapController.interactionLevel === InteractionLevel.ROOM ||
- this.mapController.interactionLevel === InteractionLevel.OBJECT) {
- this.mapView.roomLayer.coloringMode = false;
- this.mapView.dcObjectLayer.coloringMode = true;
- } else if (this.mapController.interactionLevel === InteractionLevel.NODE) {
- this.mapController.nodeModeController.goToObjectMode();
- }
-
- this.mapController.appMode = AppMode.SIMULATION;
- this.mapView.dcObjectLayer.detailedMode = false;
- this.mapView.gridLayer.setVisibility(false);
- this.mapView.updateScene = true;
-
- this.mapController.setAllMenuModes();
- SimulationController.showOrHideSimComponents(true);
- $(".mode-switch").attr("data-selected", "simulation");
- $("#save-version-btn").hide();
- $(".color-indicator").removeClass("hidden");
-
- $("#change-experiment-btn").click(() => {
- this.playing = false;
- this.stateCache.stopCaching();
- this.timelineController.update();
- this.showExperimentsDialog();
- });
-
- this.setupColorMenu();
- this.showExperimentsDialog();
- }
-
- private launchSimulation(): void {
- this.onSimulationSectionChange();
-
- this.chartController.setup();
-
- this.stateCache.startCaching();
-
- this.tickerId = setInterval(() => {
- this.simulationTick();
- }, 1000);
- }
-
- private onSimulationSectionChange(): void {
- this.currentSection = this.currentPath.sections[this.sectionIndex];
- this.mapView.currentDatacenter = this.currentSection.datacenter;
-
- // Generate a map of all rack IDs in relation to their room IDs for use in room stats
- this.rackToRoomMap = {};
- this.currentSection.datacenter.rooms.forEach((room: IRoom) => {
- room.tiles.forEach((tile: ITile) => {
- if (tile.object !== undefined && tile.objectType === "RACK") {
- this.rackToRoomMap[tile.objectId] = room.id;
- }
- });
- });
-
- if (this.mapController.interactionLevel === InteractionLevel.NODE) {
- this.mapController.nodeModeController.goToObjectMode();
- }
- if (this.mapController.interactionLevel === InteractionLevel.OBJECT) {
- this.mapController.objectModeController.goToRoomMode();
- }
- if (this.mapController.interactionLevel === InteractionLevel.ROOM) {
- this.mapController.roomModeController.goToBuildingMode();
- }
-
- this.mapView.redrawMap();
-
- this.mapView.zoomOutOnDC();
- }
-
- public exitMode() {
- this.closeExperimentsDialog();
-
- this.mapController.appMode = AppMode.CONSTRUCTION;
- this.mapView.dcObjectLayer.detailedMode = true;
- this.mapView.gridLayer.setVisibility(true);
- this.mapView.redrawMap();
-
- this.stateCache.stopCaching();
- this.playing = false;
-
- this.mapController.setAllMenuModes();
- SimulationController.showOrHideSimComponents(false);
-
- this.setColors();
- $(".color-indicator").addClass("hidden")["popover"]("hide").off();
- $(".mode-switch").attr("data-selected", "construction");
- $("#save-version-btn").show();
-
- clearInterval(this.tickerId);
- }
-
- public update() {
- if (this.stateCache.cacheBlock) {
- return;
- }
-
- this.setColors();
- this.updateBuildingStats();
- this.updateRoomStats();
- this.chartController.update();
- this.taskViewController.update();
- }
-
- public simulationTick(): void {
- this.timelineController.update();
-
- if (this.currentTick > this.lastSimulatedTick) {
- this.currentTick = this.lastSimulatedTick;
- this.playing = false;
- this.timelineController.setButtonIcon();
- }
-
- if (this.playing) {
- this.checkCurrentSimulationSection();
- this.update();
-
- if (!this.stateCache.cacheBlock) {
- this.currentTick++;
- }
- }
- }
-
- public checkCurrentSimulationSection(): void {
- for (let i = this.sections.length - 1; i >= 0; i--) {
- if (this.currentTick >= this.sections[i].startTick) {
- if (this.sectionIndex !== i) {
- this.sectionIndex = i;
- this.onSimulationSectionChange();
- }
- break;
- }
- }
- }
-
- public transitionFromBuildingToRoom(): void {
- this.mapView.roomLayer.coloringMode = false;
- this.mapView.dcObjectLayer.coloringMode = true;
-
- this.setColors();
- this.updateRoomStats();
- this.chartController.update();
- }
-
- public transitionFromRoomToBuilding(): void {
- this.mapView.roomLayer.coloringMode = true;
- this.mapView.dcObjectLayer.coloringMode = false;
-
- this.setColors();
- this.updateBuildingStats();
- this.chartController.update();
- }
-
- public transitionFromRoomToRack(): void {
- this.setColors();
- $("#statistics-menu").addClass("hidden");
- this.chartController.update();
- }
-
- public transitionFromRackToRoom(): void {
- this.setColors();
- $("#statistics-menu").removeClass("hidden");
- }
-
- public transitionFromRackToNode(): void {
- this.chartController.update();
- }
-
- public transitionFromNodeToRack(): void {
- }
-
- private showExperimentsDialog(): void {
- $(".experiment-name-alert").hide();
-
- this.populateExperimentsList();
- this.populateDropdowns();
-
- $(".experiment-row").click((event: JQueryEventObject) => {
- if ($(event.target).hasClass("remove-experiment")) {
- return;
- }
-
- const row = $(event.target).closest(".experiment-row");
- this.prepareAndLaunchExperiment(this.experiments[row.index()]);
- });
-
- $(".experiment-list .list-body").on("click", ".remove-experiment", (event: JQueryEventObject) => {
- event.stopPropagation();
- const affectedRow = $(event.target).closest(".experiment-row");
- const index = affectedRow.index();
- const affectedExperiment = this.experiments[index];
-
- MapController.showConfirmDeleteDialog("experiment", () => {
- this.mapController.api.deleteExperiment(affectedExperiment.simulationId, affectedExperiment.id)
- .then(() => {
- this.experiments.splice(index, 1);
- this.populateExperimentsList();
- });
- });
- });
-
- let newExperimentBtn = $("#new-experiment-btn");
- // Remove previously added event handlers
- newExperimentBtn.off();
-
- newExperimentBtn.click(() => {
- const nameInput = $("#new-experiment-name-input");
- if (nameInput.val() === "") {
- $(".experiment-name-alert").show();
- return;
- } else {
- $(".experiment-name-alert").hide();
- }
-
- const newExperiment: IExperiment = {
- id: -1,
- name: nameInput.text(),
- pathId: parseInt($("#new-experiment-path-select").val()),
- schedulerName: $("#new-experiment-scheduler-select").val(),
- traceId: parseInt($("#new-experiment-trace-select").val()),
- simulationId: this.simulation.id
- };
-
- this.mapController.api.addExperimentToSimulation(this.simulation.id, newExperiment)
- .then((data: IExperiment) => {
- this.simulation.experiments.push(data);
- this.prepareAndLaunchExperiment(data);
- });
- });
-
- $(".window-close").click(() => {
- this.exitMode();
- });
-
- $(".window-overlay").fadeIn(200);
- }
-
- private prepareAndLaunchExperiment(experiment: IExperiment): void {
- this.prepareSimulationData(experiment);
- this.launchSimulation();
- this.closeExperimentsDialog();
- }
-
- private prepareSimulationData(experiment: IExperiment): void {
- this.currentExperiment = experiment;
- this.currentPath = this.getPathById(this.currentExperiment.pathId);
- this.sections = this.currentPath.sections;
- this.sectionIndex = 0;
- this.currentTick = 1;
- this.playing = false;
- this.stateCache = new StateCache(this);
- this.colorRepresentation = ColorRepresentation.LOAD;
-
- this.sections.sort((a: ISection, b: ISection) => {
- return a.startTick - b.startTick;
- });
-
- $("#experiment-menu-name").text(experiment.name);
- $("#experiment-menu-path").text(SimulationController.getPathName(this.currentPath));
- $("#experiment-menu-scheduler").text(experiment.schedulerName);
- $("#experiment-menu-trace").text(experiment.trace.name);
- }
-
- private closeExperimentsDialog(): void {
- $(".window-overlay").fadeOut(200);
- $(".window-overlay input").val("");
- }
-
- private populateDropdowns(): void {
- const pathDropdown = $("#new-experiment-path-select");
- const traceDropdown = $("#new-experiment-trace-select");
- const schedulerDropdown = $("#new-experiment-scheduler-select");
-
- pathDropdown.empty();
- for (let i = 0; i < this.simulation.paths.length; i++) {
- pathDropdown.append(
- $("<option>").text(SimulationController.getPathName(this.simulation.paths[i]))
- .val(this.simulation.paths[i].id)
- );
- }
-
- traceDropdown.empty();
- for (let i = 0; i < this.traces.length; i++) {
- traceDropdown.append(
- $("<option>").text(this.traces[i].name)
- .val(this.traces[i].id)
- );
- }
-
- schedulerDropdown.empty();
- for (let i = 0; i < this.schedulers.length; i++) {
- schedulerDropdown.append(
- $("<option>").text(this.schedulers[i].name)
- .val(this.schedulers[i].name)
- );
- }
- }
-
- /**
- * Populates the list of experiments.
- */
- private populateExperimentsList(): void {
- const table = $(".experiment-list .list-body");
- table.empty();
-
- console.log("EXPERIMENT", this.experiments);
- console.log("SIMULATION", this.simulation);
-
- if (this.experiments.length === 0) {
- $(".experiment-list").hide();
- $(".no-experiments-alert").show();
- } else {
- $(".no-experiments-alert").hide();
- this.experiments.forEach((experiment: IExperiment) => {
- table.append(
- '<div class="experiment-row">' +
- ' <div>' + experiment.name + '</div>' +
- ' <div>' + this.getPathNameById(experiment.pathId) + '</div>' +
- ' <div>' + experiment.trace.name + '</div>' +
- ' <div>' + experiment.schedulerName + '</div>' +
- ' <div class="remove-experiment glyphicon glyphicon-remove"></div>' +
- '</div>'
- );
- });
- }
- }
-
- private getPathNameById(id: number): string {
- for (let i = 0; i < this.simulation.paths.length; i++) {
- if (id === this.simulation.paths[i].id) {
- return SimulationController.getPathName(this.simulation.paths[i]);
- }
- }
- }
-
- private getPathById(id: number): IPath {
- for (let i = 0; i < this.simulation.paths.length; i++) {
- if (id === this.simulation.paths[i].id) {
- return this.simulation.paths[i];
- }
- }
- }
-
- private static getPathName(path: IPath): string {
- if (path.name === null) {
- return "Path " + path.id;
- } else {
- return path.name;
- }
- }
-
- private setColors() {
- if (this.mapController.appMode === AppMode.SIMULATION) {
- if (this.mapController.interactionLevel === InteractionLevel.BUILDING) {
- this.mapView.roomLayer.intensityLevels = {};
-
- this.stateCache.stateList[this.currentTick].roomStates.forEach((roomState: IRoomState) => {
- if (this.colorRepresentation === ColorRepresentation.LOAD) {
- this.mapView.roomLayer.intensityLevels[roomState.roomId] =
- Util.determineLoadIntensityLevel(roomState.loadFraction);
- }
- });
-
- this.mapView.roomLayer.draw();
- this.mapView.dcObjectLayer.draw();
- } else if (this.mapController.interactionLevel === InteractionLevel.ROOM ||
- this.mapController.interactionLevel === InteractionLevel.OBJECT) {
- this.mapView.dcObjectLayer.intensityLevels = {};
-
- this.stateCache.stateList[this.currentTick].rackStates.forEach((rackState: IRackState) => {
- if (this.colorRepresentation === ColorRepresentation.LOAD) {
- this.mapView.dcObjectLayer.intensityLevels[rackState.rackId] =
- Util.determineLoadIntensityLevel(rackState.loadFraction);
- }
- });
-
- this.mapView.roomLayer.draw();
- this.mapView.dcObjectLayer.draw();
- }
-
- if (this.mapController.interactionLevel === InteractionLevel.OBJECT ||
- this.mapController.interactionLevel === InteractionLevel.NODE) {
- this.stateCache.stateList[this.currentTick].machineStates.forEach((machineState: IMachineState) => {
- let element = $('.node-element[data-id="' + machineState.machineId + '"] .node-element-content');
- element.css("background-color", Util.convertIntensityToColor(
- Util.determineLoadIntensityLevel(machineState.loadFraction)
- ));
-
- // Color all transparent icon overlays, as well
- element = $('.node-element[data-id="' + machineState.machineId + '"] .icon-overlay');
- element.css("background-color", Util.convertIntensityToColor(
- Util.determineLoadIntensityLevel(machineState.loadFraction)
- ));
- });
- }
- } else {
- this.mapView.roomLayer.coloringMode = false;
- this.mapView.dcObjectLayer.coloringMode = false;
-
- this.mapView.roomLayer.draw();
- this.mapView.dcObjectLayer.draw();
- }
- }
-
- /**
- * Populates the building simulation menu with dynamic statistics concerning the state of all rooms in the building.
- */
- private updateBuildingStats(): void {
- if (this.mapController.interactionLevel !== InteractionLevel.BUILDING) {
- return;
- }
-
- const container = $(".building-stats-list");
-
- container.children().remove("div");
-
- this.stateCache.stateList[this.currentTick].roomStates.forEach((roomState: IRoomState) => {
- if (this.colorRepresentation === ColorRepresentation.LOAD && roomState.room !== undefined) {
- const html = '<div>' +
- ' <h4>' + roomState.room.name + '</h4>' +
- ' <p>Load: ' + Math.round(roomState.loadFraction * 100) + '%</p>' +
- '</div>';
- container.append(html);
- }
- });
-
- }
-
- /**
- * Populates the room simulation menu with dynamic statistics concerning the state of all racks in the room.
- */
- private updateRoomStats(): void {
- if (this.mapController.interactionLevel !== InteractionLevel.ROOM) {
- return;
- }
-
- $("#room-name-field").text(this.mapController.roomModeController.currentRoom.name);
- $("#room-type-field").text(this.mapController.roomModeController.currentRoom.roomType);
-
- const container = $(".room-stats-list");
-
- container.children().remove("div");
-
- this.stateCache.stateList[this.currentTick].rackStates.forEach((rackState: IRackState) => {
- if (this.rackToRoomMap[rackState.rackId] !== this.mapController.roomModeController.currentRoom.id) {
- return;
- }
- if (this.colorRepresentation === ColorRepresentation.LOAD) {
- const html = '<div>' +
- ' <h4>' + rackState.rack.name + '</h4>' +
- ' <p>Load: ' + Math.round(rackState.loadFraction * 100) + '%</p>' +
- '</div>';
- container.append(html);
- }
- });
- }
-
- private setupColorMenu(): void {
- const html =
- '<select class="form-control" title="Color Representation" id="color-representation-select">' +
- ' <option value="1" selected>Load</option>' +
- ' <option value="2">Power use</option>' +
- '</select>';
-
- const indicator = $(".color-indicator");
- indicator["popover"]({
- animation: true,
- content: html,
- html: true,
- placement: "top",
- title: "Colors represent:",
- trigger: "manual"
- });
- indicator.click(() => {
- //noinspection JSJQueryEfficiency // suppressed for dynamic element insertion
- if ($("#color-representation-select").length) {
- indicator["popover"]("hide");
- } else {
- indicator["popover"]("show");
-
- const selectElement = $("#color-representation-select");
- selectElement.change(() => {
- console.log(selectElement.val());
- });
- }
- });
- }
-}