<commit_before>const events = require('events');

const GameConstants = require('./game-constants');
const KnockGame = require('./knock-game');
const VersionedStore = require('./versioned-store');

const STATE_UPDATE_CURRENT_GAME = "game";

const STATUS_RUNNING = "running";
const STATUS_LOCKED = "locked";

export default class Sculpture extends events.EventEmitter {
  constructor() {
    super();

    this._currentGame = null;

    // Temporarily here to make the knock game work
    this.currentGame = new KnockGame();

    this.store = new VersionedStore({
      status: STATUS_RUNNING
    });
  }

  // Store properties
  get status() {
    return this.store.get("status");
  }

  // Store Methods
  lockSculpture() {
    this.store.set("status", STATUS_LOCKED);
  }

  unlockSculpture() {
    this.store.set("status", STATUS_RUNNING);
  }

  // Current Game

  get currentGame() {
    return this._currentGame;
  }

  set currentGame(game) {
    this._currentGame = game;

    if (this._currentGame) {
      this._currentGame.on(GameConstants.EVENT_UPDATE, this._handleGameUpdate);
    }
  }

  get isPlayingKnockGame() {
    return this.currentGame instanceof KnockGame;
  }

  /**
   * Event handler to be called every frame for updates
   */
  onFrame() {
    if (this.status === STATUS_LOCKED) {
      return;
    }

    if (this.currentGame) {
      this.currentGame.onFrame();
    }

    this.emitStateUpdate();
  }

  mergeUpdate(update) {
    //TODO: Merge top-level properties
    if (update[STATE_UPDATE_CURRENT_GAME]) {
      if (!this.currentGame) {
        //TODO
        throw new Error("");
      }

      this.currentGame.mergeUpdate(update[STATE_UPDATE_CURRENT_GAME]);
    }
  }

  emitStateUpdate() {
    const thisUpdate = this.store.getChangedCurrentValues();
    this.store.clearChanges();

    if (this.currentGame) {
      const gameUpdate = this.currentGame.store.getChangedCurrentValues();
      this.currentGame.store.clearChanges();

      thisUpdate[STATE_UPDATE_CURRENT_GAME]: gameUpdate
    }
    
    if (Object.keys(thisUpdate).length) {
      this.emit(GameConstants.EVENT_UPDATE, thisUpdate);
    }
  }
}<commit_msg>Fixed a syntax error<commit_after>const events = require('events');

const GameConstants = require('./game-constants');
const KnockGame = require('./knock-game');
const VersionedStore = require('./versioned-store');

const STATE_UPDATE_CURRENT_GAME = "game";

const STATUS_RUNNING = "running";
const STATUS_LOCKED = "locked";

export default class Sculpture extends events.EventEmitter {
  constructor() {
    super();

    this._currentGame = null;

    // Temporarily here to make the knock game work
    this.currentGame = new KnockGame();

    this.store = new VersionedStore({
      status: STATUS_RUNNING
    });
  }

  // Store properties
  get status() {
    return this.store.get("status");
  }

  // Store Methods
  lockSculpture() {
    this.store.set("status", STATUS_LOCKED);
  }

  unlockSculpture() {
    this.store.set("status", STATUS_RUNNING);
  }

  // Current Game

  get currentGame() {
    return this._currentGame;
  }

  set currentGame(game) {
    this._currentGame = game;

    if (this._currentGame) {
      this._currentGame.on(GameConstants.EVENT_UPDATE, this._handleGameUpdate);
    }
  }

  get isPlayingKnockGame() {
    return this.currentGame instanceof KnockGame;
  }

  /**
   * Event handler to be called every frame for updates
   */
  onFrame() {
    if (this.status === STATUS_LOCKED) {
      return;
    }

    if (this.currentGame) {
      this.currentGame.onFrame();
    }

    this.emitStateUpdate();
  }

  mergeUpdate(update) {
    //TODO: Merge top-level properties
    if (update[STATE_UPDATE_CURRENT_GAME]) {
      if (!this.currentGame) {
        //TODO
        throw new Error("");
      }

      this.currentGame.mergeUpdate(update[STATE_UPDATE_CURRENT_GAME]);
    }
  }

  emitStateUpdate() {
    const thisUpdate = this.store.getChangedCurrentValues();
    this.store.clearChanges();

    if (this.currentGame) {
      const gameUpdate = this.currentGame.store.getChangedCurrentValues();
      this.currentGame.store.clearChanges();

      thisUpdate[STATE_UPDATE_CURRENT_GAME] = gameUpdate;
    }
    
    if (Object.keys(thisUpdate).length) {
      this.emit(GameConstants.EVENT_UPDATE, thisUpdate);
    }
  }
}
{'fraction_non_alphanumeric': 0.12323699421965317, 'fraction_numerical': 0.0, 'mean_word_length': 3.0772855796418472, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '1254821', 'n_tokens_mistral': 1376, 'n_tokens_neox': 1330, 'n_words': 263}