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

3
const MAX_GAZE_POINT_AGE = 4000,
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
      if (client.color === undefined) {
52
        client.color = Colors.getNextColor();
53
        Logger.log(`Assign client color: ${client.color}`, "ImageViewer Room");
54 55
      }
      message.data.color = client.color;
Alexander Bazo committed
56 57
      let point = GazePoint.fromClientData(message.data);
      gazePoints.push(point);
58 59 60
      Logger.log(
        `Adding new gaze point (${gazePoints.length} points stored)`,
        "ImageViewer Room");
Alexander Bazo committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
    }
    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
82
  // Run on each tick (~30FPS)
Alexander Bazo committed
83 84
  update() {
    let now = Date.now();
Alexander Bazo committed
85
    // Remove old gaze points
Alexander Bazo committed
86
    this.updateGazePoints(now);
Alexander Bazo committed
87
    // Sanity check to prevent empty updates to subscribers
88
    if (gazePoints.length === 0) {
Alexander Bazo committed
89 90 91
      return;
    }
    // Sanity check to prevent high frequency gaze updates to subscribers
92
    if (now - lastGazePointUpdate < GAZE_POINT_UPDATE_DELAY) {
Alexander Bazo committed
93 94 95 96
      return;
    }
    for (let i = 0; i < gazeSubscribers.length; i++) {
      Logger.log(`${gazePoints.length} gaze points available`);
Alexander Bazo committed
97
      if (gazeSubscribers[i]) {
98 99 100
        Logger.log(`Sending ${gazePoints.length} gaze points to subscriber`,
          "ImageViewer Room");
        this.send(gazeSubscribers[i], {
Alexander Bazo committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
          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
122
    // Cycle through available tasks
Alexander Bazo committed
123 124 125 126 127
    currentTaskIndex += 1;
    if (currentTaskIndex >= availableTasks.length) {
      currentTaskIndex = 0;
    }
    currentTask = availableTasks[currentTaskIndex];
Alexander Bazo committed
128 129
    // Send task to state to auto update clients
    // Set listener for task change event (is based on task's duration property)
Alexander Bazo committed
130 131 132 133 134
    this.state.setTask(currentTask, this.onTaskFinished.bind(this));
  }
}

module.exports = ImageViewerRoom;