From 301d7fd30aae90c13d36f1848b20c20058534938 Mon Sep 17 00:00:00 2001 From: nonodev96 Date: Wed, 24 Nov 2021 22:03:36 +0100 Subject: [PATCH] add eslint and fix project, add Breakpoint manager, fix monaco breakpoint, save file items in firebase store, refactor cypress, etc... Example prime.s --- .eslintrc.json | 77 ++- .github/workflows/create-release.yaml | 5 +- UML/0.1.StoryCase.puml | 109 ++-- UML/3.4.Model.puml | 75 +++ UML/styles.puml | 232 ++++++++ cypress/integration/app.spec.ts | 10 +- cypress/integration/auth.spect.ts | 18 +- cypress/integration/cycle-clock.spect.ts | 31 +- cypress/integration/lang.spec.ts | 8 +- cypress/integration/memory.spect.ts | 4 +- cypress/integration/navigate.spect.ts | 60 +-- cypress/plugins/index.ts | 2 +- cypress/support/commands/goToPage.ts | 66 +-- package.json | 4 +- src/app/CONSTAST.ts | 71 ++- src/app/Utils.ts | 163 ++++-- src/app/__core/DLX/_Memory.ts | 60 ++- src/app/__core/DLX/_Registers.ts | 2 +- src/app/__core/DLX/interfaces.ts | 10 +- src/app/__core/auth/auth.service.ts | 207 ++++---- src/app/__core/machine/PixiJSGrid.ts | 20 +- src/app/__core/machine/PixiJSTable.ts | 23 +- .../machine/PixiTHUMDER_CycleClockDiagram.ts | 22 +- .../__core/machine/PixiTHUMDER_Pipeline.ts | 232 ++++---- src/app/__core/machine/PixiUtils.ts | 8 +- .../machine/debugger/BreakpointManager.ts | 47 ++ src/app/__core/machine/machine.service.ts | 498 ++++++++++-------- .../services/electron/electron.service.ts | 6 +- .../file-system-storage.service.ts | 119 ++++- .../file-system.service.ts | 356 +++++-------- .../socket-provider-connect.service.ts | 18 +- .../__core/services/tasks/tasks.service.ts | 208 ++++---- .../__core/services/tests/tests.service.ts | 2 +- src/app/__core/storage/storage.service.ts | 23 +- .../page-not-found.component.ts | 6 +- src/app/__shared/guard/auth.guard.ts | 29 +- src/app/_tasks/Tasks.ts | 80 +-- src/app/app-routing.module.ts | 4 + src/app/app.component.ts | 22 +- src/app/app.module.ts | 20 +- .../aside/aside-left/aside-left.component.ts | 8 +- .../breadcrumb/breadcrumb.component.ts | 16 +- .../footer-admin/footer-admin.component.ts | 7 +- .../footers/footer/footer.component.ts | 2 +- .../edit-memory-binary32.component.ts | 108 ++-- .../edit-register-binary32.component.ts | 28 +- .../monaco-editor.component.html | 2 +- .../monaco-editor/monaco-editor.component.ts | 184 ++++--- .../admin-navbar/admin-navbar.component.ts | 4 +- .../auth-navbar/auth-navbar.component.html | 14 +- .../auth-navbar/auth-navbar.component.ts | 51 +- ...pixi-cycle-clock-diagram.component.spec.ts | 5 +- .../pixi-cycle-clock-diagram.component.ts | 90 +++- .../pixi-pipeline/pixi-pipeline.component.ts | 47 +- .../components/sidebar/sidebar.component.ts | 4 +- src/app/components/xterm/xterm.component.ts | 41 +- src/app/types.ts | 317 ++++++----- .../_views/multiples-views.component.html | 7 + .../_auth/_views/multiples-views.component.ts | 23 + .../views/_auth/calculator/calculator.view.ts | 30 +- src/app/views/_auth/code/code.view.ts | 133 +---- src/app/views/_auth/config/config.view.html | 55 +- src/app/views/_auth/config/config.view.ts | 52 +- src/app/views/_auth/docs/docs.view.ts | 4 +- .../_auth/file-manager/file-manager.view.html | 1 - .../_auth/file-manager/file-manager.view.ts | 77 +-- src/app/views/_auth/ide/ide.view.html | 45 +- src/app/views/_auth/ide/ide.view.ts | 112 +++- src/app/views/_auth/logger/logger.view.html | 26 + src/app/views/_auth/logger/logger.view.ts | 29 + src/app/views/_auth/memory/memory.view.ts | 44 +- .../cycle-clock-diagram.view.html | 27 +- .../cycle-clock-diagram.view.ts | 12 +- .../_auth/pixi-pipeline/pipeline.view.html | 17 +- .../_auth/pixi-pipeline/pipeline.view.ts | 1 + src/app/views/_auth/profile/profile.view.ts | 5 +- .../views/_auth/registers/registers.view.ts | 24 +- .../views/_auth/statistics/statistics.view.ts | 2 +- src/app/views/_landing/about/about.view.html | 6 +- src/assets/examples-dlx/example-runner.json | 350 +----------- src/assets/examples-dlx/prim.s | 2 +- src/assets/examples-dlx/prime.s/run_0.json | 32 ++ src/assets/examples-dlx/prime.s/run_1.json | 40 ++ src/assets/examples-dlx/prime.s/run_2.json | 40 ++ src/assets/examples-dlx/prime.s/run_3.json | 40 ++ src/assets/examples-dlx/prime.s/run_4.json | 44 ++ src/assets/examples-dlx/prime.s/run_5.json | 44 ++ src/assets/examples-dlx/prime.s/run_6.json | 44 ++ src/assets/examples-dlx/prime.s/run_7.json | 40 ++ src/assets/examples-dlx/prime.s/run_8.json | 35 ++ src/assets/i18n/en.json | 6 +- 91 files changed, 3137 insertions(+), 2197 deletions(-) create mode 100644 UML/3.4.Model.puml create mode 100644 UML/styles.puml create mode 100644 src/app/__core/machine/debugger/BreakpointManager.ts create mode 100644 src/app/views/_auth/_views/multiples-views.component.html create mode 100644 src/app/views/_auth/_views/multiples-views.component.ts create mode 100644 src/app/views/_auth/logger/logger.view.html create mode 100644 src/app/views/_auth/logger/logger.view.ts create mode 100644 src/assets/examples-dlx/prime.s/run_0.json create mode 100644 src/assets/examples-dlx/prime.s/run_1.json create mode 100644 src/assets/examples-dlx/prime.s/run_2.json create mode 100644 src/assets/examples-dlx/prime.s/run_3.json create mode 100644 src/assets/examples-dlx/prime.s/run_4.json create mode 100644 src/assets/examples-dlx/prime.s/run_5.json create mode 100644 src/assets/examples-dlx/prime.s/run_6.json create mode 100644 src/assets/examples-dlx/prime.s/run_7.json create mode 100644 src/assets/examples-dlx/prime.s/run_8.json diff --git a/.eslintrc.json b/.eslintrc.json index 69a93a9..9d87f61 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,13 +1,18 @@ { + "ignorePatterns": [ + "src/app/__core/machine/PixiJSGrid.ts" + ], "env": { - "browser": true, - "node": true, - "es6": true, - "es2017": true + "browser": true, + "node": true, + "es6": true, + "es2017": true }, "overrides": [ { - "files": ["*.ts"], + "files": [ + "*.ts" + ], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", @@ -18,6 +23,7 @@ "parserOptions": { "ecmaVersion": 10, "project": [ + "./cypress/*", "./tsconfig.serve.json", "./src/tsconfig.app.json", "./src/tsconfig.spec.json", @@ -25,20 +31,57 @@ ], "sourceType": "module", "ecmaFeatures": { - "modules": true + "modules": true } }, "plugins": [ "@typescript-eslint", - "@angular-eslint/eslint-plugin" + "@angular-eslint/eslint-plugin", + "cypress" ], "rules": { + "space-before-function-paren": "off", + "no-useless-escape": "off", "@typescript-eslint/indent": [ - "error", 2, { + "error", + 2, + { "SwitchCase": 1, - "CallExpression": {"arguments": "first"}, - "FunctionExpression": {"parameters": "first"}, - "FunctionDeclaration": {"parameters": "first"} + "CallExpression": { + "arguments": "first" + }, + "FunctionExpression": { + "parameters": "first" + }, + "FunctionDeclaration": { + "parameters": "first" + } + } + ], + "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/restrict-plus-operands": "off", + "@typescript-eslint/restrict-template-expressions": "off", + "@typescript-eslint/prefer-regexp-exec": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-async-promise-executor": "off", + "@typescript-eslint/semi": [ + "error" + ], + "@typescript-eslint/promise-function-async": [ + "error", + { + "allowAny": true + } + ], + "@typescript-eslint/no-misused-promises": [ + "off", + { + "checksVoidReturn": true, + "checksConditionals": true } ], "@typescript-eslint/no-empty-function": 0, @@ -54,12 +97,16 @@ } }, { - "files": ["*.component.html"], + "files": [ + "*.component.html" + ], "parser": "@angular-eslint/template-parser", - "plugins": ["@angular-eslint/template"], + "plugins": [ + "@angular-eslint/template" + ], "rules": { - "@angular-eslint/template/banana-in-a-box": "error", - "@angular-eslint/template/no-negated-async": "error" + "@angular-eslint/template/banana-in-a-box": "off", + "@angular-eslint/template/no-negated-async": "error" } } ] diff --git a/.github/workflows/create-release.yaml b/.github/workflows/create-release.yaml index abee040..f7ba163 100644 --- a/.github/workflows/create-release.yaml +++ b/.github/workflows/create-release.yaml @@ -31,8 +31,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} VERSION: "v${{ steps.package_version.outputs.version }}" - MESSAGE: "Release v${{ steps.package_version.outputs.version }}" - NAME: "Release v${{ steps.package_version.outputs.version }}" + MESSAGE: "Pre release v${{ steps.package_version.outputs.version }}" + NAME: "Pre release v${{ steps.package_version.outputs.version }}" - id: step_version run: echo "::set-output name=version::${{ steps.package_version.outputs.version }}" @@ -49,7 +49,6 @@ jobs: asset_name: "thumder-v${{ needs.Make_GitHub_Release.outputs.version }}.AppImage" asset_content_type: application/zip - os: windows-latest - # by electron-builder | artifact_name: "thumder-v${{ needs.Make_GitHub_Release.outputs.version }}.exe" asset_name: "thumder-v${{ needs.Make_GitHub_Release.outputs.version }}.exe" asset_content_type: application/exe diff --git a/UML/0.1.StoryCase.puml b/UML/0.1.StoryCase.puml index f48f180..fa27e18 100644 --- a/UML/0.1.StoryCase.puml +++ b/UML/0.1.StoryCase.puml @@ -10,24 +10,62 @@ skinparam linetype ortho left to right direction 'https://www.freeprojectz.com/uml-diagram/chat-application-system-sequence-diagram -actor "User" as user +actor "Usuario" as user + rectangle THUMDER-Client { - usecase "<>\nCrear una cuenta" as C_UC1 - usecase "<>\nIniciar sesión" as C_UC2 - usecase "<>\nCrear carpeta" as C_UC3.1a - usecase "<>\nCrear fichero" as C_UC3.2a - usecase "<>\nModificar nombre carpeta" as C_UC3.1b - usecase "<>\nModificar nombre fichero"" as C_UC3.2b - usecase "<>\nEliminar carpeta" as C_UC3.1c - usecase "<>\nEliminar fichero" as C_UC3.2c - usecase "<>\nEditar contenido fichero" as C_UC4 - usecase "<>\nSimular" as C_UC5 - usecase "<>\nMostrar estado maquina" as C_UC6 - usecase "<>\nActualizar estado maquina" as C_UC7 -' usecase "<>\nAlterar estado maquina" as C_UC9 -' usecase "<>\nDebug" as C_UC_Debug + usecase "<>\nCrear una cuenta" as S_CU1 + usecase "<>\nIniciar sesión" as S_CU2 + usecase "<>\nRecuperar una cuenta" as S_CU3 + usecase "<>\nModificar una cuenta" as S_CU4 + usecase "<>\nCrear carpetas" as S_CU5 + usecase "<>\nCrear ficheros" as S_CU6 + usecase "<>\nModificar nombre de una carpeta" as S_CU7 + usecase "<>\nModificar nombre de un fichero" as S_CU8 + usecase "<>\nEditar contenido de un fichero" as S_CU9 + usecase "<>\nAuto completar código DLX" as S_CU10 + usecase "<>\nMostrar documentación del DLX en el editor" as S_CU11 + usecase "<>\nMostrar errores de código en el editor" as S_CU12 + usecase "<>\nMostrar logs en la ventana de Xterm.js" as S_CU13 + usecase "<>\nModificar el estado de la memoria" as S_CU14 + usecase "<>\nModificar el estado de los registros" as S_CU15 + usecase "<>\nVisualizar el pipeline" as S_CU16 + usecase "<>\nVisualizar el diagrama de ciclos" as S_CU17 + usecase "<>\nVisualizar el código en memoria" as S_CU18 + usecase "<>\nVisualizar la memoria" as S_CU19 + usecase "<>\nVisualizar los registros" as S_CU20 + usecase "<>\nConfigurar la simulación" as S_CU21 + usecase "<>\nRepresentar datos en distintos formatos y estándares" as S_CU22 + usecase "<>\nCargar una simulación" as S_CU23 + usecase "<>\nRealizar una simulación de un código \npor instrucción" as S_CU24 + usecase "<>\nRealizar una simulación de un código" as S_CU25 } /' +{cu-01}{Crear una cuenta}}{} +{cu-02}{Iniciar una sesión}}{} +{cu-03}{Recuperar una cuenta}}{} +{cu-04}{Modificar una cuenta}}{} +{cu-05}{Crear carpetas}}{} +{cu-06}{Crear ficheros}}{} +{cu-07}{Modificar nombre de una carpeta}}{} +{cu-08}{Modificar nombre de una fichero}}{} +{cu-09}{Editar contenido de un fichero}}{} +{cu-10}{Auto completar código DLX}}{} +{cu-11}{Mostrar documentación del DLX en el editor}}{} +{cu-12}{Mostrar errores de código en el editor}}{} +{cu-13}{Mostrar logs en la ventana de Xterm.js}}{} +{cu-14}{Modificar el estado de la memoria}}{} +{cu-15}{Modificar el estado de los registros}}{} +{cu-16}{Visualizar el pipeline}}{} +{cu-17}{Visualizar el diagrama de ciclos}}{} +{cu-18}{Visualizar el código en memoria}}{} +{cu-19}{Visualizar la memoria}}{} +{cu-20}{Visualizar los registros}}{} +{cu-21}{Configurar la simulación}}{} +{cu-22}{Representar datos en distintos formatos y estándares}}{} +{cu-23}{Cargar una simulación}}{} +{cu-24}{Realizar una simulación de un código por instrucción}}{} +{cu-25}{Realizar una simulación de un código}}{} + rectangle THUMDER-Server { usecase "Recibir" as S_UC00 usecase "Analizar" as S_UC01 @@ -38,21 +76,30 @@ rectangle THUMDER-Server { 'admin --> UC01 'admin --> UC02 -user --> C_UC1 -user --> C_UC2 - -user --> C_UC3.1a -C_UC3.1a --> C_UC3.2a -user --> C_UC3.1b -C_UC3.1b --> C_UC3.2b -user --> C_UC3.1c -C_UC3.1c --> C_UC3.2c - -user --> C_UC4 -user --> C_UC5 -user --> C_UC6 -user --> C_UC7 -'user --> C_UC9 -'user --> C_UC10 +user --> S_CU1 +user --> S_CU2 +S_CU1 --> S_CU3 +S_CU2 --> S_CU4 +user --> S_CU5 +user --> S_CU6 +S_CU5 --> S_CU7 +S_CU6 --> S_CU8 +user --> S_CU9 +S_CU9 --> S_CU10 +user --> S_CU11 +S_CU11 --> S_CU12 +user --> S_CU13 +user --> S_CU14 +S_CU14 --> S_CU15 +user --> S_CU16 +S_CU16 --> S_CU17 +user --> S_CU18 +S_CU18 --> S_CU19 +S_CU19 --> S_CU20 +user --> S_CU21 +user --> S_CU22 +user --> S_CU23 +S_CU23 --> S_CU24 +S_CU24 --> S_CU25 @enduml diff --git a/UML/3.4.Model.puml b/UML/3.4.Model.puml new file mode 100644 index 0000000..8adc150 --- /dev/null +++ b/UML/3.4.Model.puml @@ -0,0 +1,75 @@ +@startuml +'https://plantuml.com/class-diagram +skinparam defaultFontName consolas +skinparam minClassWidth 100 +skinparam conditionStyle inside +'skinparam defaultTextAlignment center +skinparam linetype polyline +skinparam linetype ortho +'left to right direction +'!include styles.puml + + +'class Users <<(T,red)>> { +' Users table +' == +' -uid: int +' -email: string +' -displayName: string +' -photoURL: string +' -emailVerified: boolean +'} +' +'class FileItem <<(T,red)>> { +' FileItem table +' == +' #uid: int +' -name: string +' -path: string +' -content: string +' -pathKeys: string as JSON +' -key: string +' -dateModified: Date +' -size: number +' -isDirectory: boolean +' -hasSubDirectories: boolean +' -thumbnail: string +' -dataItem: string as JSON +' 'any +'} + +'e01 ||..o{ e02 +'one and only one <--> zero or many + + +entity "Users" as e01 { + *uid : number <> + -- + email: text + displayName: text + photoURL: text + emailVerified: boolean +} + +entity "FileItems" as e02 { + *f_id : number <> + key : text + pathKeys: text as JSON + -- + description: text + name: text + path: text + content: text + dateModified: Date + size: number + isDirectory: boolean + hasSubDirectories: boolean + thumbnail: text + dataItem: text as JSON + e1_uid: number <> +} + +e01 ||..o{ e02 + + +@enduml diff --git a/UML/styles.puml b/UML/styles.puml new file mode 100644 index 0000000..a143070 --- /dev/null +++ b/UML/styles.puml @@ -0,0 +1,232 @@ +@startuml + +!define COLOR_DEFAULT_BACKGROUND #92C4DD +!define COLOR_DEFAULT_TEXT Black +!define COLOR_ITP_DARK_BLUE #211551 +!define COLOR_ITP_YELLOW #FFCD00 +!define COLOR_BLACK #000000 +!define COLOR_WHITE #ffffff + +!define FONT_FIRA_MONO Fira Mono +!define FONT_FIRA_CODE Fira Code +!define FONT_FIRA_SANS Fira Sans + +skinparam backgroundcolor transparent + +skinparam defaultFontColor COLOR_DEFAULT_TEXT +skinparam defaultFontName FONT_FIRA_MONO +skinparam defaultFontSize 14 +skinParam defaultFontStyle plain + +skinparam dpi 90 + +'Controls how lines are drawn in PlantUML +'values: otho, polyline, splines (default) +skinparam linetype ortho + +'Distance between elements (vertically, default: 30) +'skinparam nodesep 30 + +'Controls the padding surrounding text +'skinparam padding 10 + +'Distance between elements (horizontally, default: 30) +'skinparam ranksep 30 + +'Line below ensures all classes have the same width in UML class diagram +'skinparam SameClassWidth true + +'Uncomment line below to disable shadows +'skinparam Shadowing false + +skinparam activity { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE + DiamondBackgroundColor COLOR_DEFAULT_BACKGROUND + DiamondBorderColor COLOR_ITP_DARK_BLUE +} + +skinparam actor { + BackgroundColor COLOR_WHITE + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam agent { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam arrow { + Color COLOR_ITP_DARK_BLUE + FontColor COLOR_DEFAULT_TEXT +} + +skinparam artifact { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam biddable { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam boundary { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam card { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam class { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE + FontStyle bold + HeaderBackgroundColor COLOR_DEFAULT_BACKGROUND +} + +skinparam cloud { + BackgroundColor COLOR_WHITE + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam collections { + BackgroundColor COLOR_WHITE + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam component { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE + Style uml2 +} + +skinparam control { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam database { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam designed { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam domain { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam entity { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam file { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam folder { + BackgroundColor COLOR_WHITE + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam frame { + BackgroundColor COLOR_WHITE + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam interface { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam object { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE + FontStyle bold +} + +skinparam node { + BackgroundColor COLOR_WHITE + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam note { + BackgroundColor COLOR_ITP_YELLOW + BorderColor COLOR_BLACK + FontName FONT_FIRA_SANS +} + +skinparam package { + BackgroundColor COLOR_WHITE + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam participant { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam queue { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam rectangle { + BackgroundColor COLOR_WHITE + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam sequence { + DividerBackgroundColor COLOR_WHITE + DividerBorderColor COLOR_ITP_DARK_BLUE + DividerFontStyle bold + GroupBackgroundColor COLOR_DEFAULT_BACKGROUND + GroupBodyBackgroundColor COLOR_WHITE + GroupFontStyle bold + GroupHeaderFontStyle bold + LifeLineBackgroundColor COLOR_WHITE + LifeLineBorderColor COLOR_ITP_DARK_BLUE + ReferenceBackgroundColor COLOR_WHITE + ReferenceHeaderBackgroundColor COLOR_DEFAULT_BACKGROUND +} + +skinparam stack { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam state { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE + StartColor COLOR_ITP_DARK_BLUE + EndColor COLOR_ITP_DARK_BLUE +} + +skinparam storage { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + +skinparam title { + FontName FONT_FIRA_SANS + FontSize 16 +} + +skinparam usecase { + BackgroundColor COLOR_DEFAULT_BACKGROUND + BorderColor COLOR_ITP_DARK_BLUE +} + + + +@enduml diff --git a/cypress/integration/app.spec.ts b/cypress/integration/app.spec.ts index bc4a142..abab8ba 100644 --- a/cypress/integration/app.spec.ts +++ b/cypress/integration/app.spec.ts @@ -1,7 +1,7 @@ describe('My First Test', () => { it('Visits the initial project page', () => { - cy.visit('/') - cy.contains('THUMDER') - cy.get('#title-app').contains('THUMDER') - }) -}) + cy.visit('/'); + cy.contains('THUMDER'); + cy.get('#title-app').contains('THUMDER'); + }); +}); diff --git a/cypress/integration/auth.spect.ts b/cypress/integration/auth.spect.ts index 3c589c6..d278f30 100644 --- a/cypress/integration/auth.spect.ts +++ b/cypress/integration/auth.spect.ts @@ -1,17 +1,17 @@ describe('Auth access', () => { beforeEach(() => { - cy.THUMDER_login() - }) + cy.THUMDER_login(); + }); it('should actually be accessible', () => { - cy.visit('/auth/pipeline') - }) + cy.visit('/auth/pipeline'); + }); it('should actually not be accessible', () => { - cy.visit('/login') - cy.location('pathname').should('not.eq', '/login') - cy.location('pathname').should('eq', '/') - }) + cy.visit('/login'); + cy.location('pathname').should('not.eq', '/login'); + cy.location('pathname').should('eq', '/'); + }); -}) +}); diff --git a/cypress/integration/cycle-clock.spect.ts b/cypress/integration/cycle-clock.spect.ts index a6f5461..125b2eb 100644 --- a/cypress/integration/cycle-clock.spect.ts +++ b/cypress/integration/cycle-clock.spect.ts @@ -1,22 +1,19 @@ -import { THUMDER_goCycleClockDiagram } from "../support/commands/goToPage"; -import { THUMDER_setLangEnglish } from "../support/commands/setLang"; - describe('Cycle Clock Diagram', () => { beforeEach(() => { cy.setCookie('user', JSON.stringify(Cypress.env('USER_COOKIES'))); cy.visit('/'); // Reload page - cy.THUMDER_goCycleClockDiagram() - cy.THUMDER_setLangEnglish() + cy.THUMDER_goCycleClockDiagram(); + cy.THUMDER_setLangEnglish(); - cy.url().should('contain', '/auth/cycle-clock-diagram') + cy.url().should('contain', '/auth/cycle-clock-diagram'); // Define variables with @name cy.get('#pixiCardCycleClockDiagram') - .as('pixiCardCycleClockDiagram') + .as('pixiCardCycleClockDiagram'); cy.get('#pixiCardCycleClockDiagram button[data-card-widget="collapse"]') - .as('pixiCardCycleClockDiagramButtonMinimize') - }) + .as('pixiCardCycleClockDiagramButtonMinimize'); + }); it('Open and close card', () => { cy.contains('Cycle clock diagram'); @@ -24,23 +21,23 @@ describe('Cycle Clock Diagram', () => { // Check card cy.get('@pixiCardCycleClockDiagram') .should(($element) => { - expect($element).to.have.class('card') + expect($element).to.have.class('card'); }); // Check collapse cy.get('@pixiCardCycleClockDiagramButtonMinimize').click(); cy.get('@pixiCardCycleClockDiagram') .should(($element) => { - expect($element).to.have.class('collapsed-card') - }) + expect($element).to.have.class('collapsed-card'); + }); // Check collapse - cy.get('@pixiCardCycleClockDiagramButtonMinimize').click() + cy.get('@pixiCardCycleClockDiagramButtonMinimize').click(); cy.get('@pixiCardCycleClockDiagram') .should(($element) => { - expect($element).not.to.have.class('collapsed-card') - }) + expect($element).not.to.have.class('collapsed-card'); + }); - }) + }); -}) +}); diff --git a/cypress/integration/lang.spec.ts b/cypress/integration/lang.spec.ts index c246be6..230c332 100644 --- a/cypress/integration/lang.spec.ts +++ b/cypress/integration/lang.spec.ts @@ -3,14 +3,14 @@ describe('Tests lang', () => { beforeEach(() => { cy.setCookie('user', JSON.stringify(Cypress.env('USER_COOKIES'))); cy.visit('/'); - }) + }); it('check spanish', () => { cy.THUMDER_setLangSpanish(); - }) + }); it('check english', () => { cy.THUMDER_setLangEnglish(); - }) + }); -}) +}); diff --git a/cypress/integration/memory.spect.ts b/cypress/integration/memory.spect.ts index 4d3b13c..6354d9a 100644 --- a/cypress/integration/memory.spect.ts +++ b/cypress/integration/memory.spect.ts @@ -115,6 +115,6 @@ describe('Memory page', () => { .type('.'); // 3,|1415 // IEEE 754 --> 3,1415 -----> 3,1414999961853027 - cy.get('@input-hexadecimal').should('have.value', '400921CAC0831400') + cy.get('@input-hexadecimal').should('have.value', '400921CAC0831400'); }); -}) +}); diff --git a/cypress/integration/navigate.spect.ts b/cypress/integration/navigate.spect.ts index 70d51e8..fba263d 100644 --- a/cypress/integration/navigate.spect.ts +++ b/cypress/integration/navigate.spect.ts @@ -1,78 +1,76 @@ -// import { THUMDER_goHome } from "../support/commands/goToPage"; - describe('Visit pages no auth', () => { beforeEach(() => { - }) + }); it('go to login', () => { - cy.visit('/login') - cy.url().should('contain', '/login') - }) + cy.visit('/login'); + cy.url().should('contain', '/login'); + }); it('go to forgot my password', () => { - cy.visit('/forgot-password') - cy.url().should('contain', '/forgot-password') - }) + cy.visit('/forgot-password'); + cy.url().should('contain', '/forgot-password'); + }); it('go to register a new membership', () => { - cy.visit('/register') - cy.url().should('contain', '/register') - cy.contains('Register a new membership') - }) + cy.visit('/register'); + cy.url().should('contain', '/register'); + cy.contains('Register a new membership'); + }); -}) +}); describe('Visit pages auth', () => { before(() => { - cy.visit('/') - }) + cy.visit('/'); + }); beforeEach(() => { cy.setCookie('user', JSON.stringify(Cypress.env('USER_COOKIES'))); cy.visit('/'); // Reload page // cy.THUMDER_login() - }) + }); it('can visit file-manager', () => { cy.THUMDER_goFileManager(); - }) + }); it('can visit IDE', () => { cy.THUMDER_goIDE(); - }) + }); it('can visit Pipeline', () => { cy.THUMDER_goPipeline(); - }) + }); it('can visit Cycle clock diagram', () => { cy.THUMDER_goCycleClockDiagram(); - }) + }); it('can visit Memory', () => { cy.THUMDER_goMemory(); - }) + }); it('can visit Code', () => { cy.THUMDER_goCode(); - }) + }); it('can visit Registers', () => { cy.THUMDER_goRegisters(); - }) + }); it('can visit Profile', () => { - cy.THUMDER_goProfile() - }) + cy.THUMDER_goProfile(); + }); it('can visit Documentation', () => { - cy.THUMDER_goDocumentation() - }) + cy.THUMDER_goDocumentation(); + }); it('can visit Config', () => { - cy.THUMDER_goConfig() - }) + cy.THUMDER_goConfig(); + }); -}) +}); diff --git a/cypress/plugins/index.ts b/cypress/plugins/index.ts index 66f8b7f..efdf4c2 100644 --- a/cypress/plugins/index.ts +++ b/cypress/plugins/index.ts @@ -1,3 +1,3 @@ // Plugins enable you to tap into, modify, or extend the internal behavior of Cypress // For more info, visit https://on.cypress.io/plugins-api -export default (on, config) => {} +export default (on, config) => {}; diff --git a/cypress/support/commands/goToPage.ts b/cypress/support/commands/goToPage.ts index f8528b4..4b3e60e 100644 --- a/cypress/support/commands/goToPage.ts +++ b/cypress/support/commands/goToPage.ts @@ -1,68 +1,68 @@ export function THUMDER_goHome() { - cy.get('a[title="HomePage"]').click() - cy.location('pathname').should('eq', '/') + cy.get('a[title="HomePage"]').click(); + cy.location('pathname').should('eq', '/'); } export function THUMDER_openNavigation() { - cy.get('#dropdownSubMenuNavigation').click() + cy.get('#dropdownSubMenuNavigation').click(); } export function THUMDER_goFileManager() { - THUMDER_openNavigation() - cy.get('a[title="file-manager"]').click() - cy.location('pathname').should('eq', '/auth/file-manager') + THUMDER_openNavigation(); + cy.get('a[title="file-manager"]').click(); + cy.location('pathname').should('eq', '/auth/file-manager'); } export function THUMDER_goIDE() { - THUMDER_openNavigation() - cy.get('a[title="ide"]').click() - cy.location('pathname').should('eq', '/auth/ide') + THUMDER_openNavigation(); + cy.get('a[title="ide"]').click(); + cy.location('pathname').should('eq', '/auth/ide'); } export function THUMDER_goPipeline() { - THUMDER_openNavigation() - cy.get('a[title="pipeline"]').click() - cy.location('pathname').should('eq', '/auth/pipeline') + THUMDER_openNavigation(); + cy.get('a[title="pipeline"]').click(); + cy.location('pathname').should('eq', '/auth/pipeline'); } export function THUMDER_goCycleClockDiagram() { - THUMDER_openNavigation() - cy.get('a[title="cycle-clock-diagram"]').click() - cy.location('pathname').should('eq', '/auth/cycle-clock-diagram') + THUMDER_openNavigation(); + cy.get('a[title="cycle-clock-diagram"]').click(); + cy.location('pathname').should('eq', '/auth/cycle-clock-diagram'); } export function THUMDER_goMemory() { - THUMDER_openNavigation() - cy.get('a[title="memory"]').click() - cy.location('pathname').should('eq', '/auth/memory') + THUMDER_openNavigation(); + cy.get('a[title="memory"]').click(); + cy.location('pathname').should('eq', '/auth/memory'); } export function THUMDER_goCode() { - THUMDER_openNavigation() - cy.get('a[title="code"]').click() - cy.location('pathname').should('eq', '/auth/code') + THUMDER_openNavigation(); + cy.get('a[title="code"]').click(); + cy.location('pathname').should('eq', '/auth/code'); } export function THUMDER_goRegisters() { - THUMDER_openNavigation() - cy.get('a[title="registers"]').click() - cy.location('pathname').should('eq', '/auth/registers') + THUMDER_openNavigation(); + cy.get('a[title="registers"]').click(); + cy.location('pathname').should('eq', '/auth/registers'); } export function THUMDER_goProfile() { - THUMDER_openNavigation() - cy.get('a[title="profile"]').click() - cy.location('pathname').should('eq', '/auth/profile') + THUMDER_openNavigation(); + cy.get('a[title="profile"]').click(); + cy.location('pathname').should('eq', '/auth/profile'); } export function THUMDER_goDocumentation() { - THUMDER_openNavigation() - cy.get('a[title="documentation"]').click() - cy.location('pathname').should('eq', '/auth/documentation') + THUMDER_openNavigation(); + cy.get('a[title="documentation"]').click(); + cy.location('pathname').should('eq', '/auth/documentation'); } export function THUMDER_goConfig() { - THUMDER_openNavigation() - cy.get('a[title="config"]').click() - cy.location('pathname').should('eq', '/auth/config') + THUMDER_openNavigation(); + cy.get('a[title="config"]').click(); + cy.location('pathname').should('eq', '/auth/config'); } diff --git a/package.json b/package.json index e629ce3..a8c91fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "thumder", - "version": "1.2.3", + "version": "1.2.5", "description": "TFG - THUMDER (THe UltiMate Dlx EmulatoR): emulador multiplataforma DLX con fines didácticos", "homepage": "https://github.com/nonodev96/THUMDER", "author": { @@ -93,6 +93,8 @@ "electron-builder": "22.10.5", "electron-reload": "1.5.0", "eslint": "7.10.0", + "eslint-plugin-cypress": "2.12.1", + "eslint-plugin-cypress-dev": "3.0.2", "eslint-plugin-import": "2.22.1", "jasmine-core": "~3.6.0", "jasmine-spec-reporter": "~5.0.0", diff --git a/src/app/CONSTAST.ts b/src/app/CONSTAST.ts index 12e1895..8e9f318 100644 --- a/src/app/CONSTAST.ts +++ b/src/app/CONSTAST.ts @@ -8,7 +8,7 @@ import { TypeFloatingPointStageConfiguration, TypeRegister, TypeRegisterToEdit, - TypeTableCode, TypeDataStatistics, TypePipeline + TypeTableCode, TypeDataStatistics, TypePipeline, TypeStepSimulation } from "./types"; import { SocketIoConfig } from "ngx-socket-io"; @@ -18,6 +18,8 @@ export const REGEX_IS_ABSOLUTE_HREF = new RegExp('(?:^[a-z][a-z0-9+.-]*:|\/\/)', export const REGEX_HEXADECIMAL_08 = new RegExp('^(0x|0X|)?([a-fA-F0-9]{08})$', 'i'); export const REGEX_HEXADECIMAL_16 = new RegExp('^(0x|0X|)?([a-fA-F0-9]{16})$', 'i'); +export const DEFAULT_TIME_SIMULATION: number = 250; +export const DEFAULT_AUTO_SAVE: boolean = true; export const DEFAULT_LANG: TypeLang = 'en'; // 0x8000 --> 32768 export const DEFAULT_MEMORY_SIZE: number = 32768; @@ -42,6 +44,39 @@ export const DEFAULT_BINARY_16_BITS = "".padStart(16, '0'); export const DEFAULT_BINARY_32_BITS = "".padStart(32, '0'); export const DEFAULT_BINARY_64_BITS = "".padStart(64, '0'); +export const DEFAULT_PIPELINE: TypePipeline = { + IF: "", + ID: "", + intEX: "", + MEM: "", + WB: "", + faddEX: [], + fdivEX: [], + fmultEX: [], +}; + +export const DEFAULT_STEP_SIMULATION: TypeStepSimulation = { + IF: 0, + IF_stall: 0, + ID: 0, + ID_stall: 0, + intEX: 0, + intEX_stall: 0, + MEM: 0, + MEM_stall: 0, + WB: 0, + WB_stall: 0, + + line: 0, + step: 0, + stage: "other", + instruction: "----------", + codeInstruction: "0x00000000", + pipeline: DEFAULT_PIPELINE, + memory: [], + registers: [] +}; + export const DEFAULT_DATA_STATISTICS: TypeDataStatistics = { TOTAL: { CYCLES_EXECUTED: {cycles: 0}, @@ -92,7 +127,7 @@ export const DEFAULT_CODE: TypeCode = { instruction: "", address: "", code: "" -} +}; export const DEFAULT_TABLE_CODE: TypeTableCode = { text: "", @@ -101,13 +136,13 @@ export const DEFAULT_TABLE_CODE: TypeTableCode = { address: "", stage: "", // binary: "00000000000000000000000000000000" -} +}; export const DEFAULT_CONFIG_TOAST: Partial = { progressBar: true, progressAnimation: 'decreasing', closeButton: true -} +}; export const MAX_VALUE_TYPE_DATA = { "Byte": 255, @@ -115,7 +150,7 @@ export const MAX_VALUE_TYPE_DATA = { "Word": 4294967295, "Float": 4294967295, "Double": 18446744073709551615 -} +}; export const STEP_TYPE_DATA = { "Byte": 1, @@ -123,10 +158,6 @@ export const STEP_TYPE_DATA = { "Word": 1, "Float": 0.1, "Double": 0.1 -} - -export const DEFAULT_PIPELINE: TypePipeline = { - IF: "", ID: "", MEM: "", WB: "", faddEX: [], fdivEX: [], fmultEX: [], intEX: "", }; export const REGISTER_TO_EDIT: TypeRegister = 'Control'; @@ -160,11 +191,11 @@ export const REGISTERS_DATA: TypeDataRegister = { export const MACHINE_TYPE_REGISTERS: TypeRegister[] = [ "Control", "Integer", "Float", "Double" -] +]; export const MACHINE_REGISTERS_C: TypeRegisterToEdit[] = [ "PC", "IMAR", "IR", "A", "AHI", "B", "BHI", "BTA", "ALU", "ALUHI", "FPSR", "DMAR", "SDR", "SDRHI", "LDR", "LDRHI" -] +]; export const MACHINE_REGISTERS_R: TypeRegisterToEdit[] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, @@ -313,7 +344,7 @@ export const ASCII_TABLE = [ {hex: "7D", binary: "01111101", ascii: "}"}, {hex: "7E", binary: "01111110", ascii: "~"}, {hex: "7F", binary: "01111111", ascii: "DEL"} -] +]; export const CONFIG_WEBSOCKET: SocketIoConfig = { url: 'http://localhost:3000', @@ -366,6 +397,13 @@ export const AUTH_ROUTES: PublicRoutesList = [ displayName: 'IDE', data: {breadcrumb: 'IDE'} }, + { + lang: "LOGGER", + path: "logger", + routerLink: '/auth/logger', + displayName: 'Logger', + data: {breadcrumb: 'Logger'} + }, { lang: "MEMORY", path: "memory", @@ -408,7 +446,14 @@ export const AUTH_ROUTES: PublicRoutesList = [ displayName: 'Statistics', data: {breadcrumb: 'Statistics'} }, -] + { + lang: "MULTIVIEW", + path: "multiview", + routerLink: '/auth/multiview', + displayName: 'Multiview', + data: {breadcrumb: 'Multiview'} + }, +]; export const PUBLIC_ROUTES: PublicRoutes = { lang: '/', diff --git a/src/app/Utils.ts b/src/app/Utils.ts index b744308..1b97211 100644 --- a/src/app/Utils.ts +++ b/src/app/Utils.ts @@ -1,10 +1,19 @@ import { MachineService } from "./__core/machine/machine.service"; import { ASCII_TABLE } from "./CONSTAST"; import { OPCODES_TYPE_I_J, OPCODES_TYPE_R_OPCODE_0, OPCODES_TYPE_R_OPCODE_1 } from "./__core/DLX/__OPCODES"; +import { InterfaceFileItem } from "./types"; +import { FileItem } from "./__core/services/file-system-nonodev96/file-system.service"; +import firebase from "firebase/app"; +import Timestamp = firebase.firestore.Timestamp; export namespace Utils { + export async function wait(timeMs: number = 1000): Promise { + await new Promise(resolve => setTimeout(resolve, timeMs)); + return Promise.resolve(); + } + export function MapToArray(map: Map): { key: K; value: V }[] { return Array.from(map, ([key, value]) => ({ key, @@ -12,21 +21,27 @@ export namespace Utils { })); } + export function stringFormat(msg: string, ...args: any) { + return msg.replace(/{([0-9]+)}/g, function (match, index) { + return typeof args[index] == 'undefined' ? match : args[index]; + }); + } + export function clone(data: T) { return JSON.parse(JSON.stringify(data)); } export function addressToIndex(address: string): number { - return Math.trunc(this.hexadecimalToDecimal(address) / 4) + return Math.trunc(this.hexadecimalToDecimal(address) / 4); } export function orderJSONBy(array, selector, desc = false) { return [...array].sort((a, b) => { if (desc) { - return parseFloat(a.selector) - parseFloat(b.selector) + return parseFloat(a.selector) - parseFloat(b.selector); } else - return parseFloat(b.selector) - parseFloat(a.selector) + return parseFloat(b.selector) - parseFloat(a.selector); }); } @@ -38,7 +53,7 @@ export namespace Utils { } export function initLongRunningFactory() { - return () => { + return async () => { return new Promise((resolve) => { setTimeout(() => { resolve(); @@ -47,10 +62,10 @@ export namespace Utils { }; } - export function initWithDependencyFactory(service: Object) { + export function initWithDependencyFactory(service: any) { return () => { console.log('initWithDependencyFactory - started'); - return service + return service; }; } @@ -59,7 +74,7 @@ export namespace Utils { // console.log('initServicesFactory - started') const finish = await service.resetMachineStatus(); if (finish === false) { - console.log('initServicesFactory - completed ', finish) + console.log('initServicesFactory - completed ', finish); } }; } @@ -94,12 +109,12 @@ export namespace Utils { } export function isSubsetV2(a, b): boolean { - return new Set(b).size === new Set(b.concat(a)).size + return new Set(b).size === new Set(b.concat(a)).size; } export function modNotNegative(n: number, m: number): number { let value = ((n % m)) % m; - value = value < 0 ? 0 : value + value = value < 0 ? 0 : value; return value; } @@ -138,12 +153,12 @@ export namespace Utils { } export function hexadecimalToBinary(hexadecimal: string, args = {maxLength: 32, fillString: '0'}): string { - const decimal = hexadecimalToDecimal(hexadecimal) - return (decimal).toString(2).padStart(args.maxLength, args.fillString) + const decimal = hexadecimalToDecimal(hexadecimal); + return (decimal).toString(2).padStart(args.maxLength, args.fillString); } export function binaryToHexadecimal(binary: string, args = {maxLength: 8, fillString: '0'}): string { - return parseInt(binary, 2).toString(16).toUpperCase().padStart(args.maxLength, args.fillString) + return parseInt(binary, 2).toString(16).toUpperCase().padStart(args.maxLength, args.fillString); } export function hexadecimalToDecimal(hex: string): number { @@ -167,11 +182,11 @@ export namespace Utils { * result =======> 1100-1100-0000-0000 */ export function binaryStringSwap(binary_A: string, binary_B: string, index: number): string { - return replaceAt(binary_A, index, binary_B) + return replaceAt(binary_A, index, binary_B); } export function binaryStringSwap_module(oldValueBinaryString: string, newValuePart: string, start: number, end: number, module: number) { - let result = oldValueBinaryString.split(''); + const result = oldValueBinaryString.split(''); for (let i = 0; i < 32; i++) { if (i >= start && i < end) { result[i] = newValuePart[i % module]; @@ -181,15 +196,15 @@ export namespace Utils { } export function integer8ToBin(integer8: number) { - return Math.abs(integer8).toString(2).padStart(8, '0').toString() + return Math.abs(integer8).toString(2).padStart(8, '0').toString(); } export function integer16ToBin(integer16: number) { - return Math.abs(integer16).toString(2).padStart(16, '0').toString() + return Math.abs(integer16).toString(2).padStart(16, '0').toString(); } export function integer32ToBin(integer32: number) { - return Math.abs(integer32).toString(2).padStart(32, '0').toString() + return Math.abs(integer32).toString(2).padStart(32, '0').toString(); } export function convertIEEE754_Number_To_Binary32Bits(float32: number): string { @@ -231,7 +246,7 @@ export namespace Utils { } export function convertIEEE754_Binary32Bits_To_Number(str: string): number { - if (str.length !== 32) throw new Error("Binary cannot be converted because the length is not 32.") + if (str.length !== 32) throw new Error("Binary cannot be converted because the length is not 32."); const arr = []; for (let i = 0; i < str.length; i += 8) { const inner = str.slice(i, i + 8); @@ -242,7 +257,7 @@ export namespace Utils { } export function convertIEEE754_Binary64Bits_To_Number(str: string): number { - if (str.length !== 64) throw new Error("Binary cannot be converted because the length is not 64.") + if (str.length !== 64) throw new Error("Binary cannot be converted because the length is not 64."); const arr = []; for (let i = 0; i < str.length; i += 8) { const inner = str.slice(i, i + 8); @@ -281,18 +296,18 @@ export namespace Utils { const func_field = binary.substr(21, 11); const func_field_6_last_bits = func_field.substr(-6); - const rs1 = parseInt(binary.substr(6, 5), 2); - const rs2 = parseInt(binary.substr(6 + 5, 5), 2); - const rd0 = parseInt(binary.substr(6 + 5 + 5, 5), 2); + const rs1 = parseInt(binary.substr(6, 5), 2).toString(); + const rs2 = parseInt(binary.substr(6 + 5, 5), 2).toString(); + const rd0 = parseInt(binary.substr(6 + 5 + 5, 5), 2).toString(); - const rs1F = parseInt(binary.substr(6, 5), 2); - const rs2F = parseInt(binary.substr(6 + 5, 5), 2); - const rd0F = parseInt(binary.substr(6 + 5 + 5, 5), 2); + const rs1F = parseInt(binary.substr(6, 5), 2).toString(); + const rs2F = parseInt(binary.substr(6 + 5, 5), 2).toString(); + const rd0F = parseInt(binary.substr(6 + 5 + 5, 5), 2).toString(); - const rs1I = parseInt(binary.substr(6, 5), 2); - const rd0I = parseInt(binary.substr(6 + 5, 5), 2); - const data = parseInt(binary.substr(6 + 5 + 5, 16), 2); - const data_26 = parseInt(binary.substr(6, 26), 2); + const rs1I = parseInt(binary.substr(6, 5), 2).toString(); + const rd0I = parseInt(binary.substr(6 + 5, 5), 2).toString(); + const data = parseInt(binary.substr(6 + 5 + 5, 16), 2).toString(); + const data_26 = parseInt(binary.substr(6, 26), 2).toString(); if (binary === "".padStart(32, '0')) { return "NOP"; @@ -300,11 +315,11 @@ export namespace Utils { const is_OPCODE_0 = opcode === "000000"; if (is_OPCODE_0) { - const obj_instrction_type_r_opcode_0 = OPCODES_TYPE_R_OPCODE_0.find(value => { + const obj_instruction_type_r_opcode_0 = OPCODES_TYPE_R_OPCODE_0.find(value => { return value.bits === func_field_6_last_bits; - }) - if (obj_instrction_type_r_opcode_0) { - const instruction_name = obj_instrction_type_r_opcode_0.name; + }); + if (obj_instruction_type_r_opcode_0) { + const instruction_name = obj_instruction_type_r_opcode_0.name; // Type R with opcode = 0 return instruction_name + " R" + rd0 + ", R" + rs1 + ", R" + rs2; } @@ -313,11 +328,11 @@ export namespace Utils { const is_OPCODE_1 = opcode === "000001"; if (is_OPCODE_1) { - const obj_instrction_type_r_opcode_1 = OPCODES_TYPE_R_OPCODE_1.find(value => { + const obj_instruction_type_r_opcode_1 = OPCODES_TYPE_R_OPCODE_1.find(value => { return value.bits === func_field_6_last_bits; - }) - if (obj_instrction_type_r_opcode_1) { - const instruction_name = obj_instrction_type_r_opcode_1.name; + }); + if (obj_instruction_type_r_opcode_1) { + const instruction_name = obj_instruction_type_r_opcode_1.name; // Type R with opcode = 1 return instruction_name + " F" + rd0F + ", F" + rs1F + ", F" + rs2F; } @@ -327,11 +342,11 @@ export namespace Utils { // Others OPCODES const is_OPCODE_TYPE_I_or_J = OPCODES_TYPE_I_J.some(value => { return value.bits === opcode; - }) + }); if (is_OPCODE_TYPE_I_or_J) { const obj_instruction_type_i_or_j = OPCODES_TYPE_I_J.find(value => { return value.bits === opcode; - }) + }); if (obj_instruction_type_i_or_j) { const instruction_name = obj_instruction_type_i_or_j.name; @@ -341,7 +356,7 @@ export namespace Utils { return instruction_name + " R" + rd0I + ", R" + rs1I + ", #" + data; } if ("LHI" === instruction_name) { - return instruction_name + " R" + rd0I + "#" + data; + return instruction_name + " R" + rd0I + ", #" + data; } // Type J ? @@ -349,7 +364,7 @@ export namespace Utils { return instruction_name + " #" + data; } if (["BEQZ", "BNEZ"].includes(instruction_name)) { - return instruction_name + " R" + rs1I + " #" + data; + return instruction_name + " R" + rs1I + ", #" + data; } if (["BFPT", "BFPF"].includes(instruction_name)) { return instruction_name + " #" + data; @@ -390,4 +405,70 @@ export namespace Utils { return "Instruction error #-1"; } + + export function MAP_FileItem_TO_InterfaceFileItem(fileItem: FileItem, UID: string): InterfaceFileItem { + return { + key: fileItem.key ?? '', + pathKeys: fileItem.pathKeys ?? [], + path: fileItem.path ?? '', + name: fileItem.name ?? '', + isDirectory: fileItem.isDirectory ?? false, + hasSubDirectories: fileItem.hasSubDirectories ?? false, + dateModified: Timestamp.fromDate(fileItem.dateModified ?? new Date()), + thumbnail: fileItem.thumbnail ?? '', + size: fileItem.size ?? 0, + dataItem: fileItem.dataItem ?? {}, + + e1_uid: UID, + f_id: '', + description: '', + content: '' + } as InterfaceFileItem; + } + + export function MAP_FileItemArray_TO_InterfaceFileItemArray(fileItemArray: FileItem[], UID: string): InterfaceFileItem[] { + return fileItemArray.map((value) => { + return this.MAP_FileItem_TO_InterfaceFileItem(value, UID); + }); + } + + export function MAP_InterfaceFileItem_TO_FileItem(interfaceFileItem: InterfaceFileItem): FileItem { + const item: FileItem = new FileItem(interfaceFileItem.path, interfaceFileItem.isDirectory, interfaceFileItem.pathKeys); + item.key = interfaceFileItem.key ?? ''; + item.pathKeys = interfaceFileItem.pathKeys ?? []; + item.path = interfaceFileItem.path ?? ''; + item.name = interfaceFileItem.name ?? ''; + item.isDirectory = interfaceFileItem.isDirectory ?? false; + item.hasSubDirectories = interfaceFileItem.hasSubDirectories ?? false; + if (interfaceFileItem.dateModified) { + item.dateModified = Timestamp.fromMillis(interfaceFileItem.dateModified.seconds * 1000).toDate(); + } else { + item.dateModified = new Date(); + } + item.thumbnail = interfaceFileItem.thumbnail ?? ''; + item.size = interfaceFileItem.size ?? 0; + item.dataItem = interfaceFileItem.dataItem ?? {}; + return item; + } + + export function MAP_InterfaceFileItemArray_TO_FileItemArray(interfaceFileItemArray: InterfaceFileItem[]): FileItem[] { + return interfaceFileItemArray.map((value) => { + return this.MAP_InterfaceFileItem_TO_FileItem(value); + }); + } + + + export function new_InterfaceFileItem() { + const {uid} = JSON.parse(localStorage.getItem('user')); + const fileItem = new FileItem('', false, []); + const interfaceFileItem: InterfaceFileItem = { + ...fileItem, + dateModified: Timestamp.fromDate(new Date()), + content: "", + description: "", + e1_uid: uid, + f_id: "", + }; + return interfaceFileItem; + } } diff --git a/src/app/__core/DLX/_Memory.ts b/src/app/__core/DLX/_Memory.ts index 6f690d0..5a01ee9 100644 --- a/src/app/__core/DLX/_Memory.ts +++ b/src/app/__core/DLX/_Memory.ts @@ -42,12 +42,12 @@ export class Memory implements InterfaceMemory { this._memoryInt8Array[index].toString(2).padStart(8, '0') + this._memoryInt8Array[index + 1].toString(2).padStart(8, '0') + this._memoryInt8Array[index + 2].toString(2).padStart(8, '0') + - this._memoryInt8Array[index + 3].toString(2).padStart(8, '0') + this._memoryInt8Array[index + 3].toString(2).padStart(8, '0'); } // WORD - SET public setMemoryWordByIndex(index: number, data: Int32) { - this.setMemoryWordBinaryByIndex(index, data.binary) + this.setMemoryWordBinaryByIndex(index, data.binary); } public setMemoryWordByAddress(address: string, data: Int32): void { @@ -55,11 +55,16 @@ export class Memory implements InterfaceMemory { this.setMemoryWordBinaryByIndex(index, data.binary); } - public setMemoryWordBinaryByIndex(index: number, binary: string): void { - const p0 = binary.substr(0, 8); - const p1 = binary.substr(8, 8); - const p2 = binary.substr(16, 8); - const p3 = binary.substr(24, 8); + public setMemoryWordBinaryByAddress(address: string, binary32: string): void { + const index = Utils.hexadecimalToDecimal(address); + this.setMemoryWordBinaryByIndex(index, binary32); + } + + public setMemoryWordBinaryByIndex(index: number, binary32: string): void { + const p0 = binary32.substr(0, 8); + const p1 = binary32.substr(8, 8); + const p2 = binary32.substr(16, 8); + const p3 = binary32.substr(24, 8); this._memoryInt8Array[index] = parseInt(p0, 2); this._memoryInt8Array[index + 1] = parseInt(p1, 2); this._memoryInt8Array[index + 2] = parseInt(p2, 2); @@ -77,6 +82,12 @@ export class Memory implements InterfaceMemory { this._memoryInt8Array[index] = parseInt(p0, 2); } + public setMemoryByteBinaryByAddress(address: string, binary08: string): void { + const p0 = binary08.substr(0, 8); + const index = Utils.hexadecimalToDecimal(address); + this._memoryInt8Array[index] = parseInt(p0, 2); + } + // HALF WORD - GET public getMemoryHalfWordBinaryByIndex(index: number): string { return "" + @@ -85,13 +96,40 @@ export class Memory implements InterfaceMemory { } // HALF WORD - SET - public setMemoryHalfWordBinaryByIndex(index: number, binary: string): void { - const p0 = binary.substr(0, 8); - const p1 = binary.substr(8, 8); + public setMemoryHalfWordBinaryByIndex(index: number, binary16: string): void { + const p0 = binary16.substr(0, 8); + const p1 = binary16.substr(8, 8); + this._memoryInt8Array[index] = parseInt(p0, 2); + this._memoryInt8Array[index + 1] = parseInt(p1, 2); + } + + public setMemoryHalfWordBinaryByAddress(address: string, binary16: string): void { + const index = Utils.hexadecimalToDecimal(address); + const p0 = binary16.substr(0, 8); + const p1 = binary16.substr(8, 8); this._memoryInt8Array[index] = parseInt(p0, 2); this._memoryInt8Array[index + 1] = parseInt(p1, 2); } + + // HALF WORD - SET + public setMemoryFloatBinaryByAddress(address: string, binary32: string): void { + const index = Utils.hexadecimalToDecimal(address); + this.setMemory_stringBinary_ByIndex(index, binary32); + } + + public setMemoryDoubleBinaryByAddress(address: string, binary64: string): void { + const index = Utils.hexadecimalToDecimal(address); + this.setMemory_stringBinary_ByIndex(index, binary64); + } + + private setMemory_stringBinary_ByIndex(index: number, binary_08_16_32_64: string): void { + for (let pos = 0; pos < binary_08_16_32_64.length; pos += 8) { + const p0 = binary_08_16_32_64.substr(pos, 8); + this._memoryInt8Array[index + (pos % 8)] = parseInt(p0, 2); + } + } + // 0 1 2 3 // 00000000 - 00000000 - 00000000 - 00000000 // Page code.view @@ -113,7 +151,7 @@ export class Memory implements InterfaceMemory { public getAllIndexByWord(): number[] { const list = []; for (let index = 0; index < this._memorySizeBytes; index += 4) { - list.push(index) + list.push(index); } return list; } diff --git a/src/app/__core/DLX/_Registers.ts b/src/app/__core/DLX/_Registers.ts index c663f73..1b594fa 100644 --- a/src/app/__core/DLX/_Registers.ts +++ b/src/app/__core/DLX/_Registers.ts @@ -1,4 +1,4 @@ -import { Double64, Float32, Int32 } from "../typesData"; +import { Float32, Int32 } from "../typesData"; import { InterfaceRegisters } from "./interfaces"; export class Registers implements InterfaceRegisters { diff --git a/src/app/__core/DLX/interfaces.ts b/src/app/__core/DLX/interfaces.ts index 4ec182b..f6f5fa8 100644 --- a/src/app/__core/DLX/interfaces.ts +++ b/src/app/__core/DLX/interfaces.ts @@ -1,4 +1,4 @@ -import { Double64, Float32, Int32 } from "../typesData"; +import { Float32, Int32 } from "../typesData"; import { stringOfLength, StringOfLength } from "../../types"; export interface InterfaceRegisters { @@ -22,6 +22,7 @@ export interface InterfaceRegisters { F: Float32[]; } + export interface InterfaceMemory { } @@ -60,7 +61,7 @@ export class InstructionTypeI implements InterfaceInstructionTypeI { } public toString() { - return this.codeOP + this.rs1 + this.rd + this.inmediato; + return this.codeOP.toString() + this.rs1.toString() + this.rd.toString() + this.inmediato.toString(); } } @@ -80,7 +81,7 @@ export class InstructionTypeR implements InstructionTypeR { } public toString() { - return this.codeOP + this.rs1 + this.rs2 + this.rd + this.func; + return this.codeOP.toString() + this.rs1.toString() + this.rs2.toString() + this.rd.toString() + this.func.toString(); } } @@ -94,7 +95,7 @@ export class InstructionTypeJ implements InterfaceInstructionTypeJ { } public toString() { - return this.codeOP + this.des; + return this.codeOP.toString() + this.des.toString(); } } @@ -113,5 +114,4 @@ export abstract class Operation implements InterfaceOperation { get name() { return this._name; } - } diff --git a/src/app/__core/auth/auth.service.ts b/src/app/__core/auth/auth.service.ts index 063b94c..5d049c4 100644 --- a/src/app/__core/auth/auth.service.ts +++ b/src/app/__core/auth/auth.service.ts @@ -1,5 +1,5 @@ import { Injectable, NgZone, OnDestroy, OnInit } from '@angular/core'; -import { User } from "../../types"; +import { InterfaceUser } from "../../types"; import { AngularFireAuth } from "@angular/fire/auth"; import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore'; import { ElectronService } from "../services"; @@ -7,31 +7,20 @@ import { Router } from "@angular/router"; import { Subscription } from "rxjs"; import firebase from 'firebase/app'; import UserCredential = firebase.auth.UserCredential; -// import GoogleAuthProvider = firebase.auth.GoogleAuthProvider(); -// import GithubAuthProvider = firebase.auth.GithubAuthProvider(); @Injectable({ providedIn: 'root' }) export class AuthService implements OnInit, OnDestroy { - userData: User; // Save logged in user data + public userData: InterfaceUser; // Save logged in user data private subscriptions$ = new Subscription(); - // afs - // afAuth - // ngZone - // router - // electronService - constructor( - public afs: AngularFirestore, // Inject Firestore service - public afAuth: AngularFireAuth, // Inject Firebase auth service - public ngZone: NgZone, // NgZone service to remove outside scope warning - public router: Router, - public electronService: ElectronService - ) { - // this.afAuth.auth.setPersistence('none'); - /* Saving user data in localstorage when - logged in and setting up null when logged out */ + + constructor(public afs: AngularFirestore, // Inject Firestore service + public afAuth: AngularFireAuth, // Inject Firebase auth service + public ngZone: NgZone, // NgZone service to remove outside scope warning + public router: Router, + public electronService: ElectronService) { this.subscriptions$.add( this.afAuth.authState.subscribe(user => { if (user) { @@ -43,59 +32,65 @@ export class AuthService implements OnInit, OnDestroy { JSON.parse(localStorage.getItem('user')); } }) - ) + ); } - ngOnInit() { + ngOnInit(): void { // this.afAuth.auth.setPersistence('none') } ngOnDestroy(): void { - this.subscriptions$.unsubscribe() + this.subscriptions$.unsubscribe(); } // Sign in with email/password - SignIn(email, password) { - return this.afAuth.signInWithEmailAndPassword(email, password) - .then(async (userCredential) => { - await this.SetUserData(userCredential); - this.ngZone.run(() => { - this.router.navigate(['/']); - }); - }).catch((error) => { - window.alert(error.message) - }) + async SignIn(email, password): Promise { + try { + const userCredential = await this.afAuth.signInWithEmailAndPassword(email, password); + await this.SetUserData(userCredential); + this.ngZone.run(() => { + this.router.navigate(['/']); + }); + return userCredential; + } catch (error) { + console.error(error); + } } // Sign up with email/password - SignUp(email, password) { - return this.afAuth.createUserWithEmailAndPassword(email, password) - .then(async (userCredential) => { - /* Call the SendVerificationMail(userCredential) function when new user sign - up and returns promise */ - await this.SendVerificationMail(userCredential); - await this.SetUserData(userCredential); - }).catch((error) => { - window.alert(error.message) - }) + async SignUp(email, password): Promise { + try { + const userCredential = await this.afAuth.createUserWithEmailAndPassword(email, password); + /* Call the SendVerificationMail(userCredential) function when new user sign + up and returns promise */ + await this.SendVerificationMail(userCredential); + await this.SetUserData(userCredential); + return userCredential; + } catch (error) { + console.error(error); + } } // Send email verification when new user sign up - SendVerificationMail(userCredential: UserCredential) { - return userCredential.user.sendEmailVerification() - .then(async () => { - await this.router.navigate(['/']); - }) + async SendVerificationMail(userCredential: UserCredential): Promise { + try { + await userCredential.user.sendEmailVerification(); + await this.router.navigate(['/']); + } catch (e) { + console.error(e); + } + return Promise.resolve(); } // Reset Forgot password - ForgotPassword(passwordResetEmail) { - return this.afAuth.sendPasswordResetEmail(passwordResetEmail) - .then(() => { - window.alert('Password reset email sent, check your inbox.'); - }).catch((error) => { - window.alert(error) - }) + async ForgotPassword(passwordResetEmail): Promise { + try { + const result_void = await this.afAuth.sendPasswordResetEmail(passwordResetEmail); + window.alert('Password reset email sent, check your inbox.'); + } catch (error) { + console.error(error); + } + return Promise.resolve(); } // Returns true when user is logged in and email is verified @@ -105,91 +100,89 @@ export class AuthService implements OnInit, OnDestroy { } // Sign in with Google - GoogleAuth(): Promise { + async GoogleAuth(): Promise { return this.AuthLogin(new firebase.auth.GoogleAuthProvider()); } // Sign in with Google - GithubAuth(): Promise { + async GithubAuth(): Promise { return this.AuthLogin(new firebase.auth.GithubAuthProvider()); } // Auth logic to run auth providers - AuthLoginAnonymously(): Promise { - return this.afAuth.signInAnonymously() - .then(async (userCredential) => { - - await this.SetUserData(userCredential); - this.ngZone.run(() => { - this.router.navigate(['/']); - }) - - }).catch((error) => { - window.alert(error) - }) + async AuthLoginAnonymously(): Promise { + try { + const userCredential = await this.afAuth.signInAnonymously(); + await this.SetUserData(userCredential); + this.ngZone.run(() => { + this.router.navigate(['/']); + }); + } catch (error) { + console.error(error); + } + return Promise.resolve(); } // Auth logic to run auth providers - private AuthLogin(provider): Promise { - return this.afAuth.signInWithPopup(provider) - .then(async (userCredential) => { + private async AuthLogin(provider): Promise { + try { + const userCredential = await this.afAuth.signInWithPopup(provider); + console.log(' AuthLogin'); + await this.SetUserData(userCredential); + this.ngZone.run(() => { + this.router.navigate(['/']); + }); + } catch (error) { + console.error(error); + } + return Promise.resolve(); + } - console.log('Entra en signInWithRedirect') + /** + * Si es la versión web esperamos una promesa por si se recibe los datos de un inicio de sesión + */ + public async AuthCheckLoginRedirect(): Promise { + if (!this.electronService.isElectronApp) { + const userCredential = await firebase.auth().getRedirectResult(); + if (userCredential.user !== null) { + console.log('Entra en getRedirectResult', userCredential); await this.SetUserData(userCredential); this.ngZone.run(() => { this.router.navigate(['/']); - }) - - }) - } - - public AuthCheckLoginRedirect(): Promise { - return new Promise(((resolve, reject) => { - // Si es la versión web esperamos una promesa por si se recibe los datos de un inicio de sesión - if (!this.electronService.isElectronApp) { - firebase.auth().getRedirectResult() - .then(async (userCredential) => { - if (userCredential.user !== null) { - console.log('Entra en getRedirectResult', userCredential) - await this.SetUserData(userCredential); - this.ngZone.run(() => { - this.router.navigate(['/']); - }) - } - resolve(true) - }) - } else { - reject("Error you can't login in electron app") + }); } - - })); + return Promise.resolve(true); + } else { + return Promise.reject("Error you can't login in electron app"); + } } /* Setting up user data when sign in with username/password, sign up with username/password and sign in with social auth provider in Firestore database using AngularFirestore + AngularFirestoreDocument service */ - SetUserData(userCredential: UserCredential) { + SetUserData(userCredential: UserCredential): any { const userRef: AngularFirestoreDocument = this.afs.doc(`users/${userCredential.user.uid}`); - const userData: User = { + const userData: InterfaceUser = { uid: userCredential.user.uid, email: userCredential.user.email, displayName: userCredential.user.displayName, photoURL: userCredential.user.photoURL, emailVerified: userCredential.user.emailVerified - } + }; return userRef.set(userData, { merge: true - }) + }); } // Sign out - SignOut() { - return this.afAuth.signOut().then( - async () => { - localStorage.removeItem('user'); - await this.router.navigate(['/login']); - } - ) + async SignOut() { + try { + await this.afAuth.signOut(); + localStorage.removeItem('user'); + await this.router.navigate(['/login']); + } catch (error) { + console.error(error); + } } } diff --git a/src/app/__core/machine/PixiJSGrid.ts b/src/app/__core/machine/PixiJSGrid.ts index 2667e22..26c9c39 100644 --- a/src/app/__core/machine/PixiJSGrid.ts +++ b/src/app/__core/machine/PixiJSGrid.ts @@ -35,6 +35,8 @@ export class PixiJSGrid extends PIXI.Graphics { _gridWidth; + private interactive: boolean; + /** * * @param {number} width number. Required. @@ -83,12 +85,13 @@ export class PixiJSGrid extends PIXI.Graphics { this.cellSize = cellSize; - const lConfig = { ...DEFAULT_LINE_STYLE, ...(lineConfig || {}) }; + const lConfig = {...DEFAULT_LINE_STYLE, ...(lineConfig || {})}; this.lineStyle(lConfig.width, lConfig.color, lConfig.alpha, lConfig.alignment, lConfig.native); // handle mouse move this.interactive = true; + /* this.on('mousemove', (evt) => { const mouseCoords = evt.data.global; // check if the mouse is within the bounds of this grid. If not, do nothing. @@ -105,22 +108,26 @@ export class PixiJSGrid extends PIXI.Graphics { this.onMousemove(evt, gridCoords); } }); + */ } /** * @param {number} cellSize number. Optional. default: the square root of the grid's side length */ - set cellSize(cellSize) { + // @ts-ignore + set cellSize(cellSize): void { this._cellSize = cellSize || Math.sqrt(this._correctedWidth); } - get cellSize() { + // @ts-ignore + get cellSize(): number { return this._cellSize; } /** * The amount of equally spaced lines along the grid's side. */ + // @ts-ignore get amtLines() { return Math.floor(this.gridWidth / this.cellSize); } @@ -128,6 +135,7 @@ export class PixiJSGrid extends PIXI.Graphics { /** * The requested width of the grid given by the `width` constructor parameter. */ + // @ts-ignore get originalWidth() { return this._gridWidth; } @@ -136,10 +144,12 @@ export class PixiJSGrid extends PIXI.Graphics { * The corrected width of the grid, which is the smallest square root number larger than * the corrected width. */ + // @ts-ignore get correctedWidth() { return this._correctedWidth; } + // @ts-ignore get useCorrectedWidth() { return this._useCorrectedWidth; } @@ -149,6 +159,7 @@ export class PixiJSGrid extends PIXI.Graphics { * @returns {{ x1: number, y1: number, x2: number, y2: number}} * The leftmost (**x1**), topmost (**y1**), rightmost (**x2**), and bottommost (**y2**) coordinates. */ + // @ts-ignore get bounds(): { x1: number, y1: number, x2: number, y2: number } { return { x1: this.x, @@ -158,10 +169,12 @@ export class PixiJSGrid extends PIXI.Graphics { }; } + // @ts-ignore set drawBoundaries(drawBoundaries) { this._drawBoundaries = drawBoundaries; } + // @ts-ignore get drawBoundaries() { return this._drawBoundaries; } @@ -171,6 +184,7 @@ export class PixiJSGrid extends PIXI.Graphics { * When the `cellSize` is not the default, the width of the grid will be the * width given in the `width` constructor. Otherwise, it is the corrected width. */ + // @ts-ignore get gridWidth() { if (!this.useCorrectedWidth) { return this._gridWidth; diff --git a/src/app/__core/machine/PixiJSTable.ts b/src/app/__core/machine/PixiJSTable.ts index c6817a8..0ebaa5d 100644 --- a/src/app/__core/machine/PixiJSTable.ts +++ b/src/app/__core/machine/PixiJSTable.ts @@ -1,6 +1,9 @@ import * as PIXI from 'pixi.js'; // Version 1.0.4 +interface InterfaceContainer extends PIXI.Container { + [key: string]: any; +} /** * Creates a new table that can have any PIXI.DisplayObject attached to it. The way to address updates is to use rows and cells. @@ -12,7 +15,7 @@ export class PixiJSTable extends PIXI.Container { private readonly title: PIXI.Text; - private readonly rows: any[] | PIXI.Container[]; + private readonly rows: InterfaceContainer[]; private rowBuffer: number; @@ -88,8 +91,8 @@ export class PixiJSTable extends PIXI.Container { const row = this.rows[this.rows.length - 1]; if (this.rowCount > 1) { row.position.set( - this.rowStartPosition.x, - this.rows[this.rows.length - 2].y + this.rows[this.rows.length - 2].height, + this.rowStartPosition.x, + this.rows[this.rows.length - 2].y + this.rows[this.rows.length - 2].height, ); } else { row.position.set(this.rowStartPosition.x, this.rowStartPosition.y); @@ -111,8 +114,8 @@ export class PixiJSTable extends PIXI.Container { const row = this.rows[rowNumber]; if (this.rowCount > 1) { row.position.set( - this.rowStartPosition.x, - this.rows[this.rows.length - 2].y + this.rows[this.rows.length - 2].height, + this.rowStartPosition.x, + this.rows[this.rows.length - 2].y + this.rows[this.rows.length - 2].height, ); } else { row.position.set(this.rowStartPosition.x, this.rowStartPosition.y); @@ -155,7 +158,7 @@ export class PixiJSTable extends PIXI.Container { * Deletes a row from the table by row ID. Redraws the entire object by creating a new one. * @param {*} rowNumber The row number to delete. */ - deleteRow(rowNumber) { + deleteRow(rowNumber: number) { this.debugLog('delete row', {rowNumber}); if (rowNumber > -1 && rowNumber < this.rowCount) { this.rows[rowNumber].destroy(true); @@ -187,8 +190,8 @@ export class PixiJSTable extends PIXI.Container { // check to see how long the array is. If it's length of 1, default to (5,5). if not, calculate. if (row.cells.length > 1) { cell.position.set( - row.cells[row.cells.length - 2].x + row.cells[row.cells.length - 2].width + this.columnBuffer, // default to 10 over for a 5 px spacing between cells - this.cellStartPosition.y, // default to 5 pixels from the top + row.cells[row.cells.length - 2].x + row.cells[row.cells.length - 2].width + this.columnBuffer, // default to 10 over for a 5 px spacing between cells + this.cellStartPosition.y, // default to 5 pixels from the top ); } else { cell.position.set(this.cellStartPosition.x, this.cellStartPosition.y); @@ -207,7 +210,7 @@ export class PixiJSTable extends PIXI.Container { * @param {*} rowNumber The row number * @param {*} cellNumber The cell number */ - deleteCell(rowNumber, cellNumber) { + deleteCell(rowNumber: number, cellNumber: number) { this.debugLog('delete cell', { rowNumber, cellNumber, @@ -265,9 +268,7 @@ export class PixiJSTable extends PIXI.Container { // add that to the previous entry, and you're good to go. this.rows.forEach((row, index) => { rowSeparation.push(0); - // @ts-ignore if (typeof row.cells !== 'undefined') { - // @ts-ignore row.cells.forEach((cell) => { if (cell.height + _inst.rowBuffer + rowSeparation[index] > rowSeparation[index + 1]) { rowSeparation[index + 1] = cell.height + _inst.rowBuffer + rowSeparation[index]; diff --git a/src/app/__core/machine/PixiTHUMDER_CycleClockDiagram.ts b/src/app/__core/machine/PixiTHUMDER_CycleClockDiagram.ts index c3711d6..c64989c 100644 --- a/src/app/__core/machine/PixiTHUMDER_CycleClockDiagram.ts +++ b/src/app/__core/machine/PixiTHUMDER_CycleClockDiagram.ts @@ -57,7 +57,7 @@ export type TypeArrowDirection = { export type TypeCellPosition = { instructionPosition: number, stepPosition: number -} +}; export type TypeCycleType = { IF?: number, @@ -88,23 +88,23 @@ class MyMap { } set(key: K, data: V) { - const k = JSON.stringify(key) + const k = JSON.stringify(key); this._map.set(k, data); } get(key: K) { - const k = JSON.stringify(key) + const k = JSON.stringify(key); return this._map.get(k); } has(key: K): boolean { - const k = JSON.stringify(key) - return this._map.has(k) + const k = JSON.stringify(key); + return this._map.has(k); } delete(key: K): boolean { - const k = JSON.stringify(key) - return this._map.delete(k) + const k = JSON.stringify(key); + return this._map.delete(k); } } @@ -164,11 +164,11 @@ export class PixiTHUMDER_CycleClockDiagram extends PIXI.Container { } set borderTopWidth(width: number) { - this.borderTop.width = width + this.borderTop.width = width; } set borderLeftHeight(height: number) { - this.borderLeft.height = height + this.borderLeft.height = height; } public reset() { @@ -298,7 +298,7 @@ export class PixiTHUMDER_CycleClockDiagram extends PIXI.Container { const start_y = initDistance_y + (arrowDirection.start.instruction * 37.5); const to_x = initDistance_x + (arrowDirection.to.step * 87.5); const to_y = initDistance_y + (arrowDirection.to.instruction * 37.5); - const bezierArrow = PixiUtils.drawArrow(start_x, start_y, to_x, to_y, color) + const bezierArrow = PixiUtils.drawArrow(start_x, start_y, to_x, to_y, color); this.arrows.addChild(bezierArrow); } @@ -356,7 +356,7 @@ export class PixiTHUMDER_CycleClockDiagram extends PIXI.Container { key = { instructionPosition: this.instructions, stepPosition: this.last - } + }; } if (code === '') { if (!this.timerVoid.has(key)) { diff --git a/src/app/__core/machine/PixiTHUMDER_Pipeline.ts b/src/app/__core/machine/PixiTHUMDER_Pipeline.ts index 035154f..19a69cc 100644 --- a/src/app/__core/machine/PixiTHUMDER_Pipeline.ts +++ b/src/app/__core/machine/PixiTHUMDER_Pipeline.ts @@ -1,11 +1,11 @@ -import * as PIXI from 'pixi.js' +import * as PIXI from 'pixi.js'; import { PixiUtils } from "./PixiUtils"; -export type ColorType = number +export type ColorType = number; export type CoordsType = { x: number, y: number -} +}; const styleFontTextPipe = new PIXI.TextStyle({ fontFamily: 'Arial', @@ -18,7 +18,7 @@ const styleFontTextPipe = new PIXI.TextStyle({ // dropShadowBlur: 4, // dropShadowAngle: Math.PI / 6, // dropShadowDistance: 6, -}) +}); const styleFontTextBox = new PIXI.TextStyle({ fontFamily: 'Arial', @@ -31,106 +31,106 @@ const styleFontTextBox = new PIXI.TextStyle({ // dropShadowBlur: 4, // dropShadowAngle: Math.PI / 6, // dropShadowDistance: 6, -}) +}); export class PixiTHUMDER_Pipeline extends PIXI.Container { - private readonly InstStages_text: PIXI.Text - private readonly IF_text: PIXI.Text - private readonly ID_text: PIXI.Text - private readonly intEX_text: PIXI.Text + private readonly InstStages_text: PIXI.Text; + private readonly IF_text: PIXI.Text; + private readonly ID_text: PIXI.Text; + private readonly intEX_text: PIXI.Text; - private readonly faddEX_array: Array - private readonly fmultEX_array: Array - private readonly fdivEX_array: Array + private readonly faddEX_array: Array; + private readonly fmultEX_array: Array; + private readonly fdivEX_array: Array; - private readonly MEM_text: PIXI.Text - private readonly WB_text: PIXI.Text + private readonly MEM_text: PIXI.Text; + private readonly WB_text: PIXI.Text; private readonly faddEX_count; private readonly fmultEX_count; private readonly fdivEX_count; constructor(faddEX_count = 1, fmultEX_count = 1, fdivEX_count = 1) { - super() - this.InstStages_text = new PIXI.Text("Inst-Stages") - this.IF_text = new PIXI.Text("", styleFontTextBox) - this.ID_text = new PIXI.Text("", styleFontTextBox) - this.intEX_text = new PIXI.Text("", styleFontTextBox) - this.MEM_text = new PIXI.Text("", styleFontTextBox) - this.WB_text = new PIXI.Text("", styleFontTextBox) - - this.faddEX_count = faddEX_count - this.fmultEX_count = fmultEX_count - this.fdivEX_count = fdivEX_count - this.faddEX_array = new Array(this.faddEX_count) + super(); + this.InstStages_text = new PIXI.Text("Inst-Stages"); + this.IF_text = new PIXI.Text("", styleFontTextBox); + this.ID_text = new PIXI.Text("", styleFontTextBox); + this.intEX_text = new PIXI.Text("", styleFontTextBox); + this.MEM_text = new PIXI.Text("", styleFontTextBox); + this.WB_text = new PIXI.Text("", styleFontTextBox); + + this.faddEX_count = faddEX_count; + this.fmultEX_count = fmultEX_count; + this.fdivEX_count = fdivEX_count; + this.faddEX_array = new Array(this.faddEX_count); for (let i = 0; i < this.faddEX_count; i++) { - this.faddEX_array[i] = new PIXI.Text("", styleFontTextBox) + this.faddEX_array[i] = new PIXI.Text("", styleFontTextBox); } - this.fmultEX_array = new Array(this.fmultEX_count) + this.fmultEX_array = new Array(this.fmultEX_count); for (let i = 0; i < this.fmultEX_count; i++) { - this.fmultEX_array[i] = new PIXI.Text("", styleFontTextBox) + this.fmultEX_array[i] = new PIXI.Text("", styleFontTextBox); } - this.fdivEX_array = new Array(this.fdivEX_count) + this.fdivEX_array = new Array(this.fdivEX_count); for (let i = 0; i < this.fdivEX_count; i++) { - this.fdivEX_array[i] = new PIXI.Text("", styleFontTextBox) + this.fdivEX_array[i] = new PIXI.Text("", styleFontTextBox); } - this.initBoxes() - this.initArrows() - this.initTexts() + this.initBoxes(); + this.initArrows(); + this.initTexts(); } private initTexts() { - this.InstStages_text.position.x = 175 - (this.InstStages_text.width) / 2 - this.InstStages_text.position.y = 20 - this.addChild(this.InstStages_text) + this.InstStages_text.position.x = 175 - (this.InstStages_text.width) / 2; + this.InstStages_text.position.y = 20; + this.addChild(this.InstStages_text); this.drawText(this.IF_text, { x: 100 + 5, y: 100 - }) + }); this.drawText(this.ID_text, { x: 100 + 5, y: 200 - }) + }); this.drawText(this.intEX_text, { x: 100 + 5, y: 300 - }) + }); this.drawText(this.MEM_text, { x: 100 + 5, y: 400 - }) + }); this.drawText(this.WB_text, { x: 100 + 5, y: 500 - }) + }); for (let i = 0; i < this.faddEX_count; i++) { this.drawText(this.faddEX_array[i], { x: 400 + 5, y: 100 + (i * 100) - }) + }); } for (let i = 0; i < this.fmultEX_count; i++) { this.drawText(this.fmultEX_array[i], { x: 650 + 5, y: 100 + (i * 100) - }) + }); } for (let i = 0; i < this.fdivEX_count; i++) { this.drawText(this.fdivEX_array[i], { x: 900 + 5, y: 100 + (i * 100) - }) + }); } } private drawText(object: PIXI.Text, coords: CoordsType) { - object.position.x = coords.x - object.position.y = coords.y - object.zIndex = 2 - this.addChild(object) + object.position.x = coords.x; + object.position.y = coords.y; + object.zIndex = 2; + this.addChild(object); } private initArrows() { @@ -141,7 +141,7 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 175, y: 100 - }) + }); // ID this.drawArrow({ x: 175, @@ -149,7 +149,7 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 175, y: 200 - }) + }); // intEX this.drawArrow({ x: 175, @@ -157,7 +157,7 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 175, y: 300 - }) + }); // MEM this.drawArrow({ x: 175, @@ -165,7 +165,7 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 175, y: 400 - }) + }); // WB this.drawArrow({ x: 175, @@ -173,14 +173,14 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 175, y: 500 - }) + }); this.drawArrow({ x: 175, y: 525 }, { x: 175, y: 600 - }) + }); // Lines this.drawLine({ @@ -189,21 +189,21 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 300, y: 275 - }) + }); this.drawLine({ x: 300, y: 275 }, { x: 300, y: 50 - }) + }); this.drawLine({ x: 300, y: 50 }, { x: 975, y: 50 - }) + }); // input faddEX, fmultEX, fdivEX this.drawArrow({ @@ -212,21 +212,21 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 400 + 75, y: 100 - }) + }); this.drawArrow({ x: 650 + 75, y: 50 }, { x: 650 + 75, y: 100 - }) + }); this.drawArrow({ x: 900 + 75, y: 50 }, { x: 900 + 75, y: 100 - }) + }); // output faddEX, fmultEX, fdivEX this.drawArrow({ @@ -235,21 +235,21 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 400 + 75, y: 900 - }) + }); this.drawArrow({ x: 650 + 75, y: 125 }, { x: 650 + 75, y: 900 - }) + }); this.drawArrow({ x: 900 + 75, y: 125 }, { x: 900 + 75, y: 900 - }) + }); // faddEX, fmultEX, fdivEX to MEM this.drawLine({ @@ -258,14 +258,14 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 300, y: 900 - }) + }); this.drawLine({ x: 300, y: 900 }, { x: 300, y: 375 - }) + }); this.drawArrow({ x: 300, @@ -273,131 +273,131 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { }, { x: 175, y: 375 - }) + }); } private initBoxes() { this.drawBox(0xFFFF00, { x: 100, y: 100 - }, "IF") + }, "IF"); this.drawBox(0XFFA200, { x: 100, y: 200 - }, "ID") + }, "ID"); this.drawBox(0XFF001C, { x: 100, y: 300 - }, "intEX") + }, "intEX"); this.drawBox(0x00FF00, { x: 100, y: 400 - }, "MEM") + }, "MEM"); this.drawBox(0XA2A2FF, { x: 100, y: 500 - }, "WB") + }, "WB"); for (let i = 0; i < this.faddEX_count; i++) { this.drawBox(0XFFC3FF, { x: 400, y: 100 + (i * 100) - }, "faddEX[" + i + "]") + }, "faddEX[" + i + "]"); } for (let i = 0; i < this.fmultEX_count; i++) { this.drawBox(0XC3FFC3, { x: 650, y: 100 + (i * 100) - }, "fmultEX[" + i + "]") + }, "fmultEX[" + i + "]"); } for (let i = 0; i < this.fdivEX_count; i++) { this.drawBox(0XFFCB8E, { x: 900, y: 100 + (i * 100) - }, "fdivEX[" + i + "]") + }, "fdivEX[" + i + "]"); } } private drawBox(color: ColorType, positionStart: CoordsType, text: string) { - const rectangle = new PIXI.Graphics() - rectangle.lineStyle(2, 0x002200, 1) - rectangle.beginFill(color) - rectangle.drawRect(positionStart.x, positionStart.y, 150, 50) - rectangle.endFill() - rectangle.zIndex = 1 - - const pixi_text = new PIXI.Text(text, styleFontTextPipe) - pixi_text.position.x = (positionStart.x - (pixi_text.width + 10)) - pixi_text.position.y = (positionStart.y) - rectangle.addChild(pixi_text) - this.addChild(rectangle) + const rectangle = new PIXI.Graphics(); + rectangle.lineStyle(2, 0x002200, 1); + rectangle.beginFill(color); + rectangle.drawRect(positionStart.x, positionStart.y, 150, 50); + rectangle.endFill(); + rectangle.zIndex = 1; + + const pixi_text = new PIXI.Text(text, styleFontTextPipe); + pixi_text.position.x = (positionStart.x - (pixi_text.width + 10)); + pixi_text.position.y = (positionStart.y); + rectangle.addChild(pixi_text); + this.addChild(rectangle); } private drawLine(from: CoordsType, to: CoordsType) { - const start_x = from.x - const start_y = from.y - const to_x = to.x - const to_y = to.y - const bezierArrow = new PIXI.Graphics() - bezierArrow.lineStyle(2, 0x000000) - bezierArrow.moveTo(start_x, start_y) - bezierArrow.lineTo(to_x, to_y) - - this.addChild(bezierArrow) + const start_x = from.x; + const start_y = from.y; + const to_x = to.x; + const to_y = to.y; + const bezierArrow = new PIXI.Graphics(); + bezierArrow.lineStyle(2, 0x000000); + bezierArrow.moveTo(start_x, start_y); + bezierArrow.lineTo(to_x, to_y); + + this.addChild(bezierArrow); } private drawArrow(from: CoordsType, to: CoordsType) { - const start_x = from.x - const start_y = from.y - const to_x = to.x - const to_y = to.y - const bezierArrow = PixiUtils.drawArrow(start_x, start_y, to_x, to_y, 0x000000) - this.addChild(bezierArrow) + const start_x = from.x; + const start_y = from.y; + const to_x = to.x; + const to_y = to.y; + const bezierArrow = PixiUtils.drawArrow(start_x, start_y, to_x, to_y, 0x000000); + this.addChild(bezierArrow); } public update_IF_text(value: string): void { - this.IF_text.text = value + this.IF_text.text = value; } public update_ID_text(value: string): void { - this.ID_text.text = value + this.ID_text.text = value; } public update_intEX_text(value: string): void { - this.intEX_text.text = value + this.intEX_text.text = value; } public update_faddEX_text(unit: number, value: string): void { if (this.faddEX_count > unit) - this.faddEX_array[unit].text = value + this.faddEX_array[unit].text = value; } public update_fmultEX_text(unit: number, value: string): void { if (this.fmultEX_count > unit) - this.fmultEX_array[unit].text = value + this.fmultEX_array[unit].text = value; } public update_fdivEX_text(unit: number, value: string): void { if (this.fdivEX_count > unit) - this.fdivEX_array[unit].text = value + this.fdivEX_array[unit].text = value; } public update_MEM_text(value: string): void { - this.MEM_text.text = value + this.MEM_text.text = value; } public update_WB_text(value: string): void { - this.WB_text.text = value + this.WB_text.text = value; } public draw(): PIXI.Container { - return this + return this; } public toString(): string { - const faddEX_array = this.faddEX_array.map(v => v.text) - const fmultEX_array = this.fmultEX_array.map(v => v.text) - const fdivEX_array = this.fdivEX_array.map(v => v.text) + const faddEX_array = this.faddEX_array.map(v => v.text); + const fmultEX_array = this.fmultEX_array.map(v => v.text); + const fdivEX_array = this.fdivEX_array.map(v => v.text); return JSON.stringify({ "IF_text": this.IF_text.text, "ID_text": this.ID_text.text, @@ -407,6 +407,6 @@ export class PixiTHUMDER_Pipeline extends PIXI.Container { "faddEX_array": faddEX_array, "fmultEX_array": fmultEX_array, "fdivEX_array": fdivEX_array, - }) + }); } } diff --git a/src/app/__core/machine/PixiUtils.ts b/src/app/__core/machine/PixiUtils.ts index 404b84d..4b596c7 100644 --- a/src/app/__core/machine/PixiUtils.ts +++ b/src/app/__core/machine/PixiUtils.ts @@ -1,13 +1,13 @@ import * as PIXI from "pixi.js"; export namespace PixiUtils { - export function getRandomInt(min, max): number { + export function getRandomInt(min: number, max: number): number { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } - export function getAngleTo(mx, my, px, py) { + export function getAngleTo(mx: number, my: number, px: number, py: number): number { // var self = that; const distX = my - py; const distY = mx - px; @@ -16,11 +16,11 @@ export namespace PixiUtils { // const degrees = angle * 180/ Math.PI; } - export function getAngleX(length, angle) { + export function getAngleX(length: number, angle: number): number { return Math.cos(angle) * length; } - export function getAngleY(length, angle) { + export function getAngleY(length: number, angle: number): number { return Math.sin(angle) * length; } diff --git a/src/app/__core/machine/debugger/BreakpointManager.ts b/src/app/__core/machine/debugger/BreakpointManager.ts new file mode 100644 index 0000000..60ef3db --- /dev/null +++ b/src/app/__core/machine/debugger/BreakpointManager.ts @@ -0,0 +1,47 @@ +import { TypeBreakpoints } from "../../../components/monaco-editor/monaco-editor.component"; + +export class BreakpointManager { + // Line numbers are 1-indexed + private breakpoints: TypeBreakpoints = {}; + + public toggleBreakpoint(lineNumber: number): void { + if (lineNumber in this.breakpoints) { + delete this.breakpoints[lineNumber]; + } else { + this.breakpoints[lineNumber] = true; + } + console.log('enabled', lineNumber, this.breakpoints[lineNumber]); + } + + public getBreakpoint(lineNumber: number): boolean | null { + if (lineNumber in this.breakpoints) { + return this.breakpoints[lineNumber]; + } else { + return null; + } + } + + public updateManager(breakpoints: TypeBreakpoints): void { + this.breakpoints = {}; + for (const [line, enabled] of Object.entries(breakpoints)) { + this.breakpoints[line] = enabled; + } + } + + public getAllBreakpoints(): TypeBreakpoints { + return this.breakpoints; + } + + public getAllLinesOfBreakpoints(): number[] { + return Object.keys(this.breakpoints).map(k => parseInt(k)); + } + + public isBreakpoint(line: number): boolean { + return this.breakpoints[line] ?? false; + } + + public clear(): void { + this.breakpoints = {}; + } + +} diff --git a/src/app/__core/machine/machine.service.ts b/src/app/__core/machine/machine.service.ts index 7d5120d..13b228e 100644 --- a/src/app/__core/machine/machine.service.ts +++ b/src/app/__core/machine/machine.service.ts @@ -6,7 +6,7 @@ import { interval, Observable, PartialObserver, Subject } from "rxjs"; import { takeUntil } from "rxjs/operators"; import { SimulationResponse, - StepSimulation, + TypeStepSimulation, TypeCode, TypeDataStatistics, TypeFloatingPointStageConfiguration, TypeRegister, @@ -28,6 +28,10 @@ import { Utils } from "../../Utils"; import { StorageService } from "../storage/storage.service"; import { Registers } from "../DLX/_Registers"; import { Memory } from "../DLX/_Memory"; +import { BreakpointManager } from "./debugger/BreakpointManager"; +import { ToastrService } from "ngx-toastr"; +import { TranslateService } from "@ngx-translate/core"; +import { IndividualConfig } from "ngx-toastr/toastr/toastr-config"; const RegexRegisterInteger = /\b(R0|R1|R2|R3|R4|R5|R6|R7|R8|R9|R10|R11|R12|R13|R14|R15|R16|R17|R18|R19|R20|R21|R22|R23|R24|R25|R26|R27|R28|R29|R30|R31)\b/i; @@ -43,41 +47,43 @@ export class MachineService { public memorySize; public floatingPointStageConfiguration: TypeFloatingPointStageConfiguration; public registers: Registers; + public breakpointManager: BreakpointManager; // La memoria se organiza de directions de 4 bits en 4 bits public memory: Memory; - + public logger: string = ""; // address --> TypeTableCode public code: Map = new Map(); - public codeText = ''; - - public tagsDebugger: TypeTags = []; - - // public memory: Array = Array(32764).fill(new Int32()); - // public code: Array = Array(32764).fill(new Int32()); - // public pipeline: PixiTHUMER_Pipeline; - // public cycleClockDiagram: PixiTHUMDER_CycleClockDiagram; - // public pipeline: PixiTHUMDER_Pipeline; // Vector con los pasos de la simulación private simulation: SimulationResponse; - + private statusMachineInStep: TypeStepSimulation | null; public dataCodeArray; - public codeSimulation$ = new Subject(); - public stepSimulation$ = new Subject(); - public dataStatistics$ = new Subject(); - public step$ = new Subject(); + + // Line + public isBreakpoint$: Subject = new Subject(); + public codeSimulation$: Subject = new Subject(); + public stepSimulation$: Subject = new Subject(); + public dataStatistics$: Subject = new Subject(); private dataStatistics: TypeDataStatistics = Utils.clone(DEFAULT_DATA_STATISTICS); + + private privateStep = 0; + private privateLine = 0; private timer: Observable; private readonly timerObserver: PartialObserver; - stopClick$ = new Subject(); - pauseClick$ = new Subject(); + public step$: Subject = new Subject(); + public line$: Subject = new Subject(); + + // stopClick$ = new Subject(); + isRunning$ = new Subject(); + isComplete$ = new Subject(); // Por defecto parado y sin completar - isRunning = false; - isComplete = false; + isRunning: boolean = false; + isComplete: boolean = false; + isBreakpoint: boolean = false; // 20 de septiembre: Me quiero morir, este código es una locura y no sé hacerlo bonito y entendible por que no @@ -86,8 +92,12 @@ export class MachineService { // 05 de octubre: Nono del pasado sigues siendo un cabron // 15 de octubre: Nono, lo has mejorado un poquito, pero sigues siendo un cabron // 22 de octubre: Nono tienes que poner ahora las tags del debugger 😂 + // 7 de noviembre: Nono haz lo que puedas cuando puedas :3 + // 21 de noviembre: Nono haz las tags y el guardar ficheros pls // https://stackblitz.com/edit/angular-play-pause-timer - constructor(private store: StorageService) { + constructor(private store: StorageService, + private translate: TranslateService, + private toast: ToastrService) { this.floatingPointStageConfiguration = this.store.getItem('floating_point_stage_configuration'); // this.pipeline = new PixiTHUMER_Pipeline( // this.floatingPointStageConfiguration.addition.count, @@ -98,37 +108,42 @@ export class MachineService { this.memorySize = this.store.getItem('memory_size'); this.memory = new Memory(this.memorySize); this.registers = new Registers(); - // this.cycleClockDiagram = new PixiTHUMDER_CycleClockDiagram(); - // this.pipeline = new PixiTHUMDER_CycleClockDiagram(); - // this.registers.D[0].value = 3.14 + this.breakpointManager = new BreakpointManager(); - this.timer = interval(250).pipe( - takeUntil(this.pauseClick$), - takeUntil(this.stopClick$) + this.privateStep = 0; + this.privateLine = 0; + + const timeSimulation = this.store.getItem('time_simulation'); + this.timer = interval(timeSimulation).pipe( + takeUntil(this.isRunning$), + takeUntil(this.isComplete$), ); this.timerObserver = { - next: (_: number) => { - this.log(new Date().getSeconds()) - if (this.isRunning) { - this.checkConditions(); - this.clock(); - this.privateStep++; - } else { - this.stopClick$.next(); - // this.isRunning = false; - // this.isComplete = true; + next: async (_: number): Promise => { + if (this.isRunning === true) { + await this.nextStep(); } + return Promise.resolve(); } }; - - this.timer.subscribe(this.timerObserver); } // TODO - public resetMachineStatus(): Promise { - return new Promise(async (resolve) => { - this.log("RESET") + public async resetMachineStatus(): Promise { + try { + await this.toastMessage('TOAST.TITLE_RESET_MACHINE', 'TOAST.MESSAGE_RESET_MACHINE'); + this.log("RESET"); + + this.memorySize = this.store.getItem('memory_size'); + this.memory = new Memory(this.memorySize); + + this.registers = new Registers(); + + this.breakpointManager = new BreakpointManager(); + const breakpointsSaved = JSON.parse(localStorage.getItem('breakpoints')); + this.breakpointManager.updateManager(breakpointsSaved); + this.floatingPointStageConfiguration = this.store.getItem('floating_point_stage_configuration'); // this.pipeline = new PixiTHUMER_Pipeline( // this.floatingPointStageConfiguration.addition.count, @@ -138,11 +153,9 @@ export class MachineService { // this.cycleClockDiagram = new PixiTHUMDER_CycleClockDiagram(); // this.pipeline = new PixiTHUMDER_Pipeline(); - this.memorySize = this.store.getItem('memory_size'); - this.memory = new Memory(this.memorySize); - this.registers = new Registers(); - this.privateStep = 0; + this.privateLine = 0; + this.dataStatistics = Utils.clone(DEFAULT_DATA_STATISTICS); this.dataStatistics$.next(this.dataStatistics); @@ -150,19 +163,36 @@ export class MachineService { this.code.clear(); this.isComplete = false; this.isRunning = false; - this.stopClick$.next(); + this.isBreakpoint = false; - await this.loadExamples(); + const timeSimulation = this.store.getItem('time_simulation'); + this.timer = null; + this.timer = interval(timeSimulation).pipe( + takeUntil(this.isRunning$), + takeUntil(this.isComplete$), + ); - resolve(true); - }) + await this.loadExamples(); + return Promise.resolve(true); + } catch (error) { + console.error(error); + return Promise.reject(error); + } } public getStepObservable(): Observable { return this.step$.asObservable(); } - public getStepSimulationObservable(): Observable { + public getLineObservable(): Observable { + return this.line$.asObservable(); + } + + public getIsRunningObservable(): Observable { + return this.isRunning$.asObservable(); + } + + public getStepSimulationObservable(): Observable { return this.stepSimulation$.asObservable(); } @@ -170,11 +200,16 @@ export class MachineService { return this.codeSimulation$.asObservable(); } + // line + public getDebuggerObservable(): Observable { + return this.isBreakpoint$.asObservable(); + } + public getDataStatisticsObservable(): Observable { return this.dataStatistics$.asObservable(); } - getStatusCycleClockDiagram(stepSimulation: StepSimulation): TypeStatusCycleClockDiagram { + public getStatusCycleClockDiagram(stepSimulation: TypeStepSimulation): TypeStatusCycleClockDiagram { return { step: stepSimulation.step, instruction: stepSimulation.instruction, @@ -194,214 +229,228 @@ export class MachineService { }; } - getListStatusPipeline(stepSimulation: StepSimulation): TypeStatusPipeline[] { + public getListStatusPipeline(stepSimulation: TypeStepSimulation): TypeStatusPipeline[] { const {IF, ID, intEX, MEM, WB} = stepSimulation.pipeline; - let list_elements: TypeStatusPipeline[] = [ - {address: IF, stage: 'IF'}, - {address: ID, stage: 'ID'}, - {address: intEX, stage: 'intEX'}, - {address: MEM, stage: 'MEM'}, - {address: WB, stage: 'WB'} - ] + const list_elements: TypeStatusPipeline[] = []; + + if (IF) list_elements.push({address: IF, stage: 'IF'}); + if (ID) list_elements.push({address: ID, stage: 'ID'}); + if (intEX) list_elements.push({address: intEX, stage: 'intEX'}); + if (MEM) list_elements.push({address: MEM, stage: 'MEM'}); + if (WB) list_elements.push({address: WB, stage: 'WB'}); + for (const f_a of stepSimulation.pipeline.faddEX) { - list_elements.push({address: f_a.address, stage: `faddEX_${f_a.unit}` as TypeStage, unit: f_a.unit}) + list_elements.push({address: f_a.address, stage: `faddEX_${f_a.unit}` as TypeStage, unit: f_a.unit}); } for (const f_m of stepSimulation.pipeline.fmultEX) { - list_elements.push({address: f_m.address, stage: `fmultEX_${f_m.unit}` as TypeStage, unit: f_m.unit}) + list_elements.push({address: f_m.address, stage: `fmultEX_${f_m.unit}` as TypeStage, unit: f_m.unit}); } for (const f_d of stepSimulation.pipeline.fdivEX) { - list_elements.push({address: f_d.address, stage: `fdivEX_${f_d.unit}` as TypeStage, unit: f_d.unit}) + list_elements.push({address: f_d.address, stage: `fdivEX_${f_d.unit}` as TypeStage, unit: f_d.unit}); } return list_elements; } // Navbar - async play(): Promise { - return new Promise((resolve) => { - resolve(); - }) + + public async play(): Promise { + return Promise.resolve(); } - async reset(): Promise { - return new Promise((resolve) => { - this.resetMachineStatus() - resolve(); - }) + public async reset(): Promise { + await this.resetMachineStatus(); + return Promise.resolve(); } - async pause(): Promise { - return new Promise(resolve => { - this.pauseClick$.next(); - this.isRunning = false; - resolve(); - }) + public async pause(): Promise { + this.isRunning = false; + this.isRunning$.next(this.isRunning); + return Promise.resolve(); } - async resume(): Promise { - return new Promise(resolve => { - this.isRunning = true; - if (this.isComplete) { - this.isComplete = false; - } - this.timer.subscribe(this.timerObserver); - resolve(); - }) + public async resume(): Promise { + if (this.isComplete) { + // this.isComplete = false; + console.warn("this.isComplete, can't resume"); + return Promise.resolve(); + } + + this.isBreakpoint = false; + this.isRunning = true; + this.isRunning$.next(this.isRunning); + + this.timer.subscribe(this.timerObserver); + return Promise.resolve(); + } + + public async nextStep(): Promise { + this.statusMachineInStep = await MachineService.getStepInRunner(this.privateStep); + + const canNextInstruction = await this.checkConditions(); + if (canNextInstruction) await this.clock(); + + this.privateLine++; + this.privateStep++; + return Promise.resolve(); } - async next(): Promise { - return new Promise(resolve => { - this.checkConditions(); - this.clock(); - this.privateStep++; - resolve(); - }) + public async end(): Promise { + this.privateStep = -1; + this.isRunning = false; + this.isComplete = true; + + this.isRunning$.next(this.isRunning); + return Promise.resolve(); } - async end(): Promise { - return new Promise(resolve => { - this.privateStep = -1; + private async checkConditions(): Promise { + if (this.statusMachineInStep === null) { + console.warn('End of status of machine'); + return Promise.resolve(false); + } + this.privateStep = this.statusMachineInStep.step; + this.privateLine = this.statusMachineInStep.line; + this.isComplete = this.statusMachineInStep.isComplete ?? false; + this.isBreakpoint = this.breakpointManager.isBreakpoint(this.privateLine); + console.debug(this.debug()); - this.stopClick$.next(); - this.isRunning = false; + if (this.isComplete) { this.isComplete = true; - resolve(); - }) + this.isRunning = false; + this.isRunning$.next(this.isRunning); + await this.toastMessage('TOAST.TITLE_END_SIMULATION', 'TOAST.MESSAGE_END_SIMULATION'); + return Promise.resolve(false); + } + + if (this.isBreakpoint) { + this.line$.next(this.privateLine); + this.isRunning = false; + this.isRunning$.next(this.isRunning); + this.isBreakpoint$.next(this.privateLine); + await this.toastMessage('TOAST.TITLE_BREAKPOINT_SIMULATION', 'TOAST.MESSAGE_BREAKPOINT_SIMULATION'); + return Promise.resolve(false); + } + + if (this.isComplete === false && this.isBreakpoint === false) { + return Promise.resolve(true); + } + + return Promise.resolve(false); } - clock(): any { - if (this.isRunning === false) { - return; + private async clock(): Promise { + if (this.isComplete === true) { + console.warn('isComplete', this.isComplete); + return Promise.resolve(); } - const statusMachineInStep = this.getStepInRunner(this.privateStep); - this.step$.next(this.privateStep); - this.stepSimulation$.next(statusMachineInStep) - const instructionText = statusMachineInStep.instruction; - // this.cycleClockDiagram.addInstruction(instructionText); - // this.cycleClockDiagram.goToStep(this.privateStep); - - if (statusMachineInStep.registers !== []) { - for (const register_value of statusMachineInStep.registers) { - const register = register_value.register - let value, binary; + + if (this.statusMachineInStep.registers !== []) { + for (const register_value of this.statusMachineInStep.registers) { + const register = register_value.register; + let binary; if (RegexRegisterInteger.test(register)) { const r: number = MachineService.getRegisterNumber(register); - value = Utils.hexadecimalToDecimal(register_value.value) - binary = Utils.hexadecimalToBinary(register_value.value) + binary = Utils.hexadecimalToBinary(register_value.value); this.registers.R[r] = new Int32(); - // this.registers.R[r].value = value; this.registers.R[r].binary = binary; } else if (RegexRegisterFloat.test(register)) { const f: number = MachineService.getRegisterNumber(register); - value = Utils.hexadecimalToDecimal(register_value.value) - binary = Utils.hexadecimalToBinary(register_value.value) + binary = Utils.hexadecimalToBinary(register_value.value); this.registers.F[f] = new Float32(); - // this.registers.F[f].value = value; this.registers.F[f].binary = binary; } else if (RegexRegisterDouble.test(register)) { const d: number = MachineService.getRegisterNumber(register); - value = Utils.hexadecimalToDecimal(register_value.value) - binary = Utils.hexadecimalToBinary(register_value.value, {maxLength: 64, fillString: '0'}) + binary = Utils.hexadecimalToBinary(register_value.value, {maxLength: 64, fillString: '0'}); this.registers.F[d] = new Float32(); - // this.registers.D[d].value = value; this.registers.F[d].binary = binary.substr(0, 32); this.registers.F[d + 1].binary = binary.substr(32, 32); } else if (RegexRegisterControl.test(register)) { - value = Utils.hexadecimalToDecimal(register_value.value) - binary = Utils.hexadecimalToBinary(register_value.value) + binary = Utils.hexadecimalToBinary(register_value.value); this.registers[register] = new Int32(); - // this.registers[register].value = value; this.registers[register].binary = binary; } - this.log('Registro: ', register, 'con valor', value, 'de la instrucción', instructionText) + // this.log('Registro: ', register, 'con valor', value, 'de la instrucción', instructionText); } } - if (statusMachineInStep.memory !== []) { - for (const memory_value of statusMachineInStep.memory) { + if (this.statusMachineInStep.memory !== []) { + for (const memory_value of this.statusMachineInStep.memory) { const address = memory_value.address; - const value = memory_value.value; - const data = new Int32(); - data.binary = parseInt(memory_value.value).toString(2).padStart(32, '0'); - this.memory.setMemoryWordByAddress(address, data); - this.log('Dirección: ', address, 'con valor', value, 'de la instrucción', instructionText) + const typeData = memory_value.typeData ?? "word"; + switch (typeData) { + case "byte": { + const binary08 = Utils.hexadecimalToBinary(memory_value.value); + this.memory.setMemoryByteBinaryByAddress(address, binary08); + break; + } + case "halfword": { + const binary16 = Utils.hexadecimalToBinary(memory_value.value); + this.memory.setMemoryHalfWordBinaryByAddress(address, binary16); + break; + } + case "word": { + const binary32 = Utils.hexadecimalToBinary(memory_value.value); + this.memory.setMemoryWordBinaryByAddress(address, binary32); + break; + } + case "float": { + const binary08 = Utils.hexadecimalToBinary(memory_value.value); + this.memory.setMemoryFloatBinaryByAddress(address, binary08); + break; + } + case "double": { + const binary64 = Utils.hexadecimalToBinary(memory_value.value); + this.memory.setMemoryDoubleBinaryByAddress(address, binary64); + break; + } + } + // this.log('Dirección: ', address, 'con valor', value, 'de la instrucción', instructionText); } } - // const {IF, ID, intEX, faddEX, fmultEX, fdivEX, MEM, WB} = statusMachineInStep.pipeline; - // - // const data_code_IF = this.code.get(IF) ?? DEFAULT_TABLE_CODE - // const data_code_ID = this.code.get(ID) ?? DEFAULT_TABLE_CODE - // const data_code_intEX = this.code.get(intEX) ?? DEFAULT_TABLE_CODE - // const data_code_MEM = this.code.get(MEM) ?? DEFAULT_TABLE_CODE - // const data_code_WB = this.code.get(WB) ?? DEFAULT_TABLE_CODE - // - // this.pipeline.update_IF_text(data_code_IF.instruction); - // this.pipeline.update_ID_text(data_code_ID.instruction); - // this.pipeline.update_intEX_text(data_code_intEX.instruction); - // this.pipeline.update_MEM_text(data_code_MEM.instruction); - // this.pipeline.update_WB_text(data_code_WB.instruction); - // - // for (const unit_value of faddEX) { - // const {instruction: faddEX_i} = this.code.get(unit_value.address) - // this.pipeline.update_faddEX_text(unit_value.unit, faddEX_i); - // } - // for (const unit_value of fmultEX) { - // const {instruction: fmultEX_i} = this.code.get(unit_value.address) - // this.pipeline.update_fmultEX_text(unit_value.unit, fmultEX_i); - // } - // for (const unit_value of fdivEX) { - // const {instruction: fdivEX_i} = this.code.get(unit_value.address) - // this.pipeline.update_fdivEX_text(unit_value.unit, fdivEX_i); - // } - - console.log("END") this.dataStatistics.TOTAL.ID_EXECUTED.instructions++; this.dataStatistics$.next(this.dataStatistics); - } - - private checkConditions() { - if (this.privateStep > this.simulation.steps) { - this.isComplete = true; - this.isRunning = false; - } + this.stepSimulation$.next(this.statusMachineInStep); + this.step$.next(this.privateStep); + this.line$.next(this.privateLine); + + /** + const message = "PrivateLine: " + this.privateLine.toString(); + const title = "CLOCK"; + await this.toastMessage(message, title); + */ + return Promise.resolve(); } private static getRegisterNumber(str): number { return parseInt(str.replace(/\D/g, '')); } - private log(...msg) { - console.log(this.privateStep, ...msg) + private log(...msg: any) { + console.debug('Line :', this.privateLine, 'Step: ', this.privateStep, msg); + this.logger = Utils.stringFormat("Private step: {0} \r\n", [this.privateStep, ...msg]); } - /** - * DEFAULT STEP - * - * @param step - * @private - */ - private getStepInRunner(step: number): StepSimulation { - const status = this.simulation.runner.filter((value) => value.step === step)[0]; + private static async getStepInRunner(step: number): Promise { + const response = await fetch('./assets/examples-dlx/prime.s/run_' + step + '.json'); + const status: TypeStepSimulation = await response.json(); + //const status = this.simulation.runner.filter((value) => value.step === step)[0]; if (status === undefined) { console.error('No hay nada que simular'); - return; + return Promise.reject('No hay nada que simular'); } else { if (status.pipeline === undefined) { status.pipeline = DEFAULT_PIPELINE; } - return status; + return Promise.resolve(status); } } - - /** - * - */ public getMemory(index: number): Int32 { if (this.memory.getMemoryWordByIndex(index) === undefined) { this.memory.setMemoryWordByIndex(index, new Int32()); } - return this.memory.getMemoryWordByIndex(index) + return this.memory.getMemoryWordByIndex(index); } public getRegister(index: TypeRegisterToEdit, typeRegister: TypeRegister): Int32 | Float32 | Double64 { @@ -436,7 +485,7 @@ export class MachineService { public getTableCode(address: string): TypeTableCode { if (this.code.get(address) === undefined) { - console.warn("Error, dirección de memoria erronea") + console.warn("Error, dirección de memoria erronea '%s' | %o", address, this.code.get(address)); return DEFAULT_TABLE_CODE; } return this.code.get(address); @@ -449,7 +498,7 @@ export class MachineService { getBinaryOfMemory_HalfWord(address: number, module: 0 | 1): string { const binary = this.getMemory(address).binary.padStart(32, '0'); - return binary.substr(16 * module, 16) + return binary.substr(16 * module, 16); } getBinaryOfMemory_Word(address: number): string { @@ -465,40 +514,73 @@ export class MachineService { if (part1 === DEFAULT_BINARY_32_BITS) { return DEFAULT_BINARY_64_BITS; } - const part2 = this.getMemory(address + 1).binary.padStart(32, '0') + const part2 = this.getMemory(address + 1).binary.padStart(32, '0'); if (part2 === DEFAULT_BINARY_32_BITS) { return DEFAULT_BINARY_64_BITS; } return part1 + part2; } - private loadExamples(): Promise { - return new Promise(async (resolve) => { - const response = await fetch('./assets/examples-dlx/example-runner.json'); - const simulation: SimulationResponse = await response.json() - this.log(simulation); - this.simulation = simulation; + private async loadExamples(): Promise { + const response = await fetch('./assets/examples-dlx/example-runner.json'); + const simulation: SimulationResponse = await response.json(); + this.log(simulation); - let data_code_array: TypeTableCode[] = []; - for (const ins of this.simulation.code) { - this.code.set(ins.address, ins); - data_code_array.push(ins) - } + this.simulation = simulation; + const data_code_array: TypeTableCode[] = []; + for (const ins of this.simulation.code) { + const address = ins.address; + const binary32 = Utils.hexadecimalToBinary(ins.code); + this.memory.setMemoryWordBinaryByAddress(address, binary32); - this.dataCodeArray = data_code_array - this.codeSimulation$.next(data_code_array) - resolve() - }) + this.code.set(ins.address, ins); + data_code_array.push(ins); + } + this.dataCodeArray = data_code_array; + this.codeSimulation$.next(data_code_array); + return Promise.resolve(); } + private async toastMessage(key_title: string = 'TOAST.LOGIN_FALSE', + key_message: string = 'TOAST.ACCESS_DENIED'): Promise { + const config: Partial = { + timeOut: 5000, + positionClass: 'toast-bottom-right' + }; + const message = await this.translate.get(key_message).toPromise(); + const title = await this.translate.get(key_title).toPromise(); + this.toast.info(title, message, config); + return Promise.resolve(); + } public getAllStatusMachine(): TypeStatusMachine { return { - codeText: this.codeText, registers: this.registers, memory: this.memory, - tagsDebugger: this.tagsDebugger, - } + breakpoints: this.breakpointManager, + hello: '' + }; + } + + private debug() { + return { + 'Line: ': this.privateLine, + 'Step: ': this.privateStep, + 'isRunning: ': this.isRunning, + 'isComplete: ': this.isComplete, + 'isBreakpoint: ': this.breakpointManager.isBreakpoint(this.privateLine), + }; + /* + console.debug( + 'Line: ', this.privateLine, + 'Step: ', this.privateStep, + 'isRunning: ', this.isRunning, + 'isComplete: ', this.isComplete, + 'isBreakpoint: ', isBreakpoint, + 'isBreakpoint: ', isBreakpoint, + 'Status: ', this.statusMachineInStep + ); + */ } } diff --git a/src/app/__core/services/electron/electron.service.ts b/src/app/__core/services/electron/electron.service.ts index 969990d..6280048 100644 --- a/src/app/__core/services/electron/electron.service.ts +++ b/src/app/__core/services/electron/electron.service.ts @@ -46,8 +46,8 @@ export class ElectronService { } public static get isServer(): boolean { - let location_href = window.location.href; - let localhost = '//localhost'; + const location_href = window.location.href; + const localhost = '//localhost'; return location_href.includes(localhost); } @@ -92,7 +92,7 @@ export class ElectronService { return this.electron ? this.electron.shell : null; } - public static get debug(): Object { + public static get debug(): any { return { 'isElectronApp': ElectronService.isElectronApp, 'isServer': ElectronService.isServer, diff --git a/src/app/__core/services/file-system-nonodev96/file-system-storage.service.ts b/src/app/__core/services/file-system-nonodev96/file-system-storage.service.ts index 5c976a7..37276de 100644 --- a/src/app/__core/services/file-system-nonodev96/file-system-storage.service.ts +++ b/src/app/__core/services/file-system-nonodev96/file-system-storage.service.ts @@ -1,9 +1,126 @@ import { Injectable } from '@angular/core'; +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; + +import { AngularFireDatabase, AngularFireList } from "@angular/fire/database"; +import { AngularFirestore, AngularFirestoreCollection } from "@angular/fire/firestore"; +import { Utils } from "../../../Utils"; +import { FileItem } from "./file-system.service"; +import { InterfaceFileItem } from "../../../types"; +import firebase from "firebase/app"; +import "firebase/firestore"; +import Timestamp = firebase.firestore.Timestamp; + @Injectable({ providedIn: 'root' }) export class FileSystemStorageService { + private fileItems_Collections: AngularFirestoreCollection; + private readonly UID: string; + + constructor(private httpClient: HttpClient, + private afs: AngularFirestore, + private db: AngularFireDatabase) { + const userData = JSON.parse(localStorage.getItem('user')); + this.UID = userData.uid; + this.fileItems_Collections = this.afs.collection('/fileitems', (ref) => { + return ref.where("e1_uid", "==", this.UID); + }); + } + + + public async initialize(): Promise { + if (await this.isInitialize()) { + return Promise.resolve(1); + } + console.log('FileSystem isInitialize'); + + const listNameExamples = ['base.s', 'fact.s', 'gcm.s', 'input.s', 'prim.s']; + for (const filename of listNameExamples) { + const defaultFile = new FileItem('', false, []); + defaultFile.name = filename; + defaultFile.key = Utils.uuidv4(); + + const content = await this.httpClient.get('assets/examples-dlx/' + filename, {responseType: 'text'}).toPromise(); + const fileItem: InterfaceFileItem = { + ...defaultFile, + dateModified: Timestamp.fromDate(new Date()), + f_id: '', + path: '', + pathKeys: [], + e1_uid: this.UID, + content: content, + description: '' + }; + await this.addFileItem(fileItem); + } + return Promise.resolve(0); + } + + public getInterfaceFileItems(): Observable { + return this.fileItems_Collections.snapshotChanges().pipe( + map((changes) => { + // console.log(items) + return changes.map((c) => { + return { + $key: c.payload.doc.id, + ...c.payload.doc.data(), + } as InterfaceFileItem; + }); + }) + ); + } + + + public async addFileItem(interfaceFileItem: InterfaceFileItem) { + const clearItem: InterfaceFileItem = { + key: interfaceFileItem.key ?? '', + pathKeys: interfaceFileItem.pathKeys ?? [], + path: interfaceFileItem.path ?? '', + name: interfaceFileItem.name ?? '', + isDirectory: interfaceFileItem.isDirectory ?? false, + hasSubDirectories: interfaceFileItem.hasSubDirectories ?? false, + dateModified: interfaceFileItem.dateModified ?? Timestamp.fromDate(new Date()), + thumbnail: interfaceFileItem.thumbnail ?? '', + size: interfaceFileItem.size ?? 0, + dataItem: interfaceFileItem.dataItem ?? {}, + + e1_uid: this.UID, + f_id: interfaceFileItem.f_id ?? '', + description: interfaceFileItem.description ?? '', + content: interfaceFileItem.content ?? '' + }; + const id = this.afs.createId(); + await this.fileItems_Collections.doc(id).set(clearItem); + } + + public async deleteFileItem(id: string): Promise { + try { + const result = await this.fileItems_Collections.doc(id).delete(); + return Promise.resolve(result); + } catch (error) { + console.error(error); + return Promise.reject(error.message); + } + } + + public async editFileItem(fileItem: InterfaceFileItem, $key: string): Promise { + try { + const id = $key ?? this.afs.createId(); + const data = {$key: id, ...fileItem}; + const result_void = await this.fileItems_Collections.doc(id).set(data); + return Promise.resolve(result_void); + } catch (error) { + console.error(error); + return Promise.reject(error.message); + } + } - constructor() { } + private async isInitialize(): Promise { + const citiesRef: AngularFirestoreCollection = this.afs.collection('/fileitems', ref => ref.where('e1_uid', '==', this.UID)); + const vector = await citiesRef.get().toPromise(); + return Promise.resolve(vector.size > 0); + } } diff --git a/src/app/__core/services/file-system-nonodev96/file-system.service.ts b/src/app/__core/services/file-system-nonodev96/file-system.service.ts index 3d83740..3d1a0de 100644 --- a/src/app/__core/services/file-system-nonodev96/file-system.service.ts +++ b/src/app/__core/services/file-system-nonodev96/file-system.service.ts @@ -3,15 +3,14 @@ import { FileSystemStorageService } from './file-system-storage.service'; import FileSystemItem from 'devextreme/file_management/file_system_item'; import UploadInfo from 'devextreme/file_management/upload_info'; import { Utils } from '../../../Utils'; -import { SocketProviderConnectService } from "../socket-provider-connect.service"; -import { TasksService } from "../tasks/tasks.service"; +import { InterfaceFileItem } from "../../../types"; +import firebase from "firebase/app"; +import Timestamp = firebase.firestore.Timestamp; export class FileItem extends FileSystemItem { - // items: FileItem[]; constructor(path: string, isDirectory: boolean, pathKeys: Array) { super(path, isDirectory, pathKeys); - // this.items = []; } } @@ -21,65 +20,61 @@ export class FileItem extends FileSystemItem { export class FileSystemService { // disk: Map; - items: FileItem[] = []; + public items: FileItem[] = []; + public ITEMS: InterfaceFileItem[] = []; + private readonly UID: string; - constructor(private serviceStorage: FileSystemStorageService, - private tasksService: TasksService) { - const documents = new FileItem('', true, []); - documents.name = 'Documents'; - documents.key = Utils.uuidv4(); - - const listNameExamples = ['base.s', 'fact.s', 'gcm.s', 'input.s', 'prim.s']; - const listFilesExamples = []; - - for (const nameFile of listNameExamples) { - const file = new FileItem('', false, []); - file.name = nameFile; - file.key = Utils.uuidv4(); - - listFilesExamples.push(file); - } - - // this.disk = new Map(); - // this.disk.set('', [documents, pepe]); - this.items = [documents, ...listFilesExamples]; + constructor(private fileSystemStorageService: FileSystemStorageService) { + const userData = JSON.parse(localStorage.getItem('user')); + this.UID = userData.uid; } - // TODO - initialize(): Promise { - return new Promise(resolve => { - resolve(true); + public async initialize(): Promise { + await this.fileSystemStorageService.initialize(); + this.fileSystemStorageService.getInterfaceFileItems().subscribe((items) => { + this.ITEMS = items; + this.items = Utils.MAP_InterfaceFileItemArray_TO_FileItemArray(this.ITEMS); }); - } - - getItems(path: FileSystemItem): PromiseLike> | Array { - return new Promise(resolve => { - const results = this.items.filter(value => Utils.arrayIsEqual(value.pathKeys, path.pathKeys)); - resolve(results); + return Promise.resolve(true); + } + + public async getItems(path: FileSystemItem): Promise> { + const results = this.ITEMS.filter(value => Utils.arrayIsEqual(value.pathKeys, path.pathKeys)); + const fileItems = results.map((value) => { + const item: FileItem = new FileItem('', false, []); + item.key = value.key; + item.dataItem = value.dataItem; + item.pathKeys = value.pathKeys; + item.path = value.path; + item.name = value.name; + item.isDirectory = value.isDirectory; + item.hasSubDirectories = value.hasSubDirectories; + item.size = value.size; + item.thumbnail = value.thumbnail; + return item; }); + return Promise.resolve(fileItems); } - createDirectory(parentDirectory: FileSystemItem, name: string): PromiseLike | any { - return new Promise(async (resolve) => { - const {path, pathKeys} = parentDirectory; - const newDirectory = new FileSystemItem(path, true, pathKeys); - newDirectory.name = name; - newDirectory.key = Utils.uuidv4(); + public async createDirectory(parentDirectory: FileSystemItem, name: string): Promise { + const {path, pathKeys} = parentDirectory; + const newDirectory = new FileSystemItem(path, true, pathKeys); + newDirectory.name = name; + newDirectory.key = Utils.uuidv4(); - // const elementsInDirectory = this.items.filter(value => Utils.arrayIsEqual(value.pathKeys, newDirectory.pathKeys)); - // const canCreate = elementsInDirectory.some(value => value.name === newDirectory.name); - const canCreateFolder = true; - if (canCreateFolder) { - this.items.push(newDirectory); - const response = await this.tasksService.createNewFolder(path, newDirectory.name) - } - // resolve (canCreateFolder); - resolve(newDirectory); - }); + // const elementsInDirectory = this.items.filter(value => Utils.arrayIsEqual(value.pathKeys, newDirectory.pathKeys)); + // const canCreate = elementsInDirectory.some(value => value.name === newDirectory.name); + const canCreateFolder = true; + if (canCreateFolder) { + this.items.push(newDirectory); + //const response = await this.tasksService.createNewFolder(path, newDirectory.name) + } + // resolve (canCreateFolder); + return Promise.resolve(newDirectory); } - async createFile(item: FileSystemItem, extension: string): Promise { - return new Promise(async (resolve) => { + public async createFile(item: FileSystemItem, extension: string): Promise { + try { const {path, pathKeys} = item; const newItem = new FileSystemItem(path, false, pathKeys); newItem.key = Utils.uuidv4(); @@ -87,200 +82,117 @@ export class FileSystemService { const index = this.items.push(newItem); // return true if can insert if (index > -1) { - const response = await this.tasksService.createNewFile(path, newItem.name) - } - resolve(index > -1); - }) - } - - updateCategory(directory: FileSystemItem, selectedItems: FileSystemItem[], newCategory: any, viewArea: 'navPane' | 'itemView'): Promise { - return new Promise(resolve => { - let items; - if (viewArea === 'navPane') { - items = [directory]; - } else { - items = selectedItems; + const newFileItem: InterfaceFileItem = { + key: newItem.key, + path: newItem.path, + pathKeys: newItem.pathKeys, + name: newItem.name, + isDirectory: false, + hasSubDirectories: false, + size: newItem.size, + dateModified: Timestamp.fromDate(new Date()), + thumbnail: newItem.thumbnail, + dataItem: newItem.dataItem, + + e1_uid: this.UID, + f_id: "", + description: "", + content: "", + }; + await this.fileSystemStorageService.addFileItem(newFileItem); + // const response = await this.tasksService.createNewFile(path, newItem.name) } - items.forEach((item) => { - if (item.dataItem) { - item.dataItem.category = newCategory; - } - }); - - resolve(items.length > 0); - }) - } - - renameItem(item: FileSystemItem, name: string): PromiseLike | any { - return new Promise(resolve => { - const index = this.items.findIndex(value => value.key === item.key); - this.items[index].name = name; - resolve(item); - }); + return Promise.resolve(index > -1); + } catch (e) { + console.error(e); + return Promise.reject(e); + } } - deleteItem(item: FileSystemItem): PromiseLike | any { - return new Promise(resolve => { - const index = this.items.findIndex(value => value.key === item.key); - if (index > -1) { - if (item.isDirectory) { - const listElementsToDelete = this.items.filter(value => Utils.isSubset(value.pathKeys, item.pathKeys)); - for (const fileItemToDelete of listElementsToDelete) { - const indexToDelete = this.items.findIndex(value => value.key === fileItemToDelete.key); - this.items.splice(indexToDelete, 1); - } - } - this.items.splice(index, 1); + public async updateCategory(directory: FileSystemItem, selectedItems: FileSystemItem[], newCategory: any, viewArea: 'navPane' | 'itemView'): Promise { + let items; + if (viewArea === 'navPane') { + items = [directory]; + } else { + items = selectedItems; + } + for (const item of items) { + const index2 = this.ITEMS.findIndex(value => value.key === item.key); + if (item.dataItem) { + item.dataItem.category = newCategory; + this.ITEMS[index2].dataItem.category = newCategory; + const {$key} = this.ITEMS[index2]; + await this.fileSystemStorageService.editFileItem(this.ITEMS[index2], $key); } - resolve(item); - }); - } - - moveItem(item: FileSystemItem, destinationDirectory: FileSystemItem): PromiseLike | any { - console.log('TODO', item, destinationDirectory); - } - - uploadFileChunk(fileData: File, uploadInfo: UploadInfo, destinationDirectory: FileSystemItem): PromiseLike | any { - console.log('TODO', fileData, uploadInfo, destinationDirectory); - } - - downloadItem(items: Array): void { - console.log('TODO', items); - } - - /* - getItems(path: FileSystemItem): PromiseLike> | Array { - return new Promise(resolve => { - const result = this.disk.get(path.path); - resolve(result); - }); - } - - // DONE - createDirectory(parentDirectory: FileSystemItem, name: string): PromiseLike | any { - const {path, pathKeys} = parentDirectory; - const newDirectory = new FileSystemItem(path, true, pathKeys); - newDirectory.name = name; - newDirectory.key = Utils.uuidv4(); - - const canCreateFolder = !this.directoryExist(parentDirectory, newDirectory); - if (canCreateFolder) { - const elements = this.disk.get(parentDirectory.path) ?? []; - elements.push(newDirectory); - this.disk.set(parentDirectory.path, [...elements]); } - return canCreateFolder; + return Promise.resolve(items.length > 0); } - // DONE - createFile(directory: FileSystemItem, extension: any): boolean { - if (!directory.isDirectory) { - return false; + public async editFileItem(updateFileItem: InterfaceFileItem, $key: string): Promise { + const index1 = this.items.findIndex(value => value.key === updateFileItem.key); + if (index1 > -1) { + this.items[index1] = Utils.MAP_InterfaceFileItem_TO_FileItem(updateFileItem); } - const {path, name, pathKeys} = directory; - const newItem = new FileSystemItem(name, false, pathKeys); - newItem.key = Utils.uuidv4(); - newItem.name = 'New file - ' + newItem.key + extension; - - const canCreateFile = !this.fileExist(directory, newItem); - if (canCreateFile) { - const elements = this.disk.get(path) ?? []; - elements.push(newItem); - this.disk.set(path, [...elements]); + const index2 = this.ITEMS.findIndex(value => value.key === updateFileItem.key); + if (index2 > -1) { + this.ITEMS[index2] = updateFileItem; } - return canCreateFile; + const result_void = await this.fileSystemStorageService.editFileItem(updateFileItem, $key); + return Promise.resolve(result_void); } - // DONE - renameItem(currentDirectory: FileSystemItem, item: FileSystemItem, name: string): PromiseLike | any { - const {path} = currentDirectory; + public async renameItem(item: FileSystemItem, newName: string): Promise { + const index1 = this.items.findIndex(value => value.key === item.key); + this.items[index1].name = newName; + this.items[index1].dateModified = new Date(); - const newItem = {...item} as FileSystemItem; - newItem.name = name; + const index2 = this.ITEMS.findIndex(value => value.key === item.key); + this.ITEMS[index2].name = newName; + this.ITEMS[index2].dateModified = Timestamp.fromDate(new Date()); - if (item.isDirectory) { - const canRenameFolder = !this.directoryExist(currentDirectory, newItem); - if (canRenameFolder) { - const elements = this.disk.get(path) ?? []; - const indexElementToUpdate = elements.findIndex(value => value.key === item.key); - elements[indexElementToUpdate] = newItem; - this.disk.set(path, [...elements]); - } - return canRenameFolder; - } else { - const canRenameFile = !this.fileExist(currentDirectory, newItem); - if (canRenameFile) { - const elements = this.disk.get(path) ?? []; - const indexElementToUpdate = elements.findIndex(value => value.key === item.key); - elements[indexElementToUpdate] = newItem; - this.disk.set(path, [...elements]); - } - return canRenameFile; - } - } - - // TODO - updateCategory(fileSystemItem: FileSystemItem, category: any, viewArea: 'navPane' | 'itemView'): boolean { - return false; + const {$key} = this.ITEMS[index2]; + await this.fileSystemStorageService.editFileItem(this.ITEMS[index2], $key); + return Promise.resolve(item); } - // DONE - deleteItem(currentDirectory: FileSystemItem, item: FileSystemItem): PromiseLike | any { - const {name} = currentDirectory; - const path = name; - - if (item.isDirectory) { - const canDeleteFolder = this.directoryExist(currentDirectory, item); - if (canDeleteFolder) { - const elements = this.disk.get(path) ?? []; - const elementsFilter = elements.filter(value => value.key !== item.key); - this.disk.set(path, [...elementsFilter]); + public async deleteItem(item: FileSystemItem): Promise { + const index1 = this.items.findIndex(value => value.key === item.key); + if (index1 > -1) { + if (item.isDirectory) { + const listElementsToDelete = this.items.filter(value => Utils.isSubset(value.pathKeys, item.pathKeys)); + for (const fileItemToDelete of listElementsToDelete) { + const indexToDelete = this.items.findIndex(value => value.key === fileItemToDelete.key); + this.items.splice(indexToDelete, 1); + } } - return canDeleteFolder; - } else { - const canDeleteFile = this.fileExist(currentDirectory, item); - if (canDeleteFile) { - const elements = this.disk.get(path) ?? []; - const elementsFilter = elements.filter(value => value.key !== item.key); - this.disk.set(path, [...elementsFilter]); + this.items.splice(index1, 1); + + const index2 = this.ITEMS.findIndex(value => value.key === item.key); + if (item.isDirectory) { + const listElementsToDelete = this.ITEMS.filter(value => Utils.isSubset(value.pathKeys, item.pathKeys)); + for (const fileItemToDelete of listElementsToDelete) { + const indexToDelete2 = this.ITEMS.findIndex(value => value.key === fileItemToDelete.key); + const {$key} = this.ITEMS[indexToDelete2]; + await this.fileSystemStorageService.deleteFileItem($key); + this.ITEMS.splice(indexToDelete2, 1); + } } - return canDeleteFile; + this.ITEMS.splice(index2, 1); } + return Promise.resolve(item); } - moveItem(item: FileSystemItem, destinationDirectory: FileSystemItem): PromiseLike | any { - console.log('TODO'); - } - - uploadFileChunk(fileData: File, uploadInfo: UploadInfo, destinationDirectory: FileSystemItem): PromiseLike | any { - console.log('TODO'); + public moveItem(item: FileSystemItem, destinationDirectory: FileSystemItem): PromiseLike | any { + console.log('TODO', item, destinationDirectory); } - downloadItem(items: Array): void { - console.log('TODO'); + public uploadFileChunk(fileData: File, uploadInfo: UploadInfo, destinationDirectory: FileSystemItem): PromiseLike | any { + console.log('TODO', fileData, uploadInfo, destinationDirectory); } - private directoryExist(parentDirectory: FileSystemItem, newDirectory: FileSystemItem): boolean { - let exist = false; - const elements = this.disk.get(parentDirectory.path) ?? []; - for (const element of elements) { - if (element.isDirectory && element.name === newDirectory.name) { - exist = true; - } - } - return exist; + public downloadItem(items: Array): void { + console.log('TODO', items); } - private fileExist(parentDirectory: FileSystemItem, newDirectory: FileSystemItem): boolean { - let exist = false; - const elements = this.disk.get(parentDirectory.path) ?? []; - for (const element of elements) { - if (!element.isDirectory && element.name === newDirectory.name) { - exist = true; - } - } - return exist; - } - */ } diff --git a/src/app/__core/services/socket-provider-connect.service.ts b/src/app/__core/services/socket-provider-connect.service.ts index f56a980..d7df2fb 100644 --- a/src/app/__core/services/socket-provider-connect.service.ts +++ b/src/app/__core/services/socket-provider-connect.service.ts @@ -26,21 +26,21 @@ export class SocketProviderConnectService { this.socket.ioSocket.on('connect', () => { const connect = this.socket.connect(); - this.connectSubject.next(connect) + this.connectSubject.next(connect); if (connect.connected) { this.socket.ioSocket.on('message', (res) => { - this.publicMessageSubject.next(res) - }) + this.publicMessageSubject.next(res); + }); this.socket.ioSocket.on(this.socket.ioSocket.id, (res) => { - this.privateMessageSubject.next(res) - }) + this.privateMessageSubject.next(res); + }); } }); this.socket.ioSocket.on('connect_error', async () => { - const title_server_down_lang = await this.translate.get('TOAST.TITLE_SERVER_DOWN').toPromise() - const message_server_down_lang = await this.translate.get('TOAST.MESSAGE_SERVER_DOWN').toPromise() - this.toast.warning(message_server_down_lang, title_server_down_lang, DEFAULT_CONFIG_TOAST) + const title_server_down_lang = await this.translate.get('TOAST.TITLE_SERVER_DOWN').toPromise(); + const message_server_down_lang = await this.translate.get('TOAST.MESSAGE_SERVER_DOWN').toPromise(); + this.toast.warning(message_server_down_lang, title_server_down_lang, DEFAULT_CONFIG_TOAST); }); this.socket.ioSocket.on('connect_failed', err => SocketProviderConnectService.handleErrors(err)); this.socket.ioSocket.on('disconnect', err => SocketProviderConnectService.handleErrors(err)); @@ -52,6 +52,6 @@ export class SocketProviderConnectService { } private static handleErrors(err) { - console.error(err) + console.error(err); } } diff --git a/src/app/__core/services/tasks/tasks.service.ts b/src/app/__core/services/tasks/tasks.service.ts index ad1b243..9ae93bd 100644 --- a/src/app/__core/services/tasks/tasks.service.ts +++ b/src/app/__core/services/tasks/tasks.service.ts @@ -35,8 +35,8 @@ export class TasksService implements OnDestroy { name: "Client", localName: "Client-" + this.coreAgentsClient.clientID, address: this.coreAgentsClient.clientID - }) - }) + }); + }); } ngOnDestroy(): void { @@ -55,27 +55,25 @@ export class TasksService implements OnDestroy { * @param key * @param newFile */ - createNewFile(path: string, key: string, newFile: string = 'example_00.s'): Promise { - return new Promise(async (resolve, reject) => { - const createFile = new CreateFile(path, key, newFile); - const createFile_string = JSON.stringify(createFile); - - const message = new ACLMessage(); - message.setSender(this.sender); - message.setPerformative(Performative.REQUEST); - message.setOntology(new Ontology("Create-File")); - message.setAction("CreateFile"); - message.setContent(createFile_string); - - const taskContainer = await this.coreAgentsClient.addTask( - new Task_CreateFile_RequestInitiator("Create-File", message) - ); - if (taskContainer.status === 'ok') { - resolve(taskContainer) - } else { - reject(taskContainer) - } - }) + async createNewFile(path: string, key: string, newFile: string = 'example_00.s'): Promise { + const createFile = new CreateFile(path, key, newFile); + const createFile_string = JSON.stringify(createFile); + + const message = new ACLMessage(); + message.setSender(this.sender); + message.setPerformative(Performative.REQUEST); + message.setOntology(new Ontology("Create-File")); + message.setAction("CreateFile"); + message.setContent(createFile_string); + + const taskContainer = await this.coreAgentsClient.addTask( + new Task_CreateFile_RequestInitiator("Create-File", message) + ); + if (taskContainer.status === 'ok') { + return Promise.resolve(taskContainer); + } else { + return Promise.reject(taskContainer); + } } /** @@ -85,27 +83,25 @@ export class TasksService implements OnDestroy { * @param key * @param newFolder */ - createNewFolder(path: string, key: string, newFolder: string = 'example_folder'): Promise { - return new Promise(async (resolve, reject) => { - const createFolder = new CreateFolder(path, key, newFolder); - const createFolder_string = JSON.stringify(createFolder); - - const message = new ACLMessage(); - message.setSender(this.sender); - message.setPerformative(Performative.REQUEST); - message.setOntology(new Ontology("Create-Folder")); - message.setAction("CreateFolder"); - message.setContent(createFolder_string); - - const taskContainer = await this.coreAgentsClient.addTask( - new Task_CreateFolder_RequestInitiator("Create-Folder", message) - ); - if (taskContainer.status === 'ok') { - resolve(taskContainer) - } else { - reject(taskContainer) - } - }) + async createNewFolder(path: string, key: string, newFolder: string = 'example_folder'): Promise { + const createFolder = new CreateFolder(path, key, newFolder); + const createFolder_string = JSON.stringify(createFolder); + + const message = new ACLMessage(); + message.setSender(this.sender); + message.setPerformative(Performative.REQUEST); + message.setOntology(new Ontology("Create-Folder")); + message.setAction("CreateFolder"); + message.setContent(createFolder_string); + + const taskContainer = await this.coreAgentsClient.addTask( + new Task_CreateFolder_RequestInitiator("Create-Folder", message) + ); + if (taskContainer.status === 'ok') { + return Promise.resolve(taskContainer); + } else { + return Promise.reject(taskContainer); + } } /** @@ -115,28 +111,26 @@ export class TasksService implements OnDestroy { * @param key ==> FileSystemItem.key * @param newName */ - modifyFile(path: string, key: string, newName: string): Promise { - return new Promise(async (resolve, reject) => { - const modifyFile = new ModifyFile(path, key, newName); - const modifyFile_string = JSON.stringify(modifyFile); - - const message = new ACLMessage(); - message.setSender(this.sender); - message.setPerformative(Performative.REQUEST); - message.setOntology(new Ontology("Modify-File")); - message.setAction("ModifyFile"); - message.setContent(modifyFile_string); - - const taskContainer = await this.coreAgentsClient.addTask( - new Task_ModifyFile_RequestInitiator("Modify-File", message) - ); - if (taskContainer.status === 'ok') { - resolve(taskContainer) - } else { - reject(taskContainer) - } - - }) + async modifyFile(path: string, key: string, newName: string): Promise { + const modifyFile = new ModifyFile(path, key, newName); + const modifyFile_string = JSON.stringify(modifyFile); + + const message = new ACLMessage(); + message.setSender(this.sender); + message.setPerformative(Performative.REQUEST); + message.setOntology(new Ontology("Modify-File")); + message.setAction("ModifyFile"); + message.setContent(modifyFile_string); + + const taskContainer = await this.coreAgentsClient.addTask( + new Task_ModifyFile_RequestInitiator("Modify-File", message) + ); + if (taskContainer.status === 'ok') { + return Promise.resolve(taskContainer); + } else { + return Promise.reject(taskContainer); + } + } /** @@ -146,27 +140,25 @@ export class TasksService implements OnDestroy { * @param key ==> FileSystemItem.key * @param newName */ - modifyFolder(path: string, key: string, newName: string): Promise { - return new Promise(async (resolve, reject) => { - const modifyFolder = new ModifyFolder(path, key, newName); - const modifyFolder_string = JSON.stringify(modifyFolder); - - const message = new ACLMessage(); - message.setSender(this.sender); - message.setPerformative(Performative.REQUEST); - message.setOntology(new Ontology("Modify-Folder")); - message.setAction("ModifyFolder"); - message.setContent(modifyFolder_string); - - const taskContainer = await this.coreAgentsClient.addTask( - new Task_ModifyFolder_RequestInitiator("Modify-Folder", message) - ); - if (taskContainer.status === 'ok') { - resolve(taskContainer) - } else { - reject(taskContainer) - } - }) + async modifyFolder(path: string, key: string, newName: string): Promise { + const modifyFolder = new ModifyFolder(path, key, newName); + const modifyFolder_string = JSON.stringify(modifyFolder); + + const message = new ACLMessage(); + message.setSender(this.sender); + message.setPerformative(Performative.REQUEST); + message.setOntology(new Ontology("Modify-Folder")); + message.setAction("ModifyFolder"); + message.setContent(modifyFolder_string); + + const taskContainer = await this.coreAgentsClient.addTask( + new Task_ModifyFolder_RequestInitiator("Modify-Folder", message) + ); + if (taskContainer.status === 'ok') { + return Promise.resolve(taskContainer); + } else { + return Promise.reject(taskContainer); + } } /** @@ -176,28 +168,24 @@ export class TasksService implements OnDestroy { * @param key ==> FileSystemItem.key * @param newContent */ - editFile(path: string, key: string, newContent: string[]): Promise { - return new Promise(async (resolve, reject) => { - const editFile = new EditFile(path, key, newContent); - const editFile_string = JSON.stringify(editFile); - - const message = new ACLMessage(); - message.setSender(this.sender); - message.setPerformative(Performative.REQUEST); - message.setOntology(new Ontology("Edit-File")); - message.setAction("EditFile"); - message.setContent(editFile_string); - - const taskContainer = await this.coreAgentsClient.addTask( - new Task_EditFile_RequestInitiator("Edit-File", message) - ); - if (taskContainer.status === 'ok') { - resolve(taskContainer) - } else { - reject(taskContainer) - } - }) + async editFile(path: string, key: string, newContent: string[]): Promise { + const editFile = new EditFile(path, key, newContent); + const editFile_string = JSON.stringify(editFile); + + const message = new ACLMessage(); + message.setSender(this.sender); + message.setPerformative(Performative.REQUEST); + message.setOntology(new Ontology("Edit-File")); + message.setAction("EditFile"); + message.setContent(editFile_string); + + const taskContainer = await this.coreAgentsClient.addTask( + new Task_EditFile_RequestInitiator("Edit-File", message) + ); + if (taskContainer.status === 'ok') { + return Promise.resolve(taskContainer); + } else { + return Promise.reject(taskContainer); + } } - - } diff --git a/src/app/__core/services/tests/tests.service.ts b/src/app/__core/services/tests/tests.service.ts index 0198ab2..e72ce96 100644 --- a/src/app/__core/services/tests/tests.service.ts +++ b/src/app/__core/services/tests/tests.service.ts @@ -10,7 +10,7 @@ export class Product { type: number; } -let productTypes: ProductType[] = [{ +const productTypes: ProductType[] = [{ id: 1, text: "All" }, { diff --git a/src/app/__core/storage/storage.service.ts b/src/app/__core/storage/storage.service.ts index 1ec283e..e562ed7 100644 --- a/src/app/__core/storage/storage.service.ts +++ b/src/app/__core/storage/storage.service.ts @@ -1,9 +1,10 @@ import { Injectable } from '@angular/core'; import { Observable, Subject } from "rxjs"; import { + DEFAULT_AUTO_SAVE, DEFAULT_FLOATING_POINT_STAGE_CONFIGURATION, DEFAULT_LANG, - DEFAULT_MEMORY_SIZE + DEFAULT_MEMORY_SIZE, DEFAULT_TIME_SIMULATION } from "../../CONSTAST"; @Injectable({ @@ -25,7 +26,7 @@ export class StorageService { return JSON.parse(localStorage.getItem(key)); } - setItem(key: string, data: any) { + setItem(key: string, data: any): void { localStorage.setItem(key, JSON.stringify(data)); this.storageSub.next(key); } @@ -34,15 +35,21 @@ export class StorageService { return localStorage.getItem(key) !== null; } - defaultDataInStorage() { - if (!this.hasItem('lang')) { - this.setItem('lang', DEFAULT_LANG) + defaultDataInStorage(): void { + if (!this.hasItem('floating_point_stage_configuration')) { + this.setItem('floating_point_stage_configuration', DEFAULT_FLOATING_POINT_STAGE_CONFIGURATION); } if (!this.hasItem('memory_size')) { - this.setItem('memory_size', DEFAULT_MEMORY_SIZE) + this.setItem('memory_size', DEFAULT_MEMORY_SIZE); } - if (!this.hasItem('floating_point_stage_configuration')) { - this.setItem('floating_point_stage_configuration', DEFAULT_FLOATING_POINT_STAGE_CONFIGURATION) + if (!this.hasItem('time_simulation')) { + this.setItem('time_simulation', DEFAULT_TIME_SIMULATION); + } + if (!this.hasItem('lang')) { + this.setItem('lang', DEFAULT_LANG); + } + if (!this.hasItem('auto_save')) { + this.setItem('auto_save', DEFAULT_AUTO_SAVE); } } } diff --git a/src/app/__shared/components/page-not-found/page-not-found.component.ts b/src/app/__shared/components/page-not-found/page-not-found.component.ts index ae41e0d..cac5403 100644 --- a/src/app/__shared/components/page-not-found/page-not-found.component.ts +++ b/src/app/__shared/components/page-not-found/page-not-found.component.ts @@ -6,7 +6,9 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./page-not-found.component.scss'] }) export class PageNotFoundComponent implements OnInit { - constructor() {} + constructor() { + } - ngOnInit(): void {} + ngOnInit(): void { + } } diff --git a/src/app/__shared/guard/auth.guard.ts b/src/app/__shared/guard/auth.guard.ts index de4fe42..e71645d 100644 --- a/src/app/__shared/guard/auth.guard.ts +++ b/src/app/__shared/guard/auth.guard.ts @@ -1,7 +1,6 @@ import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; import { AuthService } from "../../__core/auth/auth.service"; -import { Observable } from 'rxjs'; import { ToastrService } from "ngx-toastr"; import { IndividualConfig } from "ngx-toastr/toastr/toastr-config"; import { TranslateService } from "@ngx-translate/core"; @@ -17,22 +16,18 @@ export class AuthGuard implements CanActivate { private toast: ToastrService) { } - canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean { - return new Promise(async (resolve) => { - - if (!this.authService.isLoggedIn) { - const config: Partial = { - progressBar: true, - progressAnimation: 'decreasing', - closeButton: true - }; - const lang_access_denied = await this.translate.get('TOAST.ACCESS_DENIED').toPromise(); - const lang_login_false = await this.translate.get('TOAST.LOGIN_FALSE').toPromise(); - this.toast.warning(lang_login_false, lang_access_denied, config); - } - - resolve(this.authService.isLoggedIn); - }) + async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise { + if (!this.authService.isLoggedIn) { + const config: Partial = { + progressBar: true, + progressAnimation: 'decreasing', + closeButton: true + }; + const lang_access_denied = await this.translate.get('TOAST.ACCESS_DENIED').toPromise(); + const lang_login_false = await this.translate.get('TOAST.LOGIN_FALSE').toPromise(); + this.toast.warning(lang_login_false, lang_access_denied, config); + } + return Promise.resolve(this.authService.isLoggedIn); } } diff --git a/src/app/_tasks/Tasks.ts b/src/app/_tasks/Tasks.ts index c1697dd..a2af550 100644 --- a/src/app/_tasks/Tasks.ts +++ b/src/app/_tasks/Tasks.ts @@ -2,110 +2,110 @@ import { AchieveREInitiator, ACLMessage } from "thumder-ontology"; export class Task_CreateFile_RequestInitiator extends AchieveREInitiator { constructor(taskName: string, message: ACLMessage) { - super(taskName, message) - console.log("Task_CreateFile_RequestInitiator") + super(taskName, message); + console.log("Task_CreateFile_RequestInitiator"); } handleAgree(agree: ACLMessage): null { - console.log("Task_CreateFile_RequestInitiator handleAgree") - return null + console.log("Task_CreateFile_RequestInitiator handleAgree"); + return null; } handleRefuse(refuse: ACLMessage): null { - console.log("Task_CreateFile_RequestInitiator handleRefuse") - return null + console.log("Task_CreateFile_RequestInitiator handleRefuse"); + return null; } handleInform(inform: ACLMessage): null { - console.log("Task_CreateFile_RequestInitiator handleInform") - return null + console.log("Task_CreateFile_RequestInitiator handleInform"); + return null; } } export class Task_CreateFolder_RequestInitiator extends AchieveREInitiator { constructor(taskName: string, message: ACLMessage) { - super(taskName, message) - console.log("Task_CreateFolder_RequestInitiator") + super(taskName, message); + console.log("Task_CreateFolder_RequestInitiator"); } handleAgree(agree: ACLMessage): null { - console.log("Task_CreateFolder_RequestInitiator handleAgree") - return null + console.log("Task_CreateFolder_RequestInitiator handleAgree"); + return null; } handleRefuse(refuse: ACLMessage): null { - console.log("Task_CreateFolder_RequestInitiator handleRefuse") - return null + console.log("Task_CreateFolder_RequestInitiator handleRefuse"); + return null; } handleInform(inform: ACLMessage): null { - console.log("Task_CreateFolder_RequestInitiator handleInform") - return null + console.log("Task_CreateFolder_RequestInitiator handleInform"); + return null; } } export class Task_ModifyFile_RequestInitiator extends AchieveREInitiator { constructor(taskName: string, message: ACLMessage) { - super(taskName, message) - console.log("Task_ModifyFile_RequestInitiator") + super(taskName, message); + console.log("Task_ModifyFile_RequestInitiator"); } handleAgree(agree: ACLMessage): null { - console.log("Task_ModifyFile_RequestInitiator handleAgree") - return null + console.log("Task_ModifyFile_RequestInitiator handleAgree"); + return null; } handleRefuse(refuse: ACLMessage): null { - console.log("Task_ModifyFile_RequestInitiator handleRefuse") - return null + console.log("Task_ModifyFile_RequestInitiator handleRefuse"); + return null; } handleInform(inform: ACLMessage): null { - console.log("Task_ModifyFile_RequestInitiator handleInform") - return null + console.log("Task_ModifyFile_RequestInitiator handleInform"); + return null; } } export class Task_ModifyFolder_RequestInitiator extends AchieveREInitiator { constructor(taskName: string, message: ACLMessage) { - super(taskName, message) - console.log("Task_ModifyFolder_RequestInitiator") + super(taskName, message); + console.log("Task_ModifyFolder_RequestInitiator"); } handleAgree(agree: ACLMessage): null { - console.log("Task_ModifyFolder_RequestInitiator handleAgree") - return null + console.log("Task_ModifyFolder_RequestInitiator handleAgree"); + return null; } handleRefuse(refuse: ACLMessage): null { - console.log("Task_ModifyFolder_RequestInitiator handleRefuse") - return null + console.log("Task_ModifyFolder_RequestInitiator handleRefuse"); + return null; } handleInform(inform: ACLMessage): null { - console.log("Task_ModifyFolder_RequestInitiator handleInform") - return null + console.log("Task_ModifyFolder_RequestInitiator handleInform"); + return null; } } export class Task_EditFile_RequestInitiator extends AchieveREInitiator { constructor(taskName: string, message: ACLMessage) { - super(taskName, message) - console.log("Task_EditFile_RequestInitiator") + super(taskName, message); + console.log("Task_EditFile_RequestInitiator"); } handleAgree(agree: ACLMessage): null { - console.log("Task_EditFile_RequestInitiator handleAgree") - return null + console.log("Task_EditFile_RequestInitiator handleAgree"); + return null; } handleRefuse(refuse: ACLMessage): null { - console.log("Task_EditFile_RequestInitiator handleRefuse") - return null + console.log("Task_EditFile_RequestInitiator handleRefuse"); + return null; } handleInform(inform: ACLMessage): null { - console.log("Task_EditFile_RequestInitiator handleInform") - return null + console.log("Task_EditFile_RequestInitiator handleInform"); + return null; } } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d12ada3..4f52b99 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -42,6 +42,8 @@ import { AboutView } from "./views/_landing/about/about.view"; // Guards import { AuthGuard } from "./__shared/guard/auth.guard"; import { NoAuthGuard } from "./__shared/guard/no-auth.guard"; +import { MultiplesViewsComponent } from "./views/_auth/_views/multiples-views.component"; +import { LoggerView } from "./views/_auth/logger/logger.view"; const routes: Routes = [ @@ -71,12 +73,14 @@ const routes: Routes = [ {path: "documentation", component: DocsView, data: {breadcrumb: 'Documentation'}}, {path: "file-manager", component: FileManagerView, data: {breadcrumb: 'File Manager'}}, {path: "ide", component: IDEView, data: {breadcrumb: 'IDE'}}, + {path: "logger", component: LoggerView, data: {breadcrumb: 'Logger'}}, {path: "memory", component: MemoryView, data: {breadcrumb: 'Memory'}}, {path: "cycle-clock-diagram", component: CycleClockDiagramView, data: {breadcrumb: 'Pipeline'}}, {path: "pipeline", component: PipelineView, data: {breadcrumb: 'Pipeline'}}, {path: "profile", component: ProfileView, data: {breadcrumb: 'Profile'}}, {path: "registers", component: RegistersView, data: {breadcrumb: 'Registers'}}, {path: "statistics", component: StatisticsView, data: {breadcrumb: 'Statistics'}}, + {path: "multiview", component: MultiplesViewsComponent, data: {breadcrumb: 'Multiview'}}, ], }, // _landing views diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 839358f..53fee15 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -20,37 +20,35 @@ export class AppComponent { lang: string = DEFAULT_LANG; - constructor(@Inject(DOCUMENT) - private document: Document, + constructor(@Inject(DOCUMENT) private document: Document, private storageService: StorageService, private machine: MachineService, private electronService: ElectronService, private translate: TranslateService, - private router: Router - ) { - console.log("ElectronService.debug: ", ElectronService.debug) + private router: Router) { + console.log("ElectronService.debug: ", ElectronService.debug); - this.lang = this.storageService.getItem('lang') + this.lang = this.storageService.getItem('lang'); this.document.documentElement.lang = this.lang; this.translate.setDefaultLang(this.lang); // clean the route class when you travel and end de navigation - router.events.subscribe((route) => { + this.router.events.subscribe((route) => { if (route instanceof NavigationEnd) { - this.document.body.className = "" + this.document.body.className = ""; } }); MonacoConfig.onMonacoLoad(); } getLang() { - this.lang = this.storageService.getItem('lang') - return this.lang + this.lang = this.storageService.getItem('lang'); + return this.lang; } setLang(lang: TypeLang) { - this.storageService.setItem('lang', lang) - this.lang = lang + this.storageService.setItem('lang', lang); + this.lang = lang; this.translate.setDefaultLang(lang); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ae67bed..43a6697 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -63,32 +63,34 @@ import { LayoutLandingComponent } from "./_layouts/landing/layout-landing.compon // _admin views // _auth views +import { MultiplesViewsComponent } from './views/_auth/_views/multiples-views.component'; +import { CalculatorView } from './views/_auth/calculator/calculator.view'; +import { CodeView } from './views/_auth/code/code.view'; +import { ConfigView } from './views/_auth/config/config.view'; import { DocsView } from './views/_auth/docs/docs.view'; import { FileManagerView } from './views/_auth/file-manager/file-manager.view'; import { IDEView } from "./views/_auth/ide/ide.view"; +import { LoggerView } from "./views/_auth/logger/logger.view"; +import { MemoryView } from './views/_auth/memory/memory.view'; import { CycleClockDiagramView } from "./views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view"; import { PipelineView } from "./views/_auth/pixi-pipeline/pipeline.view"; import { ProfileView } from "./views/_auth/profile/profile.view"; -import { CalculatorView } from './views/_auth/calculator/calculator.view'; +import { RegistersView } from './views/_auth/registers/registers.view'; +import { StatisticsView } from './views/_auth/statistics/statistics.view'; // no _layouts views +import { AboutView } from './views/_landing/about/about.view'; +import { LandingView } from "./views/_landing/landing/landing.view"; import { DebugView } from './views/debug/debug-view'; import { ForgotPasswordView } from "./views/forgot-password/forgot-password.view"; -import { LandingView } from "./views/_landing/landing/landing.view"; -import { AboutView } from './views/_landing/about/about.view'; import { LoginView } from "./views/login/login.view"; import { RegisterView } from "./views/register/register.view"; // Index import { IndexView } from "./views/_index/index.view"; -import { RegistersView } from './views/_auth/registers/registers.view'; -import { CodeView } from './views/_auth/code/code.view'; -import { MemoryView } from './views/_auth/memory/memory.view'; // AoT requires an exported function for factories import * as PIXI from "pixi.js"; -import { ConfigView } from './views/_auth/config/config.view'; -import { StatisticsView } from './views/_auth/statistics/statistics.view'; PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST; PIXI.settings.SORTABLE_CHILDREN = true; @@ -127,6 +129,7 @@ export function markedOptionsFactory(): MarkedOptions { AppComponent, DebugView, + MultiplesViewsComponent, LayoutAdminComponent, LayoutAuthComponent, @@ -145,6 +148,7 @@ export function markedOptionsFactory(): MarkedOptions { DocsView, FileManagerView, IDEView, + LoggerView, MemoryView, CycleClockDiagramView, PipelineView, diff --git a/src/app/components/aside/aside-left/aside-left.component.ts b/src/app/components/aside/aside-left/aside-left.component.ts index 1315f1b..a2ec1ae 100644 --- a/src/app/components/aside/aside-left/aside-left.component.ts +++ b/src/app/components/aside/aside-left/aside-left.component.ts @@ -20,10 +20,8 @@ export class AsideLeftComponent implements OnInit { ngOnInit(): void { } - goToPage($event: MouseEvent, menu: PublicRoutes) { - this.router.navigateByUrl(menu.routerLink) - .then(() => { - // console.log(value) - }) + async goToPage($event: MouseEvent, menu: PublicRoutes): Promise { + const data = this.router.navigateByUrl(menu.routerLink); + return Promise.resolve(data); } } diff --git a/src/app/components/breadcrumb/breadcrumb.component.ts b/src/app/components/breadcrumb/breadcrumb.component.ts index 2f97ad8..2608d3c 100644 --- a/src/app/components/breadcrumb/breadcrumb.component.ts +++ b/src/app/components/breadcrumb/breadcrumb.component.ts @@ -2,10 +2,6 @@ import { Component } from "@angular/core"; import { Router, Event, - ActivationStart, - ActivationEnd, - ActivatedRouteSnapshot, - NavigationStart, NavigationEnd, ActivatedRoute, Data @@ -28,12 +24,12 @@ export class BreadcrumbComponent { menuItemsLoaded: Promise; constructor(private router: Router, private activatedRoute: ActivatedRoute) { - this.router.events.pipe( - filter((event: Event) => event instanceof NavigationEnd), - ).subscribe((event) => { - this.menuItems = this.createBreadcrumbs(this.activatedRoute.root); - this.menuItemsLoaded = Promise.resolve(true) - }); + this.router.events + .pipe(filter((event: Event) => event instanceof NavigationEnd)) + .subscribe((event) => { + this.menuItems = this.createBreadcrumbs(this.activatedRoute.root); + this.menuItemsLoaded = Promise.resolve(true); + }); } private createBreadcrumbs(route: ActivatedRoute, url: string = '', breadcrumbs: MenuItem[] = []): MenuItem[] { diff --git a/src/app/components/footers/footer-admin/footer-admin.component.ts b/src/app/components/footers/footer-admin/footer-admin.component.ts index 8b52c1f..8d0a310 100644 --- a/src/app/components/footers/footer-admin/footer-admin.component.ts +++ b/src/app/components/footers/footer-admin/footer-admin.component.ts @@ -6,7 +6,10 @@ import { Component, OnInit } from "@angular/core"; }) export class FooterAdminComponent implements OnInit { date = new Date().getFullYear(); - constructor() {} - ngOnInit(): void {} + constructor() { + } + + ngOnInit(): void { + } } diff --git a/src/app/components/footers/footer/footer.component.ts b/src/app/components/footers/footer/footer.component.ts index 5c1011d..5bdca70 100644 --- a/src/app/components/footers/footer/footer.component.ts +++ b/src/app/components/footers/footer/footer.component.ts @@ -18,6 +18,6 @@ export class FooterComponent implements OnInit { this.lang = this.storageService.getItem('lang'); this.storageService.watchStorage().subscribe((update_key) => { this.lang = this.storageService.getItem('lang'); - }) + }); } } diff --git a/src/app/components/modals/edit-memory-binary32/edit-memory-binary32.component.ts b/src/app/components/modals/edit-memory-binary32/edit-memory-binary32.component.ts index abe5822..aa5a2c6 100644 --- a/src/app/components/modals/edit-memory-binary32/edit-memory-binary32.component.ts +++ b/src/app/components/modals/edit-memory-binary32/edit-memory-binary32.component.ts @@ -3,8 +3,6 @@ import { DEFAULT_BINARY_32_BITS, DEFAULT_HEXADECIMAL_08_DIGITS, MAX_VALUE_TYPE_DATA, REGEX_HEXADECIMAL_08, - REGEX_HEXADECIMAL_16, - STEP_TYPE_DATA } from '../../../CONSTAST'; import { Utils } from "../../../Utils"; import { MachineService } from "../../../__core/machine/machine.service"; @@ -38,15 +36,15 @@ export class EditMemoryBinary32Component implements OnInit { * addressMemoryModule === 0 ==> "0000000000000001" * addressMemoryModule === 2 ==> "0000001000000011" */ - addressMemoryModule = 0 + addressMemoryModule = 0; // index in decimal value --> memory[addressMemoryToEdit] = new Int32 // addressMemoryToEdit = addressMemoryDisplay % 4 - addressIsValid = true + addressIsValid = true; typeDataSelected: TypeData = "Word"; // Binary - _binaryValue: string = DEFAULT_BINARY_32_BITS + _binaryValue: string = DEFAULT_BINARY_32_BITS; // Hexadecimal 8 digits - _hexadecimalAddressMemory: string = DEFAULT_HEXADECIMAL_08_DIGITS + _hexadecimalAddressMemory: string = DEFAULT_HEXADECIMAL_08_DIGITS; constructor(public machine: MachineService, private translate: TranslateService, @@ -83,17 +81,17 @@ export class EditMemoryBinary32Component implements OnInit { get valueInSection_Hexadecimal() { const maxLength = this.typeDataSelected === 'Double' ? 16 : 8; const binary_32_64 = this.typeDataSelected === 'Double' ? this.memoryValueBinary64Display : this.memoryValueBinary32Display; - return Utils.binaryToHexadecimal(binary_32_64, {maxLength: maxLength, fillString: '0'}) + return Utils.binaryToHexadecimal(binary_32_64, {maxLength: maxLength, fillString: '0'}); } set valueInSection_Hexadecimal(hexadecimal: string) { const maxLength = this.typeDataSelected === 'Double' ? 64 : 32; - this.binaryValue = Utils.hexadecimalToBinary(hexadecimal, {maxLength: maxLength, fillString: '0'}) + this.binaryValue = Utils.hexadecimalToBinary(hexadecimal, {maxLength: maxLength, fillString: '0'}); } // Address: 0x00000001 // Binary: 00000000 XXXXXXXX 00000000 00000000 - get valueInSection_Byte() { + get valueInSection_Byte(): number { const binary32 = this.memoryValueBinary32Display; const binary8_byte = binary32.substr(8 * this.addressMemoryModule, 8); return parseInt(binary8_byte, 2); @@ -105,7 +103,7 @@ export class EditMemoryBinary32Component implements OnInit { this.binaryValue = Utils.binaryStringSwap(binary32, binary8_byte, 8 * this.addressMemoryModule); } - get valueInSection_HalfWord() { + get valueInSection_HalfWord(): number { const binary32 = this.memoryValueBinary32Display; const binary16_halfword = binary32.substr(8 * this.addressMemoryModule, 16); return parseInt(binary16_halfword, 2); @@ -117,7 +115,7 @@ export class EditMemoryBinary32Component implements OnInit { this.binaryValue = Utils.binaryStringSwap(binary32, binary16_halfword, 8 * this.addressMemoryModule); } - get valueInSection_Word() { + get valueInSection_Word(): number { const binary32 = this.memoryValueBinary32Display; return parseInt(binary32, 2); } @@ -126,7 +124,7 @@ export class EditMemoryBinary32Component implements OnInit { this.binaryValue = word.toString(2).padStart(32, '0'); } - get valueInSection_Float_Binary32_IEEE754() { + get valueInSection_Float_Binary32_IEEE754(): number { const binary32 = this.memoryValueBinary32Display; return Utils.convertIEEE754_Binary32Bits_To_Number(binary32); } @@ -135,7 +133,7 @@ export class EditMemoryBinary32Component implements OnInit { this.binaryValue = Utils.convertIEEE754_Number_To_Binary32Bits(float32); } - get valueInSection_Double_Binary64_IEEE754() { + get valueInSection_Double_Binary64_IEEE754(): number { const binary64 = this.memoryValueBinary64Display; return Utils.convertIEEE754_Binary64Bits_To_Number(binary64); } @@ -152,7 +150,7 @@ export class EditMemoryBinary32Component implements OnInit { } else if (binary.length === 64) { this._binaryValue = binary; } else { - throw new Error("Binary length error: " + binary.length) + throw new Error("Binary length error: " + binary.length.toString()); } } @@ -222,13 +220,13 @@ export class EditMemoryBinary32Component implements OnInit { // Recuperamos el dato anterior switch (this.typeDataSelected) { case "Byte": - this.valueInSection_Byte = parseInt(this.machine.memory.getMemoryByteBinaryByIndex(this.addressMemoryIndex), 2) + this.valueInSection_Byte = parseInt(this.machine.memory.getMemoryByteBinaryByIndex(this.addressMemoryIndex), 2); break; case "HalfWord": - this.valueInSection_HalfWord = parseInt(this.machine.memory.getMemoryWordBinaryByIndex(this.addressMemoryIndex), 2) + this.valueInSection_HalfWord = parseInt(this.machine.memory.getMemoryWordBinaryByIndex(this.addressMemoryIndex), 2); break; case "Word": - this.valueInSection_Word = parseInt(this.machine.memory.getMemoryWordBinaryByIndex(this.addressMemoryIndex), 2) + this.valueInSection_Word = parseInt(this.machine.memory.getMemoryWordBinaryByIndex(this.addressMemoryIndex), 2); break; case "Float": this.valueInSection_Float_Binary32_IEEE754 = 0; @@ -240,7 +238,7 @@ export class EditMemoryBinary32Component implements OnInit { } else { this.addressIsValid = false; console.error("Address not valid, out of memory"); - await this.TOAST_ErrorInAddressMemory() + await this.TOAST_ErrorInAddressMemory(); } } else { await this.TOAST_ErrorRegex(); @@ -263,48 +261,36 @@ export class EditMemoryBinary32Component implements OnInit { // Ej: "1." ---> 1.0 // let oldValueBinaryString = this.machine.getMemory(this.addressMemoryIndex).binary.padStart(32, '0'); switch (this.typeDataSelected) { - case "Byte": + case "Byte": { const newValue_byte = value; const newValue_8bits = Utils.integer8ToBin(newValue_byte); - // let newValueBinaryString_byte = oldValueBinaryString; - // if (this.addressMemoryModule === 0) { - // newValueBinaryString_byte = Utils.binaryStringSwap_module(oldValueBinaryString, newValue_8bits, 0, 8, 8); - // } else if (this.addressMemoryModule === 1) { - // newValueBinaryString_byte = Utils.binaryStringSwap_module(oldValueBinaryString, newValue_8bits, 8, 16, 8); - // } else if (this.addressMemoryModule === 2) { - // newValueBinaryString_byte = Utils.binaryStringSwap_module(oldValueBinaryString, newValue_8bits, 16, 24, 8); - // } else if (this.addressMemoryModule === 3) { - // newValueBinaryString_byte = Utils.binaryStringSwap_module(oldValueBinaryString, newValue_8bits, 24, 32, 8); - // } this.valueInSection_Byte = newValue_byte; this.machine.memory.setMemoryByteBinaryByIndex(this.addressMemoryIndex, newValue_8bits); break; - case "HalfWord": + } + case "HalfWord": { const newValue_h_word = value; const newValue_16bits = Utils.integer16ToBin(newValue_h_word); - // let newValueBinaryString_h_word = oldValueBinaryString; - // if (this.addressMemoryModule === 0) { - // newValueBinaryString_h_word = Utils.binaryStringSwap_module(oldValueBinaryString, newValue_16bits, 0, 16, 16); - // } else if (this.addressMemoryModule === 2) { - // newValueBinaryString_h_word = Utils.binaryStringSwap_module(oldValueBinaryString, newValue_16bits, 16, 32, 16); - // } this.valueInSection_HalfWord = newValue_h_word; this.machine.memory.setMemoryHalfWordBinaryByIndex(this.addressMemoryIndex, newValue_16bits); break; - case "Word": + } + case "Word": { const newValue_word = value; const newValue_32bits = Utils.integer32ToBin(newValue_word); this.valueInSection_Word = newValue_word; this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, newValue_32bits); break; - case "Float": + } + case "Float": { const newValue_float = Utils.formatDecimalNumber(value); const newValue_float_s = Utils.formatDecimalString(newValue_float); const newValue_32bits_floating_point = Utils.convertIEEE754_Number_To_Binary32Bits(newValue_float); this.valueInSection_Float_Binary32_IEEE754 = newValue_float_s; this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, newValue_32bits_floating_point); break; - case "Double": + } + case "Double": { const newValue_double = Utils.formatDecimalNumber(value); const newValue_double_s = Utils.formatDecimalString(newValue_double); const newValue_64bits_floating_point = Utils.convertIEEE754_Number_To_Binary64Bits(newValue_double); @@ -314,6 +300,7 @@ export class EditMemoryBinary32Component implements OnInit { this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, part1); this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex + 4, part2); break; + } } } catch (e) { await this.TOAST_ErrorInValueMemory(); @@ -330,14 +317,14 @@ export class EditMemoryBinary32Component implements OnInit { this._binaryValue = this.machine.memory.getMemoryWordByIndex(0).binary; switch (this.typeDataSelected) { case "Word": - this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, DEFAULT_BINARY_32_BITS) + this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, DEFAULT_BINARY_32_BITS); break; case "Float": - this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, DEFAULT_BINARY_32_BITS) + this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, DEFAULT_BINARY_32_BITS); break; case "Double": - this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, DEFAULT_BINARY_32_BITS) - this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex + 4, DEFAULT_BINARY_32_BITS) + this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex, DEFAULT_BINARY_32_BITS); + this.machine.memory.setMemoryWordBinaryByIndex(this.addressMemoryIndex + 4, DEFAULT_BINARY_32_BITS); break; } this.ref.detectChanges(); @@ -377,7 +364,7 @@ export class EditMemoryBinary32Component implements OnInit { const initIndex = this.addressMemoryIndex - this.addressMemoryModule; const string32bits = this.machine.memory.getMemoryWordBinaryByIndex(initIndex); const string32bits_next_address = this.machine.memory.getMemoryWordBinaryByIndex(initIndex + 4); - let module = this.addressMemoryModule; + const module = this.addressMemoryModule; let partToChange_init = 0; let partToChange_end = 32; let partToChange_next_address_init = 0; @@ -439,12 +426,12 @@ export class EditMemoryBinary32Component implements OnInit { break; } - let text_init = string32bits.slice(0, partToChange_init); - let text_mid = string32bits.slice(partToChange_init, partToChange_end); - let text_end = string32bits.slice(partToChange_end, 32); - let text_init_next_address = string32bits_next_address.slice(0, partToChange_next_address_init); - let text_mid_next_address = string32bits_next_address.slice(partToChange_next_address_init, partToChange_next_address_end); - let text_end_next_address = string32bits_next_address.slice(partToChange_next_address_end, 32); + const text_init = string32bits.slice(0, partToChange_init); + const text_mid = string32bits.slice(partToChange_init, partToChange_end); + const text_end = string32bits.slice(partToChange_end, 32); + const text_init_next_address = string32bits_next_address.slice(0, partToChange_next_address_init); + const text_mid_next_address = string32bits_next_address.slice(partToChange_next_address_init, partToChange_next_address_end); + const text_end_next_address = string32bits_next_address.slice(partToChange_next_address_end, 32); let html = ""; html += '

' + text_init + '' + text_mid + "" + text_end + "

"; html += '

' + text_init_next_address + '' + text_mid_next_address + "" + text_end_next_address + "

"; @@ -479,15 +466,16 @@ export class EditMemoryBinary32Component implements OnInit { // ================================================================================================================= - async ngModelChange_ValueInSection_Hexadecimal(hexadecimal: string) { + async ngModelChange_ValueInSection_Hexadecimal(hexadecimal: string): Promise { this.valueInSection_Hexadecimal = hexadecimal; - await this.changeMemory(this.valueInSection_Word) + await this.changeMemory(this.valueInSection_Word); + return Promise.resolve(); } - async ngModelChange_ValueInSection_Decimal(value: number) { + async ngModelChange_ValueInSection_Decimal(value: number): Promise { if (typeof value === "string") { value = 0; - console.error('Should be a number', value) + console.error('Should be a number', value); } if (value === undefined || value === null) { value = 0; @@ -502,24 +490,26 @@ export class EditMemoryBinary32Component implements OnInit { switch (this.typeDataSelected) { case "Byte": this.valueInSection_Byte = value; - await this.changeMemory(value) + await this.changeMemory(value); break; case "HalfWord": this.valueInSection_HalfWord = value; - await this.changeMemory(value) + await this.changeMemory(value); break; case "Word": this.valueInSection_Word = value; - await this.changeMemory(value) + await this.changeMemory(value); break; case "Float": this.valueInSection_Float_Binary32_IEEE754 = value; - await this.changeMemory(value) + await this.changeMemory(value); break; case "Double": this.valueInSection_Double_Binary64_IEEE754 = value; - await this.changeMemory(value) + await this.changeMemory(value); break; } + + return Promise.resolve(); } } diff --git a/src/app/components/modals/edit-register-binary32/edit-register-binary32.component.ts b/src/app/components/modals/edit-register-binary32/edit-register-binary32.component.ts index 6021e93..38ba427 100644 --- a/src/app/components/modals/edit-register-binary32/edit-register-binary32.component.ts +++ b/src/app/components/modals/edit-register-binary32/edit-register-binary32.component.ts @@ -30,8 +30,8 @@ export class EditRegisterBinary32Component implements OnInit, AfterViewInit { maxLengthHexadecimal: number = 8; registerToEditHexadecimalValueIsValid: boolean = true; - regExp_32bits_hex = new RegExp('\\b[0-9A-F]{8}\\b') - regExp_64bits_hex = new RegExp('\\b[0-9A-F]{16}\\b') + regExp_32bits_hex = new RegExp('\\b[0-9A-F]{8}\\b'); + regExp_64bits_hex = new RegExp('\\b[0-9A-F]{16}\\b'); _registerToEdit_binary: string = DEFAULT_BINARY_32_BITS; get registerToEdit_Binary() { @@ -52,7 +52,7 @@ export class EditRegisterBinary32Component implements OnInit, AfterViewInit { get registerToEdit_Hexadecimal() { const maxLengthHexadecimal = this.registerSelected === 'Double' ? 16 : 8; - return parseInt(this._registerToEdit_binary, 2).toString(16).toUpperCase().padStart(maxLengthHexadecimal, '0') + return parseInt(this._registerToEdit_binary, 2).toString(16).toUpperCase().padStart(maxLengthHexadecimal, '0'); } set registerToEdit_Hexadecimal(hexadecimal: string) { @@ -97,7 +97,7 @@ export class EditRegisterBinary32Component implements OnInit, AfterViewInit { this.registerSelected = typeRegister; switch (this.registerSelected) { case "Control": - this.registerToEdit = "PC" + this.registerToEdit = "PC"; this.listRegisters = MACHINE_REGISTERS_C; this.aliasTypeRegister = ""; this.maxLengthHexadecimal = 8; @@ -135,29 +135,32 @@ export class EditRegisterBinary32Component implements OnInit, AfterViewInit { try { let binary; if (this.registerSelected === "Integer" && this.registerToEdit === 0) { - await this.TOAST_ErrorRegister() + await this.TOAST_ErrorRegister(); return; } switch (this.registerSelected) { - case "Control": + case "Control": { this.registerToEditHexadecimalValueIsValid = this.regExp_32bits_hex.test(hexadecimal); binary = Utils.hexadecimalToBinary(hexadecimal); this.registerToEdit_Binary = binary; this.machine.registers[this.registerToEdit].binary = binary; break; - case "Integer": + } + case "Integer": { this.registerToEditHexadecimalValueIsValid = this.regExp_32bits_hex.test(hexadecimal); binary = Utils.hexadecimalToBinary(hexadecimal); this.registerToEdit_Binary = binary; this.machine.registers.R[this.registerToEdit].binary = binary; break; - case "Float": + } + case "Float": { this.registerToEditHexadecimalValueIsValid = this.regExp_32bits_hex.test(hexadecimal); binary = Utils.hexadecimalToBinary(hexadecimal); this.registerToEdit_Binary = binary; this.machine.registers.F[this.registerToEdit].binary = binary; break; - case "Double": + } + case "Double": { this.registerToEditHexadecimalValueIsValid = this.regExp_64bits_hex.test(hexadecimal); binary = Utils.hexadecimalToBinary(hexadecimal, {maxLength: 64, fillString: '0'}); this.registerToEdit_Binary = binary; @@ -165,15 +168,16 @@ export class EditRegisterBinary32Component implements OnInit, AfterViewInit { this.machine.registers.F[index].binary = binary.substr(0, 32); this.machine.registers.F[index + 1].binary = binary.substr(32, 32); break; + } } } catch (e) { - console.error(e) + console.error(e); } } async onRegisterToEditChangeHexadecimal(hexadecimal: string) { this.registerToEdit_Hexadecimal = hexadecimal; - await this.changeRegisterToEditValue(hexadecimal) + await this.changeRegisterToEditValue(hexadecimal); } async onRegisterToEditChange_WordFloatDouble(value: number) { @@ -191,7 +195,7 @@ export class EditRegisterBinary32Component implements OnInit, AfterViewInit { this.registerToEdit_Double = value; break; } - await this.changeRegisterToEditValue(this.registerToEdit_Hexadecimal) + await this.changeRegisterToEditValue(this.registerToEdit_Hexadecimal); } private async TOAST_ErrorRegister() { diff --git a/src/app/components/monaco-editor/monaco-editor.component.html b/src/app/components/monaco-editor/monaco-editor.component.html index c0f4999..7f532bc 100644 --- a/src/app/components/monaco-editor/monaco-editor.component.html +++ b/src/app/components/monaco-editor/monaco-editor.component.html @@ -5,7 +5,7 @@ theme="thumderTheme" language="thumderLanguage" [editorOptions]="EDITOR_OPTIONS_THUMDER" - [(ngModel)]="code_asm" + [(ngModel)]="content" (ngModelChange)="callBackFunc($event)" (editorInitialized)="editorInitialized($any($event))" (editorConfigurationChanged)="editorConfigurationChanged()" diff --git a/src/app/components/monaco-editor/monaco-editor.component.ts b/src/app/components/monaco-editor/monaco-editor.component.ts index cc22228..2213c66 100644 --- a/src/app/components/monaco-editor/monaco-editor.component.ts +++ b/src/app/components/monaco-editor/monaco-editor.component.ts @@ -1,28 +1,28 @@ -import MonacoConfig from "../../../monaco-config"; -import { Component, HostListener, OnInit, ViewChild } from '@angular/core'; -import { HttpClient } from "@angular/common/http"; -import { TypeTags } from "../../types"; -import { MachineService } from "../../__core/machine/machine.service"; +import { AfterViewInit, Component, OnDestroy, OnInit } from '@angular/core'; +import { Observable, Subject } from "rxjs"; import * as monaco from "monaco-editor"; +import { TypeComponentStatus, TypeTags } from "../../types"; +import MonacoConfig from "../../../monaco-config"; import IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor; -import IModelDecoration = monaco.editor.IModelDecoration; import IStandaloneEditorConstructionOptions = monaco.editor.IStandaloneEditorConstructionOptions; +export type TypeBreakpoints = { + [line: number]: boolean +}; + @Component({ selector: 'thumder-monaco-editor', templateUrl: './monaco-editor.component.html', styleUrls: ['./monaco-editor.component.scss'] }) -export class MonacoEditorComponent implements OnInit { +export class MonacoEditorComponent implements OnInit, AfterViewInit, OnDestroy { // export function create(domElement: HTMLElement, options?: IStandaloneEditorConstructionOptions, override?: IEditorOverrideServices): IStandaloneCodeEditor; - - private httpClient: HttpClient; - public readonly EDITOR_OPTIONS_THUMDER: IStandaloneEditorConstructionOptions = MonacoConfig.defaultOptions; public _height = 70; - public code_asm: string = ''; + public content: string = ''; + public initialized$: Subject = new Subject(); private editor: IStandaloneCodeEditor; // private oldDecorationDebugTag_targetId: { line: number, target_id: string } []= []; @@ -30,9 +30,11 @@ export class MonacoEditorComponent implements OnInit { private oldDecorationDebugLine: string[] = []; private iteratorLine: number = 1; - constructor(private http: HttpClient, - private machine: MachineService) { - this.httpClient = http; + public breakpoints: TypeBreakpoints = {}; + public breakpoints$: Subject = new Subject(); + public componentStatus$: Subject = new Subject(); + + constructor() { } set height(value: number) { @@ -40,24 +42,25 @@ export class MonacoEditorComponent implements OnInit { this.editor.layout(); } - get height() { + get height(): number { return this._height; } ngOnInit(): void { - this.httpClient.get('assets/examples-dlx/prim.s', {responseType: 'text'}) - .subscribe(data => { - // console.log(data) - this.code_asm = data; - }); + this.componentStatus$.next('OnInit'); } - editorInitialized($event: IStandaloneCodeEditor) { - console.log('editorInitialized', $event); - this.editor = $event; + ngAfterViewInit(): void { + this.componentStatus$.next('AfterViewInit'); + } - this.editor.layout(); + ngOnDestroy(): void { + this.componentStatus$.next('OnDestroy'); + } + editorInitialized($event: IStandaloneCodeEditor): void { + this.editor = $event; + this.editor.layout(); this.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S, () => { }); @@ -68,30 +71,51 @@ export class MonacoEditorComponent implements OnInit { }); this.editor.onDidChangeModelDecorations((e) => { - + this.breakpoints = this.getAllBreakpoints(); + this.breakpoints$.next(this.breakpoints); }); + this.initialized$.next(true); } - editorLanguageChanged() { + getInitializedObservable(): Observable { + return this.initialized$.asObservable(); + } + + getBreakpointsObservable(): Observable { + return this.breakpoints$.asObservable(); + } + + getComponentStatusObservable(): Observable { + return this.componentStatus$.asObservable(); + } + + async updateContent(content: string): Promise { + this.content = content; + this.editor.setValue(this.content); + return Promise.resolve(); + } + + editorLanguageChanged(): void { // console.log('editorLanguageChanged'); } - editorConfigurationChanged() { + editorConfigurationChanged(): void { // console.log('editorConfigurationChanged'); } - editorValueChange() { + editorValueChange(): void { // console.log('editorValueChange'); } - callBackFunc($event_text: any) { + callBackFunc($event_text: any): void { // console.log('callBackFunc', $event_text) } /* * Controllers */ - public debug() { + + public debug(): void { const line = this.editor.getPosition().lineNumber ?? 1; const decorations = this.editor.getModel().getLineDecorations(line); const decorations_target_id = decorations.map(v => v.id); @@ -104,82 +128,104 @@ export class MonacoEditorComponent implements OnInit { console.log("decorations.some( fas fa-circle color-red )", decorations.some(value => value.options.glyphMarginClassName === "fas fa-circle color-red")); } - public toggleDebuggerTag() { - const line = this.editor.getPosition().lineNumber ?? 1; + public toggleDebuggerTag(line: number = null): void { + line = line ?? this.editor.getPosition().lineNumber ?? 1; const decorations = this.editor.getModel().getLineDecorations(line); const decorations_target_id = decorations.map(v => v.id); - if (decorations.some(value => value.options.glyphMarginClassName === "fas fa-circle color-red")) { - // Eliminamos la tag + // remove the tag + this.breakpoints[line] = false; this.oldDecorationDebugTag_targetId = this.editor.getModel().deltaDecorations([...decorations_target_id], []); } else { - // Añadimos la tag - this.oldDecorationDebugTag_targetId = this.editor.getModel().deltaDecorations([], [ - { - range: new monaco.Range(line, 0, line, 0), - options: { - isWholeLine: true, - // inlineClassName: 'fas fa-circle color-red', - glyphMarginClassName: 'fas fa-circle color-red', - } - } - ] - ); + // add the tag + this.breakpoints[line] = true; + const newDecoration = { + range: new monaco.Range(line, 0, line, 0), + options: { + isWholeLine: true, + // inlineClassName: 'fas fa-circle color-red', + glyphMarginClassName: 'fas fa-circle color-red', + } + }; + this.oldDecorationDebugTag_targetId = this.editor.getModel().deltaDecorations([], [newDecoration]); } - - this.machine.tagsDebugger = this.getListOfTags(); - + localStorage.setItem('breakpoints', JSON.stringify(this.breakpoints)); } public getListOfTags(): TypeTags { const vectorOfInstructions: TypeTags = []; const lineCount = this.editor.getModel().getLineCount(); - for (let line = 0; line < lineCount; line++) { const decorations = this.editor.getModel().getLineDecorations(line); if (decorations.some(value => value.options.glyphMarginClassName === "fas fa-circle color-red")) { - vectorOfInstructions.push({ line: line, content: this.editor.getModel().getLineContent(line), }); - } } return vectorOfInstructions; } - - public debugNextLine() { - const lineCount = this.editor.getModel().getLineCount() + public debugNextLine(): void { + const lineCount = this.editor.getModel().getLineCount(); this.iteratorLine = this.iteratorLine % lineCount === 0 ? 1 : this.iteratorLine + 1; - this.printLine(this.iteratorLine) + this.printLine(this.iteratorLine); + } + + public debugToLine(iteratorLine: number): void { + console.log('debugToLine'); + const lineCount = this.editor.getModel().getLineCount(); + this.iteratorLine = iteratorLine % lineCount; + this.printLine(this.iteratorLine); } /** * Este método busca las lineas marcadas como debug y va iterando en ellas */ - public debugNextLineWithTag() { + public debugNextLineWithTag(): void { const listOfTags = this.getListOfTags(); - const listOfTags_filter = listOfTags.filter(value => value.line > this.iteratorLine) + const listOfTags_filter = listOfTags.filter(value => value.line > this.iteratorLine); this.iteratorLine = listOfTags_filter.length > 0 ? listOfTags_filter.shift().line : 1; - this.printLine(this.iteratorLine) + this.printLine(this.iteratorLine); + } + + getAllBreakpoints(): TypeBreakpoints { + const allDecorations = this.editor.getModel().getAllDecorations(); + const tags: { [line: number]: boolean } = {}; + for (const decoration of allDecorations) { + if (decoration.options.glyphMarginClassName === "fas fa-circle color-red") { + tags[decoration.range.startLineNumber] = true; + } + } + return tags; + } + + clearBreakpoints() { + this.breakpoints = {}; } /** - * Este método pinta una linea en concreto de rojo + * Este método pinta una linea en concreto con un fondo azul * * @param line * @private */ - private printLine(line: number) { - this.oldDecorationDebugLine = this.editor.deltaDecorations(this.oldDecorationDebugLine, [{ - range: new monaco.Range(line, 1, line, 1), - options: { - isWholeLine: true, - className: 'debugLine' - } - }] - ); + printLine(line: number): void { + const newDecoration = { + range: new monaco.Range(line, 1, line, 1), + options: { + isWholeLine: true, + className: 'debugLine' + } + }; + this.oldDecorationDebugLine = this.editor.deltaDecorations(this.oldDecorationDebugLine, [newDecoration]); + } + + setBreakpoints(breakpoints: TypeBreakpoints) { + this.breakpoints = breakpoints; + for (const [line, enabled] of Object.entries(this.breakpoints)) { + this.toggleDebuggerTag(parseInt(line)); + } } } diff --git a/src/app/components/navbars/admin-navbar/admin-navbar.component.ts b/src/app/components/navbars/admin-navbar/admin-navbar.component.ts index 0d370e9..0845518 100644 --- a/src/app/components/navbars/admin-navbar/admin-navbar.component.ts +++ b/src/app/components/navbars/admin-navbar/admin-navbar.component.ts @@ -11,7 +11,7 @@ export class AdminNavbarComponent implements OnInit { ngOnInit(): void { } - log(msg: string) { - console.log(msg) + log(msg: string): void { + console.log(msg); } } diff --git a/src/app/components/navbars/auth-navbar/auth-navbar.component.html b/src/app/components/navbars/auth-navbar/auth-navbar.component.html index fecb8c1..be3d5e8 100644 --- a/src/app/components/navbars/auth-navbar/auth-navbar.component.html +++ b/src/app/components/navbars/auth-navbar/auth-navbar.component.html @@ -67,6 +67,11 @@ + + + diff --git a/src/app/components/navbars/auth-navbar/auth-navbar.component.ts b/src/app/components/navbars/auth-navbar/auth-navbar.component.ts index 0506637..eebc2aa 100644 --- a/src/app/components/navbars/auth-navbar/auth-navbar.component.ts +++ b/src/app/components/navbars/auth-navbar/auth-navbar.component.ts @@ -13,55 +13,66 @@ import { AUTH_ROUTES } from "../../../CONSTAST"; }) export class AuthNavbarComponent implements OnInit { navbarOpen = false; + isRunning = false; AUTH_ROUTES = AUTH_ROUTES; - constructor(@Inject(DOCUMENT) - private document: Document, + constructor(@Inject(DOCUMENT) private document: Document, private router: Router, public app: AppComponent, public machine: MachineService, public authService: AuthService) { + + this.machine.getIsRunningObservable().subscribe((isRunning) => { + this.isRunning = isRunning; + }); } ngOnInit(): void { } - setNavbarOpen() { + setNavbarOpen(): void { this.navbarOpen = !this.navbarOpen; } - async togglePlayPause() { + async togglePlayPause(): Promise { if (this.machine.isRunning === false) { - await this.machine.resume() + await this.machine.resume(); } else { - await this.machine.pause() + await this.machine.pause(); } } - async reset() { - await this.machine.reset() + async reset(): Promise { + await this.machine.reset(); + return Promise.resolve(); + } + + async play(): Promise { + await this.machine.play(); + return Promise.resolve(); } - async play() { - await this.machine.play() + async nextStep(): Promise { + await this.machine.nextStep(); + return Promise.resolve(); } - async next() { - await this.machine.next() + async end(): Promise { + await this.machine.end(); + return Promise.resolve(); } - async end() { - await this.machine.end() + async debug(): Promise { + console.log(this.machine.getAllStatusMachine()); + return Promise.resolve(); } - goToPage($event: MouseEvent, menu: PublicRoutes) { - this.router.navigateByUrl(menu.routerLink) - .then(() => { - // console.log(value) - }) + async goToPage($event: MouseEvent, menu: PublicRoutes): Promise { + const data = await this.router.navigateByUrl(menu.routerLink); + return Promise.resolve(data); } - toggleCollapsed() { + toggleCollapsed(): void { } } diff --git a/src/app/components/pixi-cycle-clock-diagram/pixi-cycle-clock-diagram.component.spec.ts b/src/app/components/pixi-cycle-clock-diagram/pixi-cycle-clock-diagram.component.spec.ts index 094a311..0cf652f 100644 --- a/src/app/components/pixi-cycle-clock-diagram/pixi-cycle-clock-diagram.component.spec.ts +++ b/src/app/components/pixi-cycle-clock-diagram/pixi-cycle-clock-diagram.component.spec.ts @@ -8,9 +8,8 @@ describe('PipelinePixiComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ PixiCycleClockDiagramComponent ] - }) - .compileComponents(); + declarations: [PixiCycleClockDiagramComponent] + }).compileComponents(); }); beforeEach(() => { diff --git a/src/app/components/pixi-cycle-clock-diagram/pixi-cycle-clock-diagram.component.ts b/src/app/components/pixi-cycle-clock-diagram/pixi-cycle-clock-diagram.component.ts index 5d65f27..57f8438 100644 --- a/src/app/components/pixi-cycle-clock-diagram/pixi-cycle-clock-diagram.component.ts +++ b/src/app/components/pixi-cycle-clock-diagram/pixi-cycle-clock-diagram.component.ts @@ -1,5 +1,14 @@ import * as PIXI from 'pixi.js'; -import { Component, HostListener, OnInit, AfterViewInit, ViewChild, OnDestroy } from '@angular/core'; +import { + Component, + HostListener, + OnInit, + AfterViewInit, + ViewChild, + OnDestroy, + Output, + EventEmitter +} from '@angular/core'; import { MachineService } from "../../__core/machine/machine.service"; import { PixiTHUMDER_CycleClockDiagram, TypeArrowDirection } from "../../__core/machine/PixiTHUMDER_CycleClockDiagram"; @@ -10,13 +19,21 @@ import { PixiTHUMDER_CycleClockDiagram, TypeArrowDirection } from "../../__core/ }) export class PixiCycleClockDiagramComponent implements OnInit, AfterViewInit, OnDestroy { - @ViewChild('pixiContainer') public pixiContainer; + @ViewChild('pixiContainer') + public pixiContainer; + public pApp: PIXI.Application; + private inCanvas: boolean = false; private cycleClockDiagram: PixiTHUMDER_CycleClockDiagram; private loader: PIXI.Loader; private ticker: PIXI.Ticker; - Keyboard - Mouse + private Keyboard; + private Mouse; + + private readonly idCanvas = "pixi-cycle-clock-diagram-id"; + + @Output() + public inCanvasEventEmitter = new EventEmitter(); constructor(public machine: MachineService) { this.Keyboard = require('pixi.js-keyboard'); @@ -27,19 +44,23 @@ export class PixiCycleClockDiagramComponent implements OnInit, AfterViewInit, On ngOnInit(): void { this.machine.getStepSimulationObservable().subscribe((stepSimulation) => { const cycle = this.machine.getStatusCycleClockDiagram(stepSimulation); - this.cycleClockDiagram.addInstruction(cycle.instruction, cycle.cycle, cycle.stepsToWait) - this.cycleClockDiagram.nextStep(cycle.step) + this.cycleClockDiagram.addInstruction(cycle.instruction, cycle.cycle, cycle.stepsToWait); + this.cycleClockDiagram.nextStep(cycle.step); }); } - ngAfterViewInit() { - let width = 1600; - let height = 975; + ngAfterViewInit(): void { + const width = 1600; + const height = 975; + const canvas = document.createElement("canvas"); + canvas.id = this.idCanvas; + this.pApp = new PIXI.Application({ width: width, height: height, backgroundColor: 0x1099BB, resolution: 1, + view: canvas }); this.pApp.stage.addChild(this.cycleClockDiagram.draw()); this.pixiContainer.nativeElement.appendChild(this.pApp.view); @@ -94,7 +115,7 @@ export class PixiCycleClockDiagramComponent implements OnInit, AfterViewInit, On // console.log("setup") // } - private gameLoop(delta: number) { + private gameLoop(delta: number): void { // Update the current game state: this.play(delta); @@ -102,7 +123,7 @@ export class PixiCycleClockDiagramComponent implements OnInit, AfterViewInit, On this.Mouse.update(); } - private play(delta: number) { + private play(delta: number): void { if (this.Keyboard.isKeyDown('ArrowLeft', 'KeyA', 'KeyJ')) { this.cycleClockDiagram.moveRight(); } @@ -132,7 +153,7 @@ export class PixiCycleClockDiagramComponent implements OnInit, AfterViewInit, On } @HostListener('window:resize', ['$event']) - onResize(event: any) { + onResize(event: any): void { event.preventDefault(); event.stopPropagation(); this.resize(); @@ -140,55 +161,74 @@ export class PixiCycleClockDiagramComponent implements OnInit, AfterViewInit, On // Detengo el movimiento de desplazamiento @HostListener('document:keydown', ['$event']) - handleKeyboardEvent(event: KeyboardEvent) { - event.preventDefault(); + handleKeyboardEvent(event: KeyboardEvent): void { + if (this.inCanvas && event.key === 'ArrowDown') { + event.preventDefault(); + } + if (this.inCanvas && event.key === 'ArrowUp') { + event.preventDefault(); + } + } + + @HostListener('document:click', ['$event', '$event.target']) + handleOnClick(event: MouseEvent, targetElement: HTMLElement): void { + // console.log(event, targetElement) + if (!targetElement) { + return; + } + this.inCanvas = targetElement.id === this.idCanvas; + this.inCanvasEventEmitter.emit(this.inCanvas); + // const clickedInside = this.elementRef.nativeElement.contains(targetElement); + // if (!clickedInside) { + // this.clickOutside.emit(event); + // } } - moveBottom() { + moveBottom(): void { this.cycleClockDiagram.moveBottom(); } - moveTop() { + moveTop(): void { this.cycleClockDiagram.moveTop(); } - moveRight() { + moveRight(): void { this.cycleClockDiagram.moveRight(); } - moveLeft() { + moveLeft(): void { this.cycleClockDiagram.moveLeft(); } - nextStep() { + nextStep(): void { this.cycleClockDiagram.nextStep(); } - nextStepX10() { + nextStepX10(): void { for (let i = 0; i < 10; i++) { this.cycleClockDiagram.nextStep(); } } - addArrow(instructionArrow: TypeArrowDirection) { + addArrow(instructionArrow: TypeArrowDirection): void { this.cycleClockDiagram.addArrow(instructionArrow); } - reset() { + reset(): void { this.cycleClockDiagram.reset(); } - debug() { + debug(): void { this.cycleClockDiagram.addInstruction("instruction 1"); this.cycleClockDiagram.addInstruction("instruction 2"); this.cycleClockDiagram.addInstruction("instruction 3"); this.cycleClockDiagram.addInstruction("instruction 4"); } - private resize() { + private resize(): void { const width = this.pixiContainer.nativeElement.offsetWidth; let height = this.pixiContainer.nativeElement.offsetHeight; - height = height === 0 ? 900 : height + height = height === 0 ? 900 : height; this.pApp.renderer.resize(width, height); this.cycleClockDiagram.borderTopWidth = width; this.cycleClockDiagram.borderLeftHeight = height; diff --git a/src/app/components/pixi-pipeline/pixi-pipeline.component.ts b/src/app/components/pixi-pipeline/pixi-pipeline.component.ts index efbbabf..3faebfa 100644 --- a/src/app/components/pixi-pipeline/pixi-pipeline.component.ts +++ b/src/app/components/pixi-pipeline/pixi-pipeline.component.ts @@ -2,6 +2,7 @@ import * as PIXI from "pixi.js"; import { AfterViewInit, Component, HostListener, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { MachineService } from "../../__core/machine/machine.service"; import { PixiTHUMDER_Pipeline } from "../../__core/machine/PixiTHUMDER_Pipeline"; +import { Utils } from "../../Utils"; @Component({ selector: 'thumder-pixi-pipeline', @@ -15,9 +16,9 @@ export class PixiPipelineComponent implements OnInit, AfterViewInit, OnDestroy { private pipeline: PixiTHUMDER_Pipeline; constructor(private machine: MachineService) { - let faddEX_count = machine.floatingPointStageConfiguration.addition.count; - let fmultEX_count = machine.floatingPointStageConfiguration.multiplication.count; - let fdivEX_count = machine.floatingPointStageConfiguration.division.count; + const faddEX_count = machine.floatingPointStageConfiguration.addition.count; + const fmultEX_count = machine.floatingPointStageConfiguration.multiplication.count; + const fdivEX_count = machine.floatingPointStageConfiguration.division.count; this.pipeline = new PixiTHUMDER_Pipeline(faddEX_count, fmultEX_count, fdivEX_count); } @@ -26,7 +27,8 @@ export class PixiPipelineComponent implements OnInit, AfterViewInit, OnDestroy { this.machine.getStepSimulationObservable().subscribe((stepSimulation) => { const list_elements = this.machine.getListStatusPipeline(stepSimulation); for (const e of list_elements) { - const instruction = this.machine.getTableCode(e.address).instruction; + const code = this.machine.getTableCode(e.address).code; + const instruction = Utils.convertHexCodeToTextMachineInstructionDLX(code); switch (e.stage) { case "IF": this.pipeline.update_IF_text(instruction); @@ -60,8 +62,8 @@ export class PixiPipelineComponent implements OnInit, AfterViewInit, OnDestroy { } ngAfterViewInit(): void { - let width = 1600; - let height = 975; + const width = 1600; + const height = 975; this.pApp = new PIXI.Application({ width: width, height: height, @@ -85,40 +87,9 @@ export class PixiPipelineComponent implements OnInit, AfterViewInit, OnDestroy { this.resize(); } - @HostListener('document:keypress', ['$event']) - handleKeyboardEvent(event: KeyboardEvent) { - event.preventDefault(); - event.stopPropagation(); - switch (event.key) { - case '1': - this.pipeline.update_IF_text("Prueba"); - break; - case '2': - this.pipeline.update_ID_text("Prueba"); - break; - case '3': - this.pipeline.update_intEX_text("Prueba"); - break; - case '4': - this.pipeline.update_faddEX_text(0, "Prueba"); - break; - case '5': - this.pipeline.update_fmultEX_text(0, "Prueba"); - break; - case '6': - this.pipeline.update_fdivEX_text(0, "Prueba"); - break; - case '7': - this.pipeline.update_MEM_text("Prueba"); - break; - case '8': - this.pipeline.update_WB_text("Prueba"); - break; - } - } private resize() { - let width = this.pixiContainer.nativeElement.offsetWidth; + const width = this.pixiContainer.nativeElement.offsetWidth; let height = this.pixiContainer.nativeElement.offsetHeight; height = height === 0 ? 900 : height; this.pApp.renderer.resize(width, height); diff --git a/src/app/components/sidebar/sidebar.component.ts b/src/app/components/sidebar/sidebar.component.ts index 5b50767..ee4cc4e 100644 --- a/src/app/components/sidebar/sidebar.component.ts +++ b/src/app/components/sidebar/sidebar.component.ts @@ -10,10 +10,10 @@ export class SidebarComponent implements OnInit { constructor() { } - ngOnInit() { + ngOnInit(): void { } - toggleCollapseShow(classes) { + toggleCollapseShow(classes): void { this.collapseShow = classes; } } diff --git a/src/app/components/xterm/xterm.component.ts b/src/app/components/xterm/xterm.component.ts index 8af3111..60d1191 100644 --- a/src/app/components/xterm/xterm.component.ts +++ b/src/app/components/xterm/xterm.component.ts @@ -1,11 +1,19 @@ -import { OnInit, AfterViewInit, Component, Input, Output, ElementRef, ViewChild } from '@angular/core'; +import { + Component, + Input, + Output, + EventEmitter, + OnInit, + AfterViewInit, + ElementRef, + ViewChild, + SimpleChanges +} from '@angular/core'; import { Terminal } from 'xterm'; -import { AttachAddon } from 'xterm-addon-attach'; -import { WebLinksAddon } from 'xterm-addon-web-links'; -// import { LigaturesAddon } from 'xterm-addon-ligatures'; import { SearchAddon } from 'xterm-addon-search'; import { WebglAddon } from 'xterm-addon-webgl'; -import { EventEmitter } from "events"; +import { TypeOnKeyEvent } from "../../types"; + @Component({ selector: 'thumder-xterm', @@ -15,7 +23,7 @@ import { EventEmitter } from "events"; export class XtermComponent implements OnInit, AfterViewInit { @ViewChild('myTerminal') terminalDiv: ElementRef; @Input() data = ''; - @Output() newEvent = new EventEmitter(); + @Output() onKey = new EventEmitter(); terminal: Terminal; @@ -23,22 +31,38 @@ export class XtermComponent implements OnInit, AfterViewInit { this.terminal = new Terminal({ theme: {background: '#090c0f'}, bellStyle: 'sound', - altClickMovesCursor: true + altClickMovesCursor: true, + cols: 120, + rendererType: "canvas" }); } ngOnInit(): void { } + ngOnChanges(changes: SimpleChanges): void { + const currentValue = changes.data.currentValue; + if (currentValue) { + for (let i = 1; i < this.terminal.rows; i++) { + this.terminal.scrollToLine(i); + this.terminal.selectLines(i - 1, i); + this.terminal.clearSelection(); + } + this.terminal.write(currentValue); + } + } + ngAfterViewInit(): void { this.terminal.open(this.terminalDiv.nativeElement); + // this.terminal.loadAddon(new AttachAddon()); // this.terminal.loadAddon(new WebLinksAddon(handler)); // this.terminal.loadAddon(new LigaturesAddon()); this.terminal.loadAddon(new SearchAddon()); this.terminal.loadAddon(new WebglAddon()); - this.terminal.writeln('Welcome to THUMDER\n') + //this.terminal.writeln(this.data) + this.terminal.writeln('Welcome to THUMDER\n'); this.terminal.write('$ '); this.terminal.onKey((e) => { @@ -53,6 +77,7 @@ export class XtermComponent implements OnInit, AfterViewInit { default: this.terminal.write(e.key); } + this.onKey.emit(e); }); } diff --git a/src/app/types.ts b/src/app/types.ts index 82f1097..ab2224b 100644 --- a/src/app/types.ts +++ b/src/app/types.ts @@ -1,7 +1,8 @@ -import { Registers } from "./__core/DLX/_Registers"; -import { Double64, Float32, Int32 } from "./__core/typesData"; import { TypeCycleType } from "./__core/machine/PixiTHUMDER_CycleClockDiagram"; import { InterfaceMemory, InterfaceRegisters } from "./__core/DLX/interfaces"; +import firebase from "firebase/app"; +import Timestamp = firebase.firestore.Timestamp; +import { BreakpointManager } from "./__core/machine/debugger/BreakpointManager"; declare global { interface Window { @@ -12,7 +13,18 @@ declare global { } } -export interface User { +export type TypeComponentStatus = "OnInit" | "AfterViewInit" | "OnDestroy"; + +export type TypeOnKeyEvent = { + domEvent: KeyboardEvent; + key: string; +}; + +export type TypeExtrasIDE = { + interfaceFileItem: InterfaceFileItem; +}; + +export interface InterfaceUser { uid: string; email: string; displayName: string; @@ -20,6 +32,26 @@ export interface User { emailVerified: boolean; } +export interface InterfaceFileItem { + $key?: string // ---? Firebase + f_id: string //- + e1_uid: string //- + + key: string //- + pathKeys: string[] //- + + path: string + name: string + content: string + description: string + dateModified: Timestamp + size: number + isDirectory: boolean + hasSubDirectories: boolean + thumbnail: string + dataItem: any +} + export type StringOfLength = string & { readonly StringOfLength: unique symbol // this is the phantom type @@ -45,23 +77,23 @@ export function stringOfLength(input: un } export type TypeTransformDecimalToBase = { - base: number, - maxLength?: number, + base: number; + maxLength?: number; fillString?: string }; export type TypeTags = { - line: number, + line: number; content: string -}[] +}[]; export type PublicRoutes = { - lang: string, - path: string, - routerLink: string, - displayName: string, + lang: string; + path: string; + routerLink: string; + displayName: string; data?: any; - children?: PublicRoutes[], + children?: PublicRoutes[]; }; export type PublicRoutesList = PublicRoutes[]; @@ -72,33 +104,34 @@ export type TypeRegister = "Control" | "Integer" | "Float" | "Double"; export type TypeDataRegister = { Control: { - registers: number, - size: number, - maxLengthHexadecimal: number, - }, + registers: number; + size: number; + maxLengthHexadecimal: number; + }; Integer: { - registers: number, - size: number, - maxLengthHexadecimal: number, - }, + registers: number; + size: number; + maxLengthHexadecimal: number; + }; Float: { - registers: number, - size: number, - maxLengthHexadecimal: number, - }, + registers: number; + size: number; + maxLengthHexadecimal: number; + }; Double: { - registers: number, - size: number, - maxLengthHexadecimal: number, - }, + registers: number; + size: number; + maxLengthHexadecimal: number; + }; DEFAULT: { - registers: number, - size: number, - maxLengthHexadecimal: number, + registers: number; + size: number; + maxLengthHexadecimal: number; } -} +}; -export type TypeRegisterToEdit = "PC" +export type TypeRegisterToEdit = + "PC" | "IMAR" | "IR" | "A" @@ -145,146 +178,154 @@ export type TypeStage = | "faddEX_7" | "fmultEX_7" | "fdivEX_7"; export type TypeTableCode = { - text: string, - address: string, - instruction: string, // 0x00000000 - code: string, // 0x00000000 - stage: TypeStage - index?: number, -} + text: string; + address: string; + instruction: string; // 0x00000000 + code: string; // 0x00000000 + stage: TypeStage; + index?: number; +}; + export type TypeCode = { - text: string, - address: string, // 0x00000000 - instruction: string, - code: string, // 0x00000000 -} + text: string; + address: string; // 0x00000000 + instruction: string; + code: string; // 0x00000000 +}; export type TypeFloatingPointStageConfiguration = { addition: { - count: number, - delay: number - }, + count: number; + delay: number; + }; multiplication: { - count: number, - delay: number - }, + count: number; + delay: number; + }; division: { - count: number, - delay: number + count: number; + delay: number; } -} -export type TypeLang = 'en' | 'sp'; +}; +export type TypeLang = 'en' | 'sp'; export type TypeStatusPipeline = { address: string; - stage: TypeStage, - unit?: number -} + stage: TypeStage; + unit?: number; +}; export type TypeStatusCycleClockDiagram = { - step: number + step: number; instruction: string; - cycle: TypeCycleType, - stepsToWait: number -} + cycle: TypeCycleType; + stepsToWait: number; +}; export type TypeStatusMachine = { - codeText: string, - registers: InterfaceRegisters, - memory: InterfaceMemory, - tagsDebugger: TypeTags, -} + registers: InterfaceRegisters; + memory: InterfaceMemory; + breakpoints: BreakpointManager; + [data: string]: any +}; export type TypePipeline = { // Address - IF: string, - ID: string, - intEX: string, - faddEX: { unit: number, address: string }[], - fmultEX: { unit: number, address: string }[], - fdivEX: { unit: number, address: string }[], - MEM: string, - WB: string, -} + IF: string; + ID: string; + intEX: string; + faddEX: { unit: number; address: string }[]; + fmultEX: { unit: number; address: string }[]; + fdivEX: { unit: number; address: string }[]; + MEM: string; + WB: string; +}; -export type StepSimulation = { - step: number, - instruction: string, - steps: number, +export type TypeStepSimulation = { + step: number; + instruction: string; + codeInstruction: string; + line: number; + isComplete?: boolean; stage: TypeStage; - IF_stall: number, - IF: number, - ID_stall: number, - ID: number, - intEX_stall: number, - intEX: number, - MEM_stall: number, - MEM: number, - WB_stall: number, - WB: number, - - pipeline: TypePipeline, - - registers: { register: string, value: string, }[], - - memory: { address: string, value: string, }[] + IF: number; + IF_stall: number; + ID: number; + ID_stall: number; + intEX: number; + intEX_stall: number; + MEM: number; + MEM_stall: number; + WB: number; + WB_stall: number; + + pipeline: TypePipeline; + registers: { + register: string; + value: string; + }[]; + memory: { + typeData: "byte" | "halfword" | "word" | "float" | "double"; + address: string; + value: string; + }[]; }; export type SimulationResponse = { - name_file: string, - date: string, - steps: number, + name_file: string; + date: string; + steps: number; + lines: number; - code: TypeTableCode[], - - runner: StepSimulation[] -} + code: TypeTableCode[]; + runner: TypeStepSimulation[]; +}; export type TypeDataStatistics = { TOTAL: { - CYCLES_EXECUTED: { cycles: number }, - ID_EXECUTED: { instructions: number }, - INSTRUCTIONS_IN_PIPELINE: { instructions_in_pipeline: number }, - }, + CYCLES_EXECUTED: { cycles: number }; + ID_EXECUTED: { instructions: number }; + INSTRUCTIONS_IN_PIPELINE: { instructions_in_pipeline: number }; + }; HARDWARE: { - MEMORY_SIZE: { size: number }, - FADD_EX_STAGES: { num: number, cycles: number }, - FMULT_EX_STAGES: { num: number, cycles: number }, - FDIV_EX_STAGES: { num: number, cycles: number }, - FORWARDING: { enabled: boolean }, - }, + MEMORY_SIZE: { size: number }; + FADD_EX_STAGES: { num: number; cycles: number }; + FMULT_EX_STAGES: { num: number; cycles: number }; + FDIV_EX_STAGES: { num: number; cycles: number }; + FORWARDING: { enabled: boolean }; + }; STALLS: { - RAW_STALLS: { num: number, per: number }, - LD_STALLS: { num: number, per: number }, - BRANCH_STALLS: { num: number, per: number }, - FLOATING_POINT_STALLS: { num: number, per: number }, - WAW_STALLS: { num: number, per: number }, - STRUCTURAL_STALLS: { num: number, per: number }, - CONTROL_STALLS: { num: number, per: number }, - TRAP_STALLS: { num: number, per: number }, - TOTAL: { num: number, per: number }, - }, + RAW_STALLS: { num: number; per: number }; + LD_STALLS: { num: number; per: number }; + BRANCH_STALLS: { num: number; per: number }; + FLOATING_POINT_STALLS: { num: number; per: number }; + WAW_STALLS: { num: number; per: number }; + STRUCTURAL_STALLS: { num: number; per: number }; + CONTROL_STALLS: { num: number; per: number }; + TRAP_STALLS: { num: number; per: number }; + TOTAL: { num: number; per: number }; + }; CONDITIONAL: { - TOTAL: { num: number, per: number }, - TAKEN: { num: number, per: number }, - NOT_TAKEN: { num: number, per: number }, - }, + TOTAL: { num: number; per: number }; + TAKEN: { num: number; per: number }; + NOT_TAKEN: { num: number; per: number }; + }; LOAD_STORE: { - TOTAL: { num: number, per: number }, - LOADS: { num: number, per: number }, - STORES: { num: number, per: number }, - }, + TOTAL: { num: number; per: number }; + LOADS: { num: number; per: number }; + STORES: { num: number; per: number }; + }; FLOATING: { - TOTAL: { num: number, per: number }, - ADDITIONS: { num: number, per: number }, - MULTIPLICATIONS: { num: number, per: number }, - DIVISIONS: { num: number, per: number }, - }, + TOTAL: { num: number; per: number }; + ADDITIONS: { num: number; per: number }; + MULTIPLICATIONS: { num: number; per: number }; + DIVISIONS: { num: number; per: number }; + }; TRAPS: { - TOTAL: { num: number, per: number }, + TOTAL: { num: number; per: number }; } -} +}; diff --git a/src/app/views/_auth/_views/multiples-views.component.html b/src/app/views/_auth/_views/multiples-views.component.html new file mode 100644 index 0000000..22c2498 --- /dev/null +++ b/src/app/views/_auth/_views/multiples-views.component.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/app/views/_auth/_views/multiples-views.component.ts b/src/app/views/_auth/_views/multiples-views.component.ts new file mode 100644 index 0000000..e62a89e --- /dev/null +++ b/src/app/views/_auth/_views/multiples-views.component.ts @@ -0,0 +1,23 @@ +import { AfterViewInit, Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'view-multiples-views', + templateUrl: './multiples-views.component.html', + styleUrls: [] +}) +export class MultiplesViewsComponent implements OnInit, AfterViewInit { + + constructor() { + } + + ngOnInit(): void { + } + + ngAfterViewInit(): void { + MultiplesViewsComponent.closeAllCards(); + } + + private static closeAllCards() { + window.jQuery('.card').CardWidget('collapse'); + } +} diff --git a/src/app/views/_auth/calculator/calculator.view.ts b/src/app/views/_auth/calculator/calculator.view.ts index 1bf3b9a..7dddb2d 100644 --- a/src/app/views/_auth/calculator/calculator.view.ts +++ b/src/app/views/_auth/calculator/calculator.view.ts @@ -15,7 +15,7 @@ export class CalculatorView implements OnInit { private _value32Float: string = DEFAULT_BINARY_32_BITS; private _value64Double: string = DEFAULT_BINARY_64_BITS; - get binary08_Value() { + get binary08_Value(): number { return parseInt(this._valueByte[0].toString(2), 2); } @@ -23,7 +23,7 @@ export class CalculatorView implements OnInit { this._valueByte[0] = value; } - get binary08_Hexadecimal() { + get binary08_Hexadecimal(): string { return parseInt(this._valueByte[0].toString(2), 2).toString(16).padStart(2, '0').toUpperCase(); } @@ -31,7 +31,7 @@ export class CalculatorView implements OnInit { this._valueByte[0] = parseInt(value, 16); } - get binary08_Binary() { + get binary08_Binary(): string { return this._valueByte[0].toString(2).padStart(8, '0'); } @@ -41,7 +41,7 @@ export class CalculatorView implements OnInit { // ================================================================================================================== - get binary16_Value() { + get binary16_Value(): number { return parseInt(this._valueHalfWord[0].toString(2), 2); } @@ -49,7 +49,7 @@ export class CalculatorView implements OnInit { this._valueHalfWord[0] = value; } - get binary16_Hexadecimal() { + get binary16_Hexadecimal(): string { return parseInt(this._valueHalfWord[0].toString(2), 2).toString(16).padStart(4, '0').toUpperCase(); } @@ -57,7 +57,7 @@ export class CalculatorView implements OnInit { this._valueHalfWord[0] = parseInt(value, 16); } - get binary16_Binary() { + get binary16_Binary(): string { return this._valueHalfWord[0].toString(2).padStart(16, '0'); } @@ -67,7 +67,7 @@ export class CalculatorView implements OnInit { // ================================================================================================================== - get binary32_Value() { + get binary32_Value(): number { return parseInt(this._valueWord[0].toString(2), 2); } @@ -75,7 +75,7 @@ export class CalculatorView implements OnInit { this._valueWord[0] = value; } - get binary32_Hexadecimal() { + get binary32_Hexadecimal(): string { return parseInt(this._valueWord[0].toString(2), 2).toString(16).padStart(8, '0').toUpperCase(); } @@ -83,7 +83,7 @@ export class CalculatorView implements OnInit { this._valueWord[0] = parseInt(value, 16); } - get binary32_Binary() { + get binary32_Binary() : string{ return this._valueWord[0].toString(2).padStart(32, '0'); } @@ -92,7 +92,7 @@ export class CalculatorView implements OnInit { } // ================================================================================================================== - get binary32_IEEE754_Value() { + get binary32_IEEE754_Value() : number{ return Utils.convertIEEE754_Binary32Bits_To_Number(this._value32Float); } @@ -100,7 +100,7 @@ export class CalculatorView implements OnInit { this._value32Float = Utils.convertIEEE754_Number_To_Binary32Bits(value); } - get binary32_IEEE754_Hexadecimal() { + get binary32_IEEE754_Hexadecimal() : string{ return parseInt(this._value32Float, 2).toString(16).padStart(8, '0').toUpperCase(); } @@ -108,7 +108,7 @@ export class CalculatorView implements OnInit { this._value32Float = parseInt(value, 16).toString(2).padStart(32, '0'); } - get binary32_IEEE754_Binary() { + get binary32_IEEE754_Binary(): string { return this._value32Float; } @@ -117,7 +117,7 @@ export class CalculatorView implements OnInit { } // ================================================================================================================== - get binary64_IEEE754_Value() { + get binary64_IEEE754_Value() : number{ return Utils.convertIEEE754_Binary64Bits_To_Number(this._value64Double); } @@ -125,7 +125,7 @@ export class CalculatorView implements OnInit { this._value64Double = Utils.convertIEEE754_Number_To_Binary64Bits(value); } - get binary64_IEEE754_Hexadecimal() { + get binary64_IEEE754_Hexadecimal(): string { return parseInt(this._value64Double, 2).toString(16).padStart(16, '0').toUpperCase(); } @@ -133,7 +133,7 @@ export class CalculatorView implements OnInit { this._value64Double = parseInt(value, 16).toString(2).padStart(64, '0'); } - get binary64_IEEE754_Binary() { + get binary64_IEEE754_Binary(): string { return this._value64Double; } diff --git a/src/app/views/_auth/code/code.view.ts b/src/app/views/_auth/code/code.view.ts index 6934122..9256b92 100644 --- a/src/app/views/_auth/code/code.view.ts +++ b/src/app/views/_auth/code/code.view.ts @@ -20,7 +20,7 @@ export class CodeView implements OnInit, AfterViewInit, OnDestroy { private privateStep = 0; constructor(public machine: MachineService) { - this.dataSourceCode.filter = null + this.dataSourceCode.filter = null; this.dataSourceCode.sort = this.sort; } @@ -33,11 +33,11 @@ export class CodeView implements OnInit, AfterViewInit, OnDestroy { stage: "", instruction: "NOP", code: "0x00000000" - } + }; }); - this.machine.getStepObservable().subscribe((realStep) => { - this.privateStep = realStep; + this.machine.getStepObservable().subscribe((step) => { + this.privateStep = step; }); this.machine.getCodeSimulationObservable().subscribe((typeTableCode) => { @@ -62,7 +62,7 @@ export class CodeView implements OnInit, AfterViewInit, OnDestroy { } ngAfterViewInit(): void { - const array = Utils.MapToArray(this.machine.code) + const array = Utils.MapToArray(this.machine.code); for (const code_memory of array) { const index = Utils.addressToIndex(code_memory.value.address); const stage = code_memory.value.stage; @@ -71,9 +71,9 @@ export class CodeView implements OnInit, AfterViewInit, OnDestroy { instruction: code_memory.value.instruction, code: code_memory.value.code, text: code_memory.value.text - } + }; - this.setRow(index, code, stage) + this.setRow(index, code, stage); } } @@ -90,12 +90,12 @@ export class CodeView implements OnInit, AfterViewInit, OnDestroy { * */ - refreshDataSourceCode() { + refreshDataSourceCode(): void { this.dataSourceCode.filter = null; this.dataSourceCode.data = [...this.dataSourceCode.data]; } - setRow(index: number, tableCode: TypeCode, stage: TypeStage = "") { + setRow(index: number, tableCode: TypeCode, stage: TypeStage = ""): void { this.dataSourceCode.data[index] = { text: tableCode.text, address: tableCode.address, @@ -108,119 +108,4 @@ export class CodeView implements OnInit, AfterViewInit, OnDestroy { this.refreshDataSourceCode(); } - /** - * - ["IF", "--", "--", "--", "--", "--", "--", "--", "--", "--", "--"] - ["ID", "IF", "--", "--", "--", "--", "--", "--", "--", "--", "--"] - ["EX", "ID", "IF", "--", "--", "--", "--", "--", "--", "--", "--"] - ["ME", "EX", "ID", "IF", "--", "--", "--", "--", "--", "--", "--"] - ["WB", "ME", "EX", "ID", "IF", "--", "--", "--", "--", "--", "--"] - ["--", "WB", "ME", "EX", "ID", "IF", "--", "--", "--", "--", "--"] - ["--", "--", "WB", "ME", "EX", "ID", "IF", "--", "--", "--", "--"] - ["--", "--", "--", "WB", "ME", "EX", "ID", "IF", "--", "--", "--"] - ["--", "--", "--", "--", "WB", "ME", "EX", "ID", "IF", "--", "--"] - ["--", "--", "--", "--", "--", "WB", "ME", "EX", "ID", "IF", "--"] - ["--", "--", "--", "--", "--", "xx", "WB", "ME", "EX", "ID", "IF"] - ["IF", "--", "--", "--", "--", "--", "--", "WB", "ME", "EX", "ID"] - ["ID", "IF", "--", "--", "--", "--", "--", "--", "WB", "ME", "EX"] - ["EX", "ID", "IF", "--", "--", "--", "--", "--", "--", "WB", "ME"] - ["ME", "EX", "ID", "IF", "--", "--", "--", "--", "--", "--", "WB"] - ["WB", "ME", "EX", "ID", "IF", "--", "--", "--", "--", "--", "--"] - */ - test() { - - // i_clear = 0; - // i_if = 0; - // i_id = 0; - // i_ex = 0; - // i_me = 0; - // i_wb = 0; - - // const step_test: { step: number, data: TypeTableCode[] }[] - // = [ - // { - // step: 0, - // data: [] - // }, - // { - // step: 1, - // data: [ - // {"address": 256, "stage": "IF", "text": "$TEXT", "instruction": "addi r1, r0, 0x00"} - // ] - // }, - // { - // step: 2, - // data: [ - // {"address": 256, "stage": "ID", "text": "$TEXT", "instruction": "addi r1, r0, 0x0"}, - // {"address": 260, "stage": "IF", "text": "main+0x4", "instruction": "addi r1, r0, 0x2"} - // ] - // }, - // { - // step: 3, - // data: [ - // {"address": 256, "stage": "intEX", "text": "$TEXT", "instruction": "addi r1, r0, 0x0"}, - // {"address": 260, "stage": "ID", "text": "main+0x4", "instruction": "addi r1, r0, 0x2"}, - // {"address": 264, "stage": "IF", "text": "main+0x8", "instruction": "addi r16, r0, 0x10"} - // ] - // }, - // { - // step: 4, - // data: [ - // {"address": 256, "stage": "MEM", "text": "$TEXT", "instruction": "addi r1, r0, 0x0"}, - // {"address": 260, "stage": "intEX", "text": "main+0x4", "instruction": "addi r1, r0, 0x2"}, - // {"address": 264, "stage": "ID", "text": "main+0x8", "instruction": "addi r16, r0, 0x10"}, - // {"address": 268, "stage": "IF", "text": "main+0xc", "instruction": "addi r18, r0, 0x8"} - // ] - // }, - // { - // step: 5, - // data: [ - // {"address": 256, "stage": "WB", "text": "$TEXT", "instruction": "addi r1, r0, 0x0"}, - // {"address": 260, "stage": "MEM", "text": "main+0x4", "instruction": "addi r1, r0, 0x2"}, - // {"address": 264, "stage": "intEX", "text": "main+0x8", "instruction": "addi r16, r0, 0x10"}, - // {"address": 268, "stage": "ID", "text": "main+0xc", "instruction": "addi r18, r0, 0x8"}, - // {"address": 272, "stage": "IF", "text": "NextValue", "instruction": "addi r3, r0, 0x0"} - // ] - // } - // ]; - // const stages: TypeStage[] = ['', 'IF', 'ID', 'intEX', 'MEM', 'WB', 'trap']; - // const stages_reverse: TypeStage[] = ['IF', 'ID', 'intEX', 'MEM', 'WB', '']; - - // this.array_test.push({line: 0, address: 0, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 1, address: 1, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 2, address: 2, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 3, address: 3, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 4, address: 4, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 5, address: 5, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 6, address: 6, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 7, address: 7, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 8, address: 8, code: 123, stage: stages[0], instruction: "add r2, r2, #0"}) - // this.array_test.push({line: 9, address: 9, code: 123, stage: stages[0], instruction: "trap"}) - - // this.array_test[this.i_clear].stage = stages_reverse[5]; - // this.array_test[this.i_wb].stage = stages_reverse[4]; - // this.array_test[this.i_me].stage = stages_reverse[3]; - // this.array_test[this.i_ex].stage = stages_reverse[2]; - // this.array_test[this.i_id].stage = stages_reverse[1]; - // this.array_test[this.i_if].stage = stages_reverse[0]; - // - // this.i_if = Utils.modNotNegative((this.i_if + 1), this.array_test.length); - // this.i_wb = Utils.modNotNegative((this.i_if - 4), this.array_test.length); - // this.i_me = Utils.modNotNegative((this.i_if - 3), this.array_test.length); - // this.i_ex = Utils.modNotNegative((this.i_if - 2), this.array_test.length); - // this.i_id = Utils.modNotNegative((this.i_if - 1), this.array_test.length); - // - // if (this.i_clear < this.array_test.length) { - // if (this.i_clear > 0) { - // this.i_clear = Utils.modNotNegative((this.i_clear + 1), this.array_test.length); - // this.i_if = Utils.modNotNegative((this.i_clear + 5), this.array_test.length); - // this.i_id = Utils.modNotNegative((this.i_clear + 4), this.array_test.length); - // this.i_ex = Utils.modNotNegative((this.i_clear + 3), this.array_test.length); - // this.i_me = Utils.modNotNegative((this.i_clear + 2), this.array_test.length); - // this.i_wb = Utils.modNotNegative((this.i_clear + 1), this.array_test.length); - // } else { - // this.i_clear = Utils.modNotNegative((this.i_if - 5), this.array_test.length); - // } - // } - } } diff --git a/src/app/views/_auth/config/config.view.html b/src/app/views/_auth/config/config.view.html index 00039e5..e6d6256 100644 --- a/src/app/views/_auth/config/config.view.html +++ b/src/app/views/_auth/config/config.view.html @@ -13,6 +13,10 @@

{{ 'CONFIG.FLOATING_POINT_STAGE_CONFIGURATION' | translat
+ +

{{ 'CONFIG.MESSAGE_1_FLOATING_POINT_STAGE_CONFIGURATION' | translate }}

+

{{ 'CONFIG.MESSAGE_2_FLOATING_POINT_STAGE_CONFIGURATION' | translate }}

+ @@ -79,21 +83,52 @@

{{ 'CONFIG.FLOATING_POINT_STAGE_CONFIGURATION' | translat class="form-control" min="512" max="1048576" step="8">

-
-

{{ 'CONFIG.MESSAGE_1_FLOATING_POINT_STAGE_CONFIGURATION' | translate }}

-

{{ 'CONFIG.MESSAGE_2_FLOATING_POINT_STAGE_CONFIGURATION' | translate }}

+ + + {{ 'CONFIG.AUTO_SAVE' | translate }} + + + {{ 'CONFIG.AUTO_SAVE' | translate }} + +
+ + +
+ + + + + + {{ 'CONFIG.TIME_SIMULATION' | translate }} + + + {{ 'CONFIG.TIME_SIMULATION' | translate }} + + + + + + -
- - -
- + diff --git a/src/app/views/_auth/config/config.view.ts b/src/app/views/_auth/config/config.view.ts index d18f997..2215f3b 100644 --- a/src/app/views/_auth/config/config.view.ts +++ b/src/app/views/_auth/config/config.view.ts @@ -1,11 +1,16 @@ import { Component, OnInit } from '@angular/core'; import { TypeFloatingPointStageConfiguration } from "../../../types"; import { StorageService } from "../../../__core/storage/storage.service"; -import { DEFAULT_FLOATING_POINT_STAGE_CONFIGURATION, DEFAULT_MEMORY_SIZE } from "../../../CONSTAST"; +import { + DEFAULT_AUTO_SAVE, + DEFAULT_FLOATING_POINT_STAGE_CONFIGURATION, + DEFAULT_MEMORY_SIZE, + DEFAULT_TIME_SIMULATION +} from "../../../CONSTAST"; import { MachineService } from "../../../__core/machine/machine.service"; interface EventTargetInput extends EventTarget { - value: string | number; + value: string | number | boolean; } @Component({ @@ -17,11 +22,15 @@ export class ConfigView implements OnInit { floatingPointStageConfiguration: TypeFloatingPointStageConfiguration; memorySize: number; + timeSimulation: number; + autoSave: boolean; constructor(private storage: StorageService, private machine: MachineService) { this.floatingPointStageConfiguration = this.storage.getItem('floating_point_stage_configuration'); this.memorySize = this.storage.getItem('memory_size'); + this.timeSimulation = this.storage.getItem('time_simulation'); + this.autoSave = this.storage.getItem('auto_save'); } ngOnInit(): void { @@ -33,23 +42,36 @@ export class ConfigView implements OnInit { case 'memory_size': this.memorySize = this.storage.getItem('memory_size'); break; + case 'time_simulation': + this.timeSimulation = this.storage.getItem('time_simulation'); + break; + case 'auto_save': + this.autoSave = this.storage.getItem('auto_save'); + break; } - }) + }); } - async updateConfiguration() { + async updateConfiguration(): Promise { this.storage.setItem('floating_point_stage_configuration', this.floatingPointStageConfiguration); this.storage.setItem('memory_size', this.memorySize); + this.storage.setItem('time_simulation', this.timeSimulation); + this.storage.setItem('auto_save', this.autoSave); await this.machine.resetMachineStatus(); + return Promise.resolve(); } - resetConfiguration() { + async resetConfiguration(): Promise { this.storage.setItem('floating_point_stage_configuration', DEFAULT_FLOATING_POINT_STAGE_CONFIGURATION); this.storage.setItem('memory_size', DEFAULT_MEMORY_SIZE); + this.storage.setItem('time_simulation', DEFAULT_TIME_SIMULATION); + this.storage.setItem('auto_save', DEFAULT_AUTO_SAVE); + await this.machine.resetMachineStatus(); + return Promise.resolve(); } - checkCount(target: EventTargetInput | any) { - const count = parseInt(target.value.toString()) + checkCount(target: EventTargetInput | any): void { + const count = parseInt(target.value.toString()); if (count >= 1 && count <= 8) { target.value = count; } else { @@ -57,8 +79,8 @@ export class ConfigView implements OnInit { } } - checkDelay(target: EventTargetInput | any) { - const delay = parseInt(target.value.toString()) + checkDelay(target: EventTargetInput | any): void { + const delay = parseInt(target.value.toString()); if (delay >= 1 && delay <= 50) { target.value = delay; } else { @@ -66,12 +88,20 @@ export class ConfigView implements OnInit { } } - checkMemorySize(target: EventTargetInput | any) { - const size = parseInt(target.value.toString()) + checkMemorySize(target: EventTargetInput | any): void { + const size = parseInt(target.value.toString()); if (size >= 512 && size <= 1048576) { target.value = size; } else { target.value = 1; } } + + updateAutoSave(target: EventTargetInput | any) { + this.autoSave = target.checked ?? false; + } + + updateTimeSimulation(target: EventTargetInput | any) { + this.timeSimulation = parseInt(target.value.toString()) + } } diff --git a/src/app/views/_auth/docs/docs.view.ts b/src/app/views/_auth/docs/docs.view.ts index 310d8f2..a75c2de 100644 --- a/src/app/views/_auth/docs/docs.view.ts +++ b/src/app/views/_auth/docs/docs.view.ts @@ -27,7 +27,7 @@ export class DocsView implements OnInit { ngOnDestroy(): void { } - public onMarkdownLoad() { + public onMarkdownLoad(): void { // because MarkdownComponent isn't 'compiled' the links don't use the angular router, // so I'll catch the link click events here and pass them to the router... if (this.markdownComponentID) { @@ -45,7 +45,7 @@ export class DocsView implements OnInit { } } - scrollToAnchor(scrollToAnchor: string) { + scrollToAnchor(scrollToAnchor: string): void { this.scroller.scrollToAnchor(scrollToAnchor); } } diff --git a/src/app/views/_auth/file-manager/file-manager.view.html b/src/app/views/_auth/file-manager/file-manager.view.html index be7dbe6..d24b54d 100644 --- a/src/app/views/_auth/file-manager/file-manager.view.html +++ b/src/app/views/_auth/file-manager/file-manager.view.html @@ -64,7 +64,6 @@ - - -
-
-

Xterm

-
- - -
-
- -
-
- -
-
- - -
diff --git a/src/app/views/_auth/ide/ide.view.ts b/src/app/views/_auth/ide/ide.view.ts index 88bb7ef..74de515 100644 --- a/src/app/views/_auth/ide/ide.view.ts +++ b/src/app/views/_auth/ide/ide.view.ts @@ -1,63 +1,121 @@ -import { Component, Inject, OnInit, ViewChild } from "@angular/core"; -import { MonacoEditorComponent } from "../../../components/monaco-editor/monaco-editor.component"; -import { XtermComponent } from "../../../components/xterm/xterm.component"; +import { AfterViewInit, Component, Inject, OnDestroy, OnInit, ViewChild } from "@angular/core"; +import { Router } from "@angular/router"; import { DOCUMENT } from "@angular/common"; +import { MonacoEditorComponent } from "../../../components/monaco-editor/monaco-editor.component"; +import { TypeExtrasIDE } from "../../../types"; +import { FileSystemService } from "../../../__core/services/file-system-nonodev96/file-system.service"; +import { Utils } from "../../../Utils"; +import { ToastrService } from "ngx-toastr"; +import { TranslateService } from "@ngx-translate/core"; +import { MachineService } from "../../../__core/machine/machine.service"; @Component({ selector: "view-ide", templateUrl: "./ide.view.html", styleUrls: [] }) -export class IDEView implements OnInit { +export class IDEView implements OnInit, AfterViewInit, OnDestroy { @ViewChild(MonacoEditorComponent) monacoEditorComponent: MonacoEditorComponent; - @ViewChild(XtermComponent) xtermComponent: XtermComponent; - enableDebugger = false; isMaximize = false; - constructor(@Inject(DOCUMENT) private document: Document) { + extrasIDE: TypeExtrasIDE; + + constructor(@Inject(DOCUMENT) private document: Document, + private router: Router, + private machine: MachineService, + private fileSystem: FileSystemService, + private translate: TranslateService, + private toastService: ToastrService) { + this.extrasIDE = this.router.getCurrentNavigation().extras.state as TypeExtrasIDE; + } ngOnInit(): void { window.jQuery('#card-IDE').on('maximized.lte.cardwidget', ($event) => { this.isMaximize = true; this.monacoEditorComponent.height = 88; - console.log(this.monacoEditorComponent.height) - }) + }); window.jQuery('#card-IDE').on('minimized.lte.cardwidget', ($event) => { this.isMaximize = false; this.monacoEditorComponent.height = 70; - console.log(this.monacoEditorComponent.height) - }) + }); } - toggleDebuggerTag() { - this.monacoEditorComponent.toggleDebuggerTag(); + ngAfterViewInit(): void { + this.monacoEditorComponent.getInitializedObservable().subscribe(async (isInitialized) => { + if (isInitialized) { + let content = ''; + if (this.extrasIDE) { + const interfaceFileItem = this.extrasIDE.interfaceFileItem ?? Utils.new_InterfaceFileItem(); + content = interfaceFileItem.content; + localStorage.setItem('interfaceFileItem', JSON.stringify(interfaceFileItem)); + } else { + content = JSON.parse(localStorage.getItem('interfaceFileItem')).content ?? ''; + } + await this.monacoEditorComponent.updateContent(content); + const breakpoints = JSON.parse(localStorage.getItem('breakpoints')); + this.monacoEditorComponent.setBreakpoints(breakpoints); + return Promise.resolve(); + } + }); + this.monacoEditorComponent.getBreakpointsObservable().subscribe((breakpoints) => { + this.machine.breakpointManager.updateManager(breakpoints); + }); + this.machine.getDebuggerObservable().subscribe((line) => { + this.monacoEditorComponent.printLine(line); + }); + this.machine.getLineObservable().subscribe((line) => { + this.monacoEditorComponent.printLine(line); + }); } - getListOfTags() { - console.log(this.monacoEditorComponent.getListOfTags()); + async ngOnDestroy(): Promise { + const auto_save = localStorage.getItem('auto_save'); + if (auto_save) { + localStorage.setItem('breakpoints', JSON.stringify(this.monacoEditorComponent.breakpoints)); + await this.save(); + } else { + localStorage.setItem('breakpoints', JSON.stringify({})); + } + return Promise.resolve(); } - toggleDebugger() { - this.enableDebugger = !this.enableDebugger; - + toggleDebuggerTag(): void { + this.monacoEditorComponent.toggleDebuggerTag(); } - debugNextLine() { - this.monacoEditorComponent.debugNextLine() - + getListOfTags(): void { + console.log(this.monacoEditorComponent.getListOfTags()); } - debugNextLineWithTag() { - this.monacoEditorComponent.debugNextLineWithTag() + changeHeight(): void { + this.monacoEditorComponent.height = 1000; } - play() { + public async save(): Promise { + let interfaceFileItem; + const updateContent = this.monacoEditorComponent.content; + if (this.extrasIDE) { + interfaceFileItem = this.extrasIDE.interfaceFileItem; + } else { + interfaceFileItem = JSON.parse(localStorage.getItem('interfaceFileItem')); + } + interfaceFileItem.content = updateContent; + localStorage.setItem('interfaceFileItem', JSON.stringify(interfaceFileItem)); + try { + await this.fileSystem.editFileItem(interfaceFileItem, interfaceFileItem.$key); - } + const title = await this.translate.get('TOAST.TITLE_SAVE_FILE').toPromise(); + const message = await this.translate.get('TOAST.MESSAGE_SAVE_FILE').toPromise(); + this.toastService.success(message, title, {timeOut: 1500}); + } catch (error) { + console.error(error); + const title = await this.translate.get('TOAST.TITLE_ERROR_SAVE_FILE').toPromise(); + const message = await this.translate.get('TOAST.MESSAGE_ERROR_SAVE_FILE').toPromise(); + this.toastService.error(message, title, {timeOut: 2500}); + } - changeHeight() { - this.monacoEditorComponent.height = 1000; + return Promise.resolve(); } } diff --git a/src/app/views/_auth/logger/logger.view.html b/src/app/views/_auth/logger/logger.view.html new file mode 100644 index 0000000..b955e97 --- /dev/null +++ b/src/app/views/_auth/logger/logger.view.html @@ -0,0 +1,26 @@ +
+
+

Xterm

+
+ + + +
+
+ +
+
+ +
+
+ + +
diff --git a/src/app/views/_auth/logger/logger.view.ts b/src/app/views/_auth/logger/logger.view.ts new file mode 100644 index 0000000..3dcd1f8 --- /dev/null +++ b/src/app/views/_auth/logger/logger.view.ts @@ -0,0 +1,29 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { XtermComponent } from "../../../components/xterm/xterm.component"; +import { TypeOnKeyEvent } from "../../../types"; +import { MachineService } from "../../../__core/machine/machine.service"; + +@Component({ + selector: 'view-logger', + templateUrl: './logger.view.html', + styleUrls: [] +}) +export class LoggerView implements OnInit { + + @ViewChild(XtermComponent) xtermComponent: XtermComponent; + text: string = "Hello"; + + constructor(public machine: MachineService) { + } + + ngOnInit(): void { + } + + onKey($event: TypeOnKeyEvent):void { + console.log($event); + } + + test():void { + this.text = this.machine.logger; + } +} diff --git a/src/app/views/_auth/memory/memory.view.ts b/src/app/views/_auth/memory/memory.view.ts index 6efbb24..596fe77 100644 --- a/src/app/views/_auth/memory/memory.view.ts +++ b/src/app/views/_auth/memory/memory.view.ts @@ -7,6 +7,7 @@ import { TranslateService } from "@ngx-translate/core"; import { EditMemoryBinary32Component } from "../../../components/modals/edit-memory-binary32/edit-memory-binary32.component"; import { TypeData } from "../../../types"; import { StorageService } from "../../../__core/storage/storage.service"; +import { Utils } from "../../../Utils"; @Component({ selector: 'view-memory', @@ -23,14 +24,14 @@ export class MemoryView implements OnInit, AfterViewInit { displayedColumnsMemory: string[] = ['Address', 'Hexadecimal', 'Binary', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'Word']; dataSourceMemory = new TableVirtualScrollDataSource(); - typeDataSelected: TypeData = "Word" + typeDataSelected: TypeData = "Word"; public maxHeightCard = 75; constructor(public machine: MachineService, private translate: TranslateService, private storage: StorageService, private toastService: ToastrService) { - this.dataSourceMemory.filter = null + this.dataSourceMemory.filter = null; this.dataSourceMemory.sort = this.sort; } @@ -41,52 +42,49 @@ export class MemoryView implements OnInit, AfterViewInit { this.dataSourceMemory.data = this.machine.memory.getAllIndexByWord(); break; } - }) + }); } ngAfterViewInit(): void { this.dataSourceMemory.data = this.machine.memory.getAllIndexByWord(); - window.jQuery('#card-Memory') - .on('expanded.lte.cardwidget', ($event) => { - this.resizeCard(75); - }) - window.jQuery('#card-Memory') - .on('minimized.lte.cardwidget', ($event) => { - this.resizeCard(75); - }) - window.jQuery('#card-Memory') - .on('maximized.lte.cardwidget', ($event) => { - this.resizeCard(85); - }) + window.jQuery('#card-Memory').on('expanded.lte.cardwidget', (/*$event*/) => { + this.resizeCard(75); + }); + window.jQuery('#card-Memory').on('minimized.lte.cardwidget', () => { + this.resizeCard(75); + }); + window.jQuery('#card-Memory').on('maximized.lte.cardwidget', () => { + this.resizeCard(85); + }); } - changeTypeDataInTable(typeData: TypeData) { + changeTypeDataInTable(typeData: TypeData): void { // Word, HalfWord, Float, Double, Bytes this.typeDataSelected = typeData; switch (typeData) { case "Byte": - this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'Binary','Address-0', 'Address-1', 'Address-2', 'Address-3', 'Bytes'] + this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'Binary', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'Bytes']; break; case "HalfWord": - this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'Binary', 'HalfWord-0', 'HalfWord-1', 'HalfWord'] + this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'Binary', 'HalfWord-0', 'HalfWord-1', 'HalfWord']; break; case "Word": - this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'Binary', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'Word'] + this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'Binary', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'Word']; break; case "ASCII": - this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'Binary', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'ASCII'] + this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'Binary', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'ASCII']; break; case "Float": - this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'BinaryFloat', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'Float'] + this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'BinaryFloat', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'Float']; break; case "Double": - this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'BinaryDouble', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'Float'] + this.displayedColumnsMemory = ['Address', 'Hexadecimal', 'BinaryDouble', 'Address-0', 'Address-1', 'Address-2', 'Address-3', 'Float']; break; } } - refresh() { + refresh(): void { this.dataSourceMemory.filter = null; this.dataSourceMemory.data = [...this.dataSourceMemory.data]; } diff --git a/src/app/views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view.html b/src/app/views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view.html index 5676953..dbbd482 100644 --- a/src/app/views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view.html +++ b/src/app/views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view.html @@ -2,7 +2,7 @@
-

{{'MACHINE.CYCLE_CLOCK_DIAGRAM' | translate}}

+

{{'MACHINE.CYCLE_CLOCK_DIAGRAM' | translate}} | {{ inCanvas }}

- - - +
- - - -
-
-
-

Manual

-
- - -
-
- -
+ - -
diff --git a/src/app/views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view.ts b/src/app/views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view.ts index c510891..c52b3ee 100644 --- a/src/app/views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view.ts +++ b/src/app/views/_auth/pixi-cycle-clock-diagram/cycle-clock-diagram.view.ts @@ -7,14 +7,18 @@ import { PixiCycleClockDiagramComponent } from "../../../components/pixi-cycle-c templateUrl: "./cycle-clock-diagram.view.html", }) export class CycleClockDiagramView implements OnInit { - @ViewChild(PixiCycleClockDiagramComponent) - pixi_CycleClockDiagramComponent: PixiCycleClockDiagramComponent; + @ViewChild(PixiCycleClockDiagramComponent) pixi_CycleClockDiagramComponent: PixiCycleClockDiagramComponent; + public inCanvas = false; - constructor(@Inject(DOCUMENT) - private document: Document) { + constructor(@Inject(DOCUMENT) private document: Document) { } ngOnInit(): void { } + handleInCanvas($event): void { + // console.log($event) + this.inCanvas = $event as boolean; + } + } diff --git a/src/app/views/_auth/pixi-pipeline/pipeline.view.html b/src/app/views/_auth/pixi-pipeline/pipeline.view.html index ee1ff28..cb60540 100644 --- a/src/app/views/_auth/pixi-pipeline/pipeline.view.html +++ b/src/app/views/_auth/pixi-pipeline/pipeline.view.html @@ -19,7 +19,22 @@

{{'MACHINE.PIPELINE' | translate}}

diff --git a/src/app/views/_auth/pixi-pipeline/pipeline.view.ts b/src/app/views/_auth/pixi-pipeline/pipeline.view.ts index 1da5d66..84e64f9 100644 --- a/src/app/views/_auth/pixi-pipeline/pipeline.view.ts +++ b/src/app/views/_auth/pixi-pipeline/pipeline.view.ts @@ -8,6 +8,7 @@ import { PixiPipelineComponent } from "../../../components/pixi-pipeline/pixi-pi styleUrls: [] }) export class PipelineView implements OnInit { + @ViewChild(PixiPipelineComponent) pixi_CycleClockDiagramComponent: PixiPipelineComponent; constructor(@Inject(DOCUMENT) private document: Document) { diff --git a/src/app/views/_auth/profile/profile.view.ts b/src/app/views/_auth/profile/profile.view.ts index 3805c6b..804815b 100644 --- a/src/app/views/_auth/profile/profile.view.ts +++ b/src/app/views/_auth/profile/profile.view.ts @@ -8,15 +8,14 @@ import { AuthService } from "../../../__core/auth/auth.service"; styleUrls: [] }) export class ProfileView implements OnInit { - constructor(@Inject(DOCUMENT) - private document: Document, + constructor(@Inject(DOCUMENT) private document: Document, public authService: AuthService) { } ngOnInit(): void { } - log(msg: string) { + log(msg: string): void { console.log(msg); } } diff --git a/src/app/views/_auth/registers/registers.view.ts b/src/app/views/_auth/registers/registers.view.ts index 53aa338..2b73e33 100644 --- a/src/app/views/_auth/registers/registers.view.ts +++ b/src/app/views/_auth/registers/registers.view.ts @@ -46,25 +46,25 @@ export class RegistersView implements OnInit, AfterViewInit { } window.jQuery('#registers_Control_id, #registers_R_id, #registers_F_id, #registers_D_id') - .on('expanded.lte.cardwidget', ($event) => { + .on('expanded.lte.cardwidget', (/*$event*/) => { this.resizeCards(60); - }) + }); window.jQuery('#registers_Control_id, #registers_R_id, #registers_F_id, #registers_D_id') - .on('minimized.lte.cardwidget', ($event) => { + .on('minimized.lte.cardwidget', (/*$event*/) => { this.resizeCards(60); - }) + }); window.jQuery('#registers_Control_id, #registers_R_id, #registers_F_id, #registers_D_id') - .on('maximized.lte.cardwidget', ($event) => { + .on('maximized.lte.cardwidget', (/*$event*/) => { this.resizeCards(80); - }) + }); } - changeTypeDataInTableRegisters(typeData: TypeData) { + changeTypeDataInTableRegisters(typeData: TypeData): void { this.typeDataSelected = typeData; this.displayedColumns[3] = typeData.toString(); } - refresh() { + refresh(): void { this.dataSource.filter = null; this.dataSource.data = [...this.dataSource.data]; @@ -78,16 +78,16 @@ export class RegistersView implements OnInit, AfterViewInit { this.dataSourceD.data = [...this.dataSourceD.data]; } - test() { - this.dataSource.data.push('PC') + test(): void { + this.dataSource.data.push('PC'); console.log(this.dataSource.data); } - applyFilter(filterValue: string) { + applyFilter(filterValue: string): void { this.dataSource.filter = filterValue.trim().toLowerCase(); } - private resizeCards(newHeightCard) { + private resizeCards(newHeightCard): void { this.maxHeightCard = newHeightCard; } } diff --git a/src/app/views/_auth/statistics/statistics.view.ts b/src/app/views/_auth/statistics/statistics.view.ts index ac14fc4..5c2ed4e 100644 --- a/src/app/views/_auth/statistics/statistics.view.ts +++ b/src/app/views/_auth/statistics/statistics.view.ts @@ -12,7 +12,7 @@ import { Utils } from "../../../Utils"; }) export class StatisticsView implements OnInit { - _data: TypeDataStatistics = Utils.clone(DEFAULT_DATA_STATISTICS); + public _data: TypeDataStatistics = Utils.clone(DEFAULT_DATA_STATISTICS); constructor(private translate: TranslateService, private machine: MachineService) { diff --git a/src/app/views/_landing/about/about.view.html b/src/app/views/_landing/about/about.view.html index 67cabab..3f11eea 100644 --- a/src/app/views/_landing/about/about.view.html +++ b/src/app/views/_landing/about/about.view.html @@ -1,6 +1,6 @@
-
- diff --git a/src/assets/examples-dlx/example-runner.json b/src/assets/examples-dlx/example-runner.json index da37a2f..c4496fc 100644 --- a/src/assets/examples-dlx/example-runner.json +++ b/src/assets/examples-dlx/example-runner.json @@ -1,7 +1,8 @@ { "name_file": "prime.s", "date": "2021-08-28 12:25:00", - "steps": 7, + "steps": 8, + "lines": 68, "code": [ { "address": "0x00000100", @@ -77,352 +78,5 @@ } ], "runner": [ - { - "step": -1, - "instruction": "", - "IF": 1, - "IF_stall": 0, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "", - "ID": "", - "intEX": "", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "", - "WB": "" - }, - "registers": [ - { - "register": "PC", - "value": "0x00000100" - } - ], - "memory": [] - }, - { - "step": 0, - "instruction": "addi r1, r0, 0x0", - "IF": 1, - "IF_stall": 0, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "0x00000100", - "ID": "", - "intEX": "", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "", - "WB": "" - }, - "registers": [ - { - "register": "PC", - "value": "0x00000104" - }, - { - "register": "IMAR", - "value": "0x00000100" - }, - { - "register": "IR", - "value": "0x20010000" - } - ], - "memory": [] - }, - { - "step": 1, - "instruction": "addi r1, r0, 0x2", - "IF": 1, - "IF_stall": 0, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "0x00000104", - "ID": "0x00000100", - "intEX": "", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "", - "WB": "" - }, - "registers": [ - { - "register": "PC", - "value": "0x00000108" - }, - { - "register": "IMAR", - "value": "0x00000104" - }, - { - "register": "IR", - "value": "0x20020002" - } - ], - "memory": [] - }, - { - "step": 2, - "instruction": "addi r16, r0, 0x10", - "IF": 1, - "IF_stall": 0, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "0x00000108", - "ID": "0x00000104", - "intEX": "0x00000100", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "", - "WB": "" - }, - "registers": [ - { - "register": "PC", - "value": "0x0000010C" - }, - { - "register": "IMAR", - "value": "0x00000108" - }, - { - "register": "IR", - "value": "0x20100010" - } - ], - "memory": [] - }, - { - "step": 3, - "instruction": "addi r18, r0, 0x8", - "IF": 1, - "IF_stall": 0, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "0x0000010C", - "ID": "0x00000108", - "intEX": "0x00000104", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "0x00000100", - "WB": "" - }, - "registers": [ - { - "register": "PC", - "value": "0x00000110" - }, - { - "register": "IMAR", - "value": "0x0000010C" - }, - { - "register": "IR", - "value": "0x20120008" - }, - { - "register": "ALU", - "value": "0x00000002" - } - ], - "memory": [] - }, - { - "step": 4, - "instruction": "addi r3, r0, 0x0", - "IF": 1, - "IF_stall": 0, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "0x00000110", - "ID": "0x0000010C", - "intEX": "0x00000108", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "0x00000104", - "WB": "0x00000100" - }, - "registers": [ - { - "register": "PC", - "value": "0x00000114" - }, - { - "register": "IMAR", - "value": "0x00000110" - }, - { - "register": "IR", - "value": "0x20030000" - }, - { - "register": "ALU", - "value": "0x00000010" - } - ], - "memory": [] - }, - { - "step": 5, - "instruction": "seq r4, r1, r3", - "IF": 1, - "IF_stall": 0, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "0x00000114", - "ID": "0x00000110", - "intEX": "0x0000010C", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "0x00000108", - "WB": "0x00000104" - }, - "registers": [ - { - "register": "PC", - "value": "0x00000118" - }, - { - "register": "IMAR", - "value": "0x00000114" - }, - { - "register": "IR", - "value": "0x00232028" - }, - { - "register": "ALU", - "value": "0x00000010" - } - ], - "memory": [] - }, - { - "step": 6, - "instruction": "benz r4, IsPrim", - "IF": 1, - "IF_stall": 0, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "0x00000118", - "ID": "0x00000114", - "intEX": "0x00000110", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "0x0000010C", - "WB": "0x00000108" - }, - "registers": [ - { - "register": "PC", - "value": "0x0000011C" - }, - { - "register": "IMAR", - "value": "0x00000118" - }, - { - "register": "IR", - "value": "0x14800024" - } - ], - "memory": [] - }, - { - "step": 7, - "instruction": "benz r4, IsPrim", - "IF": 1, - "IF_stall": 1, - "ID": 1, - "ID_stall": 0, - "intEX": 1, - "intEX_stall": 0, - "MEM": 1, - "MEM_stall": 0, - "WB": 1, - "WB_stall": 0, - "pipeline": { - "IF": "0x00000118", - "ID": "💥", - "intEX": "0x00000114", - "faddEX": [], - "fmultEX": [], - "fdivEX": [], - "MEM": "0x00000110", - "WB": "0x0000010C" - }, - "registers": [ - { - "register": "ALU", - "value": "0x00000001" - } - ], - "memory": [] - } ] } diff --git a/src/assets/examples-dlx/prim.s b/src/assets/examples-dlx/prim.s index 6e08066..d827ddf 100644 --- a/src/assets/examples-dlx/prim.s +++ b/src/assets/examples-dlx/prim.s @@ -28,7 +28,7 @@ MAIN: ;*** DETERMINE, IF R2 CAN BE DIVIDED BY A VALUE IN TABLE NEXTVALUE: - ADDI R3, R0, #0 ;HELPINDEX IN TABLE + ADDI R3, R0, #0 ;HELPINDEX IN TABLE LOOP: SEQ R4, R1, R3 ;END OF TABLE? diff --git a/src/assets/examples-dlx/prime.s/run_0.json b/src/assets/examples-dlx/prime.s/run_0.json new file mode 100644 index 0000000..ab59216 --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_0.json @@ -0,0 +1,32 @@ +{ + "step": 0, + "line": 0, + "instruction": "", + "IF": 1, + "IF_stall": 0, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "", + "ID": "", + "intEX": "", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "", + "WB": "" + }, + "registers": [ + { + "register": "PC", + "value": "0x00000100" + } + ], + "memory": [] +} diff --git a/src/assets/examples-dlx/prime.s/run_1.json b/src/assets/examples-dlx/prime.s/run_1.json new file mode 100644 index 0000000..d83e05e --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_1.json @@ -0,0 +1,40 @@ +{ + "step": 1, + "line": 24, + "instruction": "addi r1, r0, 0x0", + "IF": 1, + "IF_stall": 0, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "0x00000100", + "ID": "", + "intEX": "", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "", + "WB": "" + }, + "registers": [ + { + "register": "PC", + "value": "0x00000104" + }, + { + "register": "IMAR", + "value": "0x00000100" + }, + { + "register": "IR", + "value": "0x20010000" + } + ], + "memory": [] +} diff --git a/src/assets/examples-dlx/prime.s/run_2.json b/src/assets/examples-dlx/prime.s/run_2.json new file mode 100644 index 0000000..cf9613a --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_2.json @@ -0,0 +1,40 @@ +{ + "step": 2, + "line": 25, + "instruction": "addi r1, r0, 0x2", + "IF": 1, + "IF_stall": 0, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "0x00000104", + "ID": "0x00000100", + "intEX": "", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "", + "WB": "" + }, + "registers": [ + { + "register": "PC", + "value": "0x00000108" + }, + { + "register": "IMAR", + "value": "0x00000104" + }, + { + "register": "IR", + "value": "0x20020002" + } + ], + "memory": [] +} diff --git a/src/assets/examples-dlx/prime.s/run_3.json b/src/assets/examples-dlx/prime.s/run_3.json new file mode 100644 index 0000000..a562559 --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_3.json @@ -0,0 +1,40 @@ +{ + "step": 3, + "line": 26, + "instruction": "addi r16, r0, 0x10", + "IF": 1, + "IF_stall": 0, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "0x00000108", + "ID": "0x00000104", + "intEX": "0x00000100", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "", + "WB": "" + }, + "registers": [ + { + "register": "PC", + "value": "0x0000010C" + }, + { + "register": "IMAR", + "value": "0x00000108" + }, + { + "register": "IR", + "value": "0x20100010" + } + ], + "memory": [] +} diff --git a/src/assets/examples-dlx/prime.s/run_4.json b/src/assets/examples-dlx/prime.s/run_4.json new file mode 100644 index 0000000..62f372f --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_4.json @@ -0,0 +1,44 @@ +{ + "step": 4, + "line": 27, + "instruction": "addi r18, r0, 0x8", + "IF": 1, + "IF_stall": 0, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "0x0000010C", + "ID": "0x00000108", + "intEX": "0x00000104", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "0x00000100", + "WB": "" + }, + "registers": [ + { + "register": "PC", + "value": "0x00000110" + }, + { + "register": "IMAR", + "value": "0x0000010C" + }, + { + "register": "IR", + "value": "0x20120008" + }, + { + "register": "ALU", + "value": "0x00000002" + } + ], + "memory": [] +} diff --git a/src/assets/examples-dlx/prime.s/run_5.json b/src/assets/examples-dlx/prime.s/run_5.json new file mode 100644 index 0000000..e133d74 --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_5.json @@ -0,0 +1,44 @@ +{ + "step": 5, + "line": 31, + "instruction": "addi r3, r0, 0x0", + "IF": 1, + "IF_stall": 0, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "0x00000110", + "ID": "0x0000010C", + "intEX": "0x00000108", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "0x00000104", + "WB": "0x00000100" + }, + "registers": [ + { + "register": "PC", + "value": "0x00000114" + }, + { + "register": "IMAR", + "value": "0x00000110" + }, + { + "register": "IR", + "value": "0x20030000" + }, + { + "register": "ALU", + "value": "0x00000010" + } + ], + "memory": [] +} diff --git a/src/assets/examples-dlx/prime.s/run_6.json b/src/assets/examples-dlx/prime.s/run_6.json new file mode 100644 index 0000000..6d191bf --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_6.json @@ -0,0 +1,44 @@ +{ + "step": 6, + "line": 34, + "instruction": "seq r4, r1, r3", + "IF": 1, + "IF_stall": 0, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "0x00000114", + "ID": "0x00000110", + "intEX": "0x0000010C", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "0x00000108", + "WB": "0x00000104" + }, + "registers": [ + { + "register": "PC", + "value": "0x00000118" + }, + { + "register": "IMAR", + "value": "0x00000114" + }, + { + "register": "IR", + "value": "0x00232028" + }, + { + "register": "ALU", + "value": "0x00000010" + } + ], + "memory": [] +} diff --git a/src/assets/examples-dlx/prime.s/run_7.json b/src/assets/examples-dlx/prime.s/run_7.json new file mode 100644 index 0000000..bea897a --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_7.json @@ -0,0 +1,40 @@ +{ + "step": 7, + "line": 35, + "instruction": "benz r4, IsPrim", + "IF": 1, + "IF_stall": 0, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "0x00000118", + "ID": "0x00000114", + "intEX": "0x00000110", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "0x0000010C", + "WB": "0x00000108" + }, + "registers": [ + { + "register": "PC", + "value": "0x0000011C" + }, + { + "register": "IMAR", + "value": "0x00000118" + }, + { + "register": "IR", + "value": "0x14800024" + } + ], + "memory": [] +} diff --git a/src/assets/examples-dlx/prime.s/run_8.json b/src/assets/examples-dlx/prime.s/run_8.json new file mode 100644 index 0000000..aa19137 --- /dev/null +++ b/src/assets/examples-dlx/prime.s/run_8.json @@ -0,0 +1,35 @@ +{ + "step": 8, + "line": 35, + "isComplete": true, + + "instruction": "benz r4, IsPrim", + "code_instruction": "0x14800024", + "IF": 1, + "IF_stall": 1, + "ID": 1, + "ID_stall": 0, + "intEX": 1, + "intEX_stall": 0, + "MEM": 1, + "MEM_stall": 0, + "WB": 1, + "WB_stall": 0, + "pipeline": { + "IF": "0x00000118", + "ID": "💥", + "intEX": "0x00000114", + "faddEX": [], + "fmultEX": [], + "fdivEX": [], + "MEM": "0x00000110", + "WB": "0x0000010C" + }, + "registers": [ + { + "register": "ALU", + "value": "0x00000001" + } + ], + "memory": [] +} diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 053e510..7b30f43 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -121,7 +121,11 @@ "TITLE_ERROR_IN_VALUE_MEMORY": "Error in value memory", "MESSAGE_ERROR_IN_VALUE_MEMORY": "Value in section not valid", "TITLE_ERROR_IN_ADDRESS_MEMORY": "Error in memory", - "MESSAGE_ERROR_IN_ADDRESS_MEMORY": "Address not valid, out of memory" + "MESSAGE_ERROR_IN_ADDRESS_MEMORY": "Address not valid, out of memory", + "TITLE_SAVE_FILE": "Saved file", + "MESSAGE_SAVE_FILE": "success", + "TITLE_ERROR_SAVE_FILE": "File not save", + "MESSAGE_ERROR_SAVE_FILE": "error" }, "CONFIG": { "LANG": "Language",