ImageViewerRoom.js 3.81 KB
Newer Older
Alexander Bazo committed
1 2
/* eslint-env node */

Alexander Bazo committed
3
const MAX_GAZE_POINT_AGE = 2000,
4 5
  // Set max update intervall to ~ 30FPS
  GAZE_POINT_UPDATE_DELAY = 1000 / 32;
Alexander Bazo committed
6 7 8

const colyseus = require("colyseus"),
  Logger = require("../utils/Logger.js"),
9
  Colors = require("../utils/Colors.js"),
Alexander Bazo committed
10 11 12 13 14
  ServerConfiguration = require("../config/ServerConfig.js"),
  GazePoint = require("../logic/GazePoint.js"),
  Task = require("../logic/Task.js"),
  ImageViewerState = require("../logic/ImageViewerState.js");

15
var tasks = Task.getTasks(),
Alexander Bazo committed
16
  availableTasks,
Alexander Bazo committed
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
  currentTask,
  currentTaskIndex,
  gazePoints,
  gazeSubscribers,
  lastGazePointUpdate = 0;

class ImageViewerRoom extends colyseus.Room {

  onCreate() {
    Logger.log("Creating ImageViewer room", "ImageViewer Room");
    gazePoints = [];
    gazeSubscribers = [];
    this.createTasks();
    this.setState(new ImageViewerState());
    this.setSimulationInterval(this.update.bind(this), ServerConfiguration.getUpdateInterval());
    this.setTask();
  }

  createTasks() {
    availableTasks = [];
Alexander Bazo committed
37 38 39
    for (let i = 0; i < tasks.length; i++) {
      availableTasks.push(new Task(tasks[i].imageUrl, tasks[i].taskDescription,
        tasks[i].taskSource, tasks[i].duration));
Alexander Bazo committed
40 41 42 43 44 45 46 47 48 49 50
    }
    currentTaskIndex = 0;
  }

  onJoin(client, options) {
    Logger.log(`Viewer ${client.sessionId} joined ImageViewer room`,
      "ImageViewer Room");
  }

  onMessage(client, message) {
    if (message.type === "gaze") {
51 52 53 54
      if (client.color === undefined) {
        client.color = Colors.createRandomColor();
      }
      message.data.color = client.color;
Alexander Bazo committed
55 56
      let point = GazePoint.fromClientData(message.data);
      gazePoints.push(point);
57 58 59
      Logger.log(
        `Adding new gaze point (${gazePoints.length} points stored)`,
        "ImageViewer Room");
Alexander Bazo committed
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    }
    if (message.type === "subscribeToGazeData") {
      Logger.log("Gaze observer subsribed", "ImageViewer Room");
      gazeSubscribers.push(client);
    }
  }

  onLeave(client, consented) {
    Logger.log(`Viewer ${client.sessionId} left ImageViewer room`,
      "ImageViewer Room");
  }

  onDispose() {
    Logger.log("Disposing ImageViewer room", "ImageViewer Room");
  }

  onTaskFinished() {
    Logger.log(`Switching to next task`, "ImageViewer Room");
    this.setTask();
  }

Alexander Bazo committed
81
  // Run on each tick (~30FPS)
Alexander Bazo committed
82 83
  update() {
    let now = Date.now();
Alexander Bazo committed
84
    // Remove old gaze points
Alexander Bazo committed
85
    this.updateGazePoints(now);
Alexander Bazo committed
86
    // Sanity check to prevent empty updates to subscribers
87
    if (gazePoints.length === 0) {
Alexander Bazo committed
88 89 90
      return;
    }
    // Sanity check to prevent high frequency gaze updates to subscribers
91
    if (now - lastGazePointUpdate < GAZE_POINT_UPDATE_DELAY) {
Alexander Bazo committed
92 93 94 95
      return;
    }
    for (let i = 0; i < gazeSubscribers.length; i++) {
      Logger.log(`${gazePoints.length} gaze points available`);
Alexander Bazo committed
96
      if (gazeSubscribers[i]) {
97 98 99
        Logger.log(`Sending ${gazePoints.length} gaze points to subscriber`,
          "ImageViewer Room");
        this.send(gazeSubscribers[i], {
Alexander Bazo committed
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
          type: "gazelist",
          data: gazePoints,
        });
      }
    }
    lastGazePointUpdate = now;
  }

  updateGazePoints(now) {
    for (let i = gazePoints.length - 1; i >= 0; i--) {
      let age = now - gazePoints[i].createdAt;
      if (age > MAX_GAZE_POINT_AGE) {
        gazePoints.splice(i, 1);
      } else {
        gazePoints[i].relativeAge = age / MAX_GAZE_POINT_AGE;
      }
    }
  }

  setTask() {
    Logger.log("Sending current task to state", "ImageViewrRoom");
Alexander Bazo committed
121
    // Cycle through available tasks
Alexander Bazo committed
122 123 124 125 126
    currentTaskIndex += 1;
    if (currentTaskIndex >= availableTasks.length) {
      currentTaskIndex = 0;
    }
    currentTask = availableTasks[currentTaskIndex];
Alexander Bazo committed
127 128
    // Send task to state to auto update clients
    // Set listener for task change event (is based on task's duration property)
Alexander Bazo committed
129 130 131 132 133
    this.state.setTask(currentTask, this.onTaskFinished.bind(this));
  }
}

module.exports = ImageViewerRoom;