summaryrefslogtreecommitdiff
path: root/src/scripts/controllers/simulationcontroller.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripts/controllers/simulationcontroller.ts')
-rw-r--r--src/scripts/controllers/simulationcontroller.ts586
1 files changed, 0 insertions, 586 deletions
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());
- });
- }
- });
- }
-}