]> git.cworth.org Git - empires-server/blob - game.js
Drop the name field from the Game class
[empires-server] / game.js
1 /* Base class providing common code for game engine implementations. */
2 class Game {
3   constructor() {
4     this.clients = [];
5     this.next_client_id = 1;
6   }
7
8   /* Suport for game meta-data.
9    *
10    * What we want here is an effectively static field that is
11    * accessible through either the class name (SomeGame.meta) or an
12    * instance (some_game.meta). To pull this off we do keep two copies
13    * of the data. But the game classes can just set SomeGame.meta once
14    * and then reference it either way.
15    */
16   static set meta(data) {
17     /* This allows class access (SomeGame.meta) via the get method below. */
18     this._meta = data;
19
20     /* While this allows access via an instance (some_game.meta). */
21     this.prototype.meta = data;
22   }
23
24   static get meta() {
25     return this._meta;
26   }
27
28   add_client(response) {
29     const id = this.next_client_id;
30     this.clients.push({id: id,
31                        response: response});
32     this.next_client_id++;
33
34     return id;
35   }
36
37   remove_client(id) {
38     this.clients = this.clients.filter(client => client.id !== id);
39   }
40
41   /* Send a string to all clients */
42   broadcast_string(str) {
43     this.clients.forEach(client => client.response.write(str + '\n'));
44   }
45
46   /* Send an event to all clients.
47    *
48    * An event has both a declared type and a separate data block.
49    * It also ends with two newlines (to mark the end of the event).
50    */
51   broadcast_event(type, data) {
52     this.broadcast_string(`event: ${type}\ndata: ${data}\n`);
53   }
54
55   handle_events(request, response) {
56     /* These headers will keep the connection open so we can stream events. */
57     const headers = {
58       "Content-type": "text/event-stream",
59       "Connection": "keep-alive",
60       "Cache-Control": "no-cache"
61     };
62     response.writeHead(200, headers);
63
64     /* Add this new client to our list of clients. */
65     const id = this.add_client(response);
66
67     /* And queue up cleanup to be triggered on client close. */
68     request.on('close', () => {
69       this.remove_client(id);
70     });
71   }
72
73 }
74
75 module.exports = Game;