Parcourir la source

Implement command counter in IVProgProcessor to delay every 100th command execution in 5ms

Lucas de Souza il y a 5 ans
Parent
commit
6b550980ef
4 fichiers modifiés avec 30 ajouts et 11 suppressions
  1. 2 1
      i18n/message.csv
  2. 15 2
      js/processor/ivprogProcessor.js
  3. 2 1
      js/processor/modes.ts
  4. 11 7
      js/visualUI/functions.js

+ 2 - 1
i18n/message.csv

@@ -7,4 +7,5 @@ assessment-empty-expected-tooltip,A saída gerada foi além do esperado,The gene
 assessment-empty-generated-tooltip,O programa não gerou saídas suficientes,The program did not generated enough outputs," "
 testcase_autogen_unused_input,O caso de teste $0 possui mais entradas do que as leituras feitas no programa.,The test case $0 has more inputs than output than the number of reads present in the algorithm.," "
 testcase_autogen_empty,O caso de teste $0 não gerou qualquer saída.,The test case $0 did not generate any output.," "
-success_execution,Programa executado com sucesso!,Program executed successfully!,
+success_execution,Programa executado com sucesso!,Program executed successfully!,
+aborted_execution,A execução do programa foi interrompida!,Program execution was aborted!,

+ 15 - 2
js/processor/ivprogProcessor.js

@@ -18,6 +18,7 @@ import { StoreValueRef } from './store/value/store_value_ref';
 import { ArrayStoreValue } from './store/value/array_store_value';
 import { ArrayStoreValueRef } from './store/value/array_store_value_ref';
 import { StoreValueAddress } from './store/value/store_value_address';
+import { LocalizedStrings } from '../services/localizedStringsService';
 
 export class IVProgProcessor {
 
@@ -42,10 +43,12 @@ export class IVProgProcessor {
     this.forceKill = false;
     this.loopTimers = [];
     this.output = null;
+    this.mode = Modes.RUN;
     /**
      * Stores the sourceInfo of every function call, command or expression
      */
     this.function_call_stack = [];
+    this.command_count = 0;
   }
 
   registerInput (input) {
@@ -86,6 +89,7 @@ export class IVProgProcessor {
     this.globalStore = new Store("$global");
     this.stores = [this.globalStore];
     this.context = [Context.BASE];
+    this.command_count = 0;
   }
 
   interpretAST () {
@@ -220,8 +224,9 @@ export class IVProgProcessor {
   }
 
   executeCommand (store, cmd) {
+    this.command_count += 1;
     return new Promise((resolve, reject) => {
-      setTimeout(() => {
+      const command_lambda = () => {
         if(this.forceKill) {
           return reject("FORCED_KILL!");
         } else if (store.mode === Modes.PAUSE) {
@@ -230,6 +235,8 @@ export class IVProgProcessor {
           return resolve(store);
         } else if(this.checkContext(Context.BREAKABLE) && store.mode === Modes.BREAK) {
           return resolve(store);
+        } else if (this.mode === Modes.ABORT) {
+          return reject(LocalizedStrings.getMessage('aborted_execution'));
         }
         if (cmd instanceof Commands.Declaration) {
           return resolve(this.executeDeclaration(store, cmd));
@@ -258,7 +265,13 @@ export class IVProgProcessor {
         } else {
           return reject(ProcessorErrorFactory.unknown_command(cmd.sourceInfo))
         }
-      }, 5);
+      };
+      if(this.command_count % 100 == 0) {
+        //every 100th command should briefly delay its execution in order to allow the browser to process other things
+        setTimeout(command_lambda, 5);
+      } else {
+        command_lambda();
+      }
     })
     
   }

+ 2 - 1
js/processor/modes.ts

@@ -2,5 +2,6 @@ export const Modes = Object.freeze({
   RETURN: Symbol('mode:return'),
   BREAK: Symbol('mode:break'),
   PAUSE: Symbol('mode:pause'),
-  RUN: Symbol('mode:run')
+  RUN: Symbol('mode:run'),
+  ABORT: Symbol('mode:abort')
 });

+ 11 - 7
js/visualUI/functions.js

@@ -986,7 +986,11 @@ function runCode () {
     proc.interpretAST().then( _ => {
       scheduleCall(() => {
         if(domConsole.pending_writes.length == 0) {
-          domConsole.info(LocalizedStrings.getMessage("success_execution"));
+          if(proc.mode === Modes.ABORT) {
+            domConsole.info(LocalizedStrings.getMessage("aborted_execution"));  
+          } else {
+            domConsole.info(LocalizedStrings.getMessage("success_execution"));
+          }
           $("#ivprog-term").removeClass('ivprog-term-active');
           isRunning = false;
           proc = null;
@@ -998,7 +1002,11 @@ function runCode () {
     }).catch(err => {
       scheduleCall(() => {
         if(domConsole.pending_writes.length == 0) {
-          domConsole.err(err.message);
+          if(err instanceof Error) {
+            domConsole.err(err.message);
+          } else {
+            domConsole.err(err);
+          }
           $("#ivprog-term").removeClass('ivprog-term-active');
           isRunning = false;
           proc = null;
@@ -1472,9 +1480,5 @@ function stopExecution () {
   if(!isRunning) {
     return;
   }
-  proc.stores.forEach( sto => {
-    sto.mode = Modes.RETURN;
-  });
-  proc = null;
-  isRunning = false;
+  proc.mode = Modes.ABORT;
 }