<commit_before>const {SculptureStore, MoleGameLogic, PanelsActionCreator, SculptureActionCreator} = require('@anyware/game-logic');

const SerialManager = require('../serial/serial-manager');
const serialProtocol = require('../serial/serial-protocol');
const {SerialProtocolCommandParser, SerialProtocolCommandBuilder} = serialProtocol;

export default class PanelView {
  constructor(store, dispatcher, serialManager) {
    this.store = store;
    this.serialManager = serialManager;
    this.serialManager.on(SerialManager.EVENT_COMMAND, this._handleCommand.bind(this));

    this.panelsActionCreator = new PanelsActionCreator(dispatcher);
    this.sculptureActionCreator = new SculptureActionCreator(dispatcher);

    this._animating = false;

    this.showAllPanels();
    this.store.on(SculptureStore.EVENT_CHANGE, this._handleChanges.bind(this));
  }

  showAllPanels() {
    const lightArray = this.store.data.get('lights');

    for (let stripId of lightArray.stripIds) {
      const panelIds = lightArray.get(stripId).panelIds;
      for (let panelId of panelIds) {
        const intensity = lightArray.getIntensity(stripId, panelId);
        const color = lightArray.getColor(stripId, panelId);
        
        const commandString = SerialProtocolCommandBuilder.buildPanelSet({
          stripId: stripId,
          panelId: panelId,
          intensity: intensity,
          color: color
        });
        this.serialManager.dispatchCommand(commandString);
      }
    }
  }

  _handleChanges(changes) {
    if (this._animating) {
      return;
    }

    this._handleStatusChanges(changes);
    this._handleLightChanges(changes);
  }

  _handleLightChanges(changes) {
    const lightChanges = changes.lights;
    if (!lightChanges) {
      return;
    }

    for (let stripId of Object.keys(lightChanges)) {
      const panels = lightChanges[stripId].panels;
      for (let panelId of Object.keys(panels)) {
        const panelChanges = panels[panelId];

        if (panelChanges.hasOwnProperty("intensity")) {
          const commandString = SerialProtocolCommandBuilder.buildPanelSet({
            stripId: stripId,
            panelId: panelId,
            intensity: panelChanges.intensity,
            color: this.store.data.get('lights').getColor(stripId, panelId)
          });
          this.serialManager.dispatchCommand(commandString);
        }

        if (panelChanges.hasOwnProperty("active")) {
          //TODO: Make this behaviour game specific with a default behaviour
          const commandString = SerialProtocolCommandBuilder.buildPanelSet({
            stripId: stripId,
            panelId: panelId,
            intensity: panelChanges.active ? 100 : 0,
            color: this.store.data.get('lights').getColor(stripId, panelId)
          });
          this.serialManager.dispatchCommand(commandString);
        }
      }
    }
  }

  _handleCommand(commandName, commandArgs) {
    if (commandName === serialProtocol.PANEL_COMMAND) {
      const {stripId, panelId, pressed} = commandArgs;

      this.panelsActionCreator.sendPanelPressed(stripId, panelId, parseInt(pressed) ? true : false);
    }
  }

  _handleStatusChanges(changes) {
    const status = changes.status;
    const statusAnimations = {
      [SculptureStore.STATUS_SUCCESS]: this._playSuccessAnimation.bind(this)
    };

    const animationMethod = statusAnimations[status];
    if (animationMethod) {
      animationMethod();
    }
  }

  _playSuccessAnimation() {
    const frames = [
      // stripId, panelId, intensity
      [0, 3, 50],
      [1, 3, 50],
      [2, 3, 50],
      [0, 4, 100],
      [1, 4, 100],
      [2, 4, 100]
    ];

    const playFrame = (frameIndex) => {
      if (frameIndex > 0) {
        const [stripId, panelId, intensity] = frames[frameIndex - 1];

        const commandString = SerialProtocolCommandBuilder.buildPanelSet({
          stripId: stripId,
          panelId: panelId,
          intensity: 0,
          color: "success"
        });
        this.serialManager.dispatchCommand(commandString);
      }

      const [stripId, panelId, intensity] = frames[frameIndex];

      const commandString = SerialProtocolCommandBuilder.buildPanelSet({
        stripId: stripId,
        panelId: panelId,
        intensity: 100,
        color: "success"
      });
      this.serialManager.dispatchCommand(commandString);

      if (frameIndex >= frames.length - 1) {
        this._animationComplete();
      }
      else {
        setTimeout(() => playFrame(frameIndex + 1), 300);
      }
    };

    playFrame(0);
  }

  _animationComplete() {
    this._animating = false;
    this.sculptureActionCreator.sendRestoreStatus();
    
    //TODO: setTimeout is used here as a hack to compensate
    //TODO: for the problem with many commands sent at once
    //TODO: being garbled up together
    setTimeout(() => {
      this.showAllPanels();
    }, 500);
  }
}
<commit_msg>Removed hack timeout<commit_after>const {SculptureStore, MoleGameLogic, PanelsActionCreator, SculptureActionCreator} = require('@anyware/game-logic');

const SerialManager = require('../serial/serial-manager');
const serialProtocol = require('../serial/serial-protocol');
const {SerialProtocolCommandParser, SerialProtocolCommandBuilder} = serialProtocol;

export default class PanelView {
  constructor(store, dispatcher, serialManager) {
    this.store = store;
    this.serialManager = serialManager;
    this.serialManager.on(SerialManager.EVENT_COMMAND, this._handleCommand.bind(this));

    this.panelsActionCreator = new PanelsActionCreator(dispatcher);
    this.sculptureActionCreator = new SculptureActionCreator(dispatcher);

    this._animating = false;

    this.showAllPanels();
    this.store.on(SculptureStore.EVENT_CHANGE, this._handleChanges.bind(this));
  }

  showAllPanels() {
    const lightArray = this.store.data.get('lights');

    for (let stripId of lightArray.stripIds) {
      const panelIds = lightArray.get(stripId).panelIds;
      for (let panelId of panelIds) {
        const intensity = lightArray.getIntensity(stripId, panelId);
        const color = lightArray.getColor(stripId, panelId);
        
        const commandString = SerialProtocolCommandBuilder.buildPanelSet({
          stripId: stripId,
          panelId: panelId,
          intensity: intensity,
          color: color
        });
        this.serialManager.dispatchCommand(commandString);
      }
    }
  }

  _handleChanges(changes) {
    if (this._animating) {
      return;
    }

    this._handleStatusChanges(changes);
    this._handleLightChanges(changes);
  }

  _handleLightChanges(changes) {
    const lightChanges = changes.lights;
    if (!lightChanges) {
      return;
    }

    for (let stripId of Object.keys(lightChanges)) {
      const panels = lightChanges[stripId].panels;
      for (let panelId of Object.keys(panels)) {
        const panelChanges = panels[panelId];

        if (panelChanges.hasOwnProperty("intensity")) {
          const commandString = SerialProtocolCommandBuilder.buildPanelSet({
            stripId: stripId,
            panelId: panelId,
            intensity: panelChanges.intensity,
            color: this.store.data.get('lights').getColor(stripId, panelId)
          });
          this.serialManager.dispatchCommand(commandString);
        }

        if (panelChanges.hasOwnProperty("active")) {
          //TODO: Make this behaviour game specific with a default behaviour
          const commandString = SerialProtocolCommandBuilder.buildPanelSet({
            stripId: stripId,
            panelId: panelId,
            intensity: panelChanges.active ? 100 : 0,
            color: this.store.data.get('lights').getColor(stripId, panelId)
          });
          this.serialManager.dispatchCommand(commandString);
        }
      }
    }
  }

  _handleCommand(commandName, commandArgs) {
    if (commandName === serialProtocol.PANEL_COMMAND) {
      const {stripId, panelId, pressed} = commandArgs;

      this.panelsActionCreator.sendPanelPressed(stripId, panelId, parseInt(pressed) ? true : false);
    }
  }

  _handleStatusChanges(changes) {
    const status = changes.status;
    const statusAnimations = {
      [SculptureStore.STATUS_SUCCESS]: this._playSuccessAnimation.bind(this)
    };

    const animationMethod = statusAnimations[status];
    if (animationMethod) {
      animationMethod();
    }
  }

  _playSuccessAnimation() {
    const frames = [
      // stripId, panelId, intensity
      [0, 3, 50],
      [1, 3, 50],
      [2, 3, 50],
      [0, 4, 100],
      [1, 4, 100],
      [2, 4, 100]
    ];

    const playFrame = (frameIndex) => {
      if (frameIndex > 0) {
        const [stripId, panelId, intensity] = frames[frameIndex - 1];

        const commandString = SerialProtocolCommandBuilder.buildPanelSet({
          stripId: stripId,
          panelId: panelId,
          intensity: 0,
          color: "success"
        });
        this.serialManager.dispatchCommand(commandString);
      }

      const [stripId, panelId, intensity] = frames[frameIndex];

      const commandString = SerialProtocolCommandBuilder.buildPanelSet({
        stripId: stripId,
        panelId: panelId,
        intensity: 100,
        color: "success"
      });
      this.serialManager.dispatchCommand(commandString);

      if (frameIndex >= frames.length - 1) {
        this._animationComplete();
      }
      else {
        setTimeout(() => playFrame(frameIndex + 1), 300);
      }
    };

    playFrame(0);
  }

  _animationComplete() {
    this._animating = false;
    this.sculptureActionCreator.sendRestoreStatus();
    this.showAllPanels();
  }
}

{'fraction_non_alphanumeric': 0.10844250363901019, 'fraction_numerical': 0.00925348305260969, 'mean_word_length': 2.792981072555205, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '203495', 'n_tokens_mistral': 2814, 'n_tokens_neox': 2699, 'n_words': 545}