-
Notifications
You must be signed in to change notification settings - Fork 1
/
module_client.js
160 lines (118 loc) · 4.37 KB
/
module_client.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
var CLIENT_MOVE_SPEED = 10; // units / sec
var FULLREFRESH_INTERVAL = 5; // sec, time between full refresh of nearby entities
module.exports = function(entity_module_builder) {
entity_module_builder.registerModule(
"client",
"this module handles client interaction and data exchange with the scene",
function(module) {
// overriding respond function
module.respondToMessage = function(message, data) {
switch(message) {
// regularly send new data on update event
case "update":
var full_refresh = false;
var now = Date.now();
if(now - this.last_refresh_time >= FULLREFRESH_INTERVAL * 1000) {
this.last_refresh_time = now;
full_refresh = true;
}
var nearby_entities = this.API.getNearbyEntities(this.entity_id);
var my_entity = this.API.getEntityById(this.entity_id);
var stream_data = [];
var drawing_instructions, modules;
var i, j;
var nearby_entity, recorded_entity, entity_data;
for(i=0; i<nearby_entities.length; i++) {
nearby_entity = nearby_entities[i];
recorded_entity = this.tracked_entities_collection[nearby_entity.id];
// skip if no state changed
if(recorded_entity && recorded_entity.entity_state == nearby_entity.state_counter && !full_refresh) {
continue;
}
// if no state saved for this entity: create a record
if(!recorded_entity) {
recorded_entity = {
entity_state: -1
};
this.tracked_entities_collection[nearby_entity.id] = recorded_entity;
}
entity_data = {};
// gather entity state
entity_data.position = nearby_entity.position;
entity_data.target_position = nearby_entity.target_position;
entity_data.speed = nearby_entity.speed;
if(nearby_entity == my_entity) {
entity_data.focus = true;
}
// save entity state on module
recorded_entity.entity_state = nearby_entity.state_counter;
// send drawing instructions
entity_data.drawing_instructions = [];
modules = this.API.getModulesByEntityId(nearby_entity.id);
for(j=0; j<modules.length; j++) {
modules[j].appendDrawingInstructions(entity_data.drawing_instructions);
}
// add to stream
stream_data.push({ entity_id: nearby_entity.id, entity_data: entity_data });
}
//send collected entities data to the client
if(stream_data.length > 0) {
this.socket.emit('entity_data', stream_data);
}
break;
case "late_update":
// clear speech stack
this.speech_stack = [];
break;
// the user clicked on the ground: go there
case "click_world":
this.API.moveEntity(this.entity_id, data.click_position, CLIENT_MOVE_SPEED);
break;
// inspector panel request
// we send back to the socket the contents of our block
case "inspector_panel":
data.socket.emit("inspector_panel_block", {
elements: [
this.API.outputPlainText("Socket id: "+this.socket.id),
this.API.outputTextField("Display name: ", "client_display_name", this.display_name)
],
rank: this.rank
});
break;
case "inspector_panel_change":
if(data.client_display_name) {
this.API.setChanged(this.entity_id);
this.display_name = data.client_display_name;
}
break;
// handle incoming commands
// temp: simply display a speech bubble
case "command_line_entered":
this.speech_stack.push(data.command);
this.API.setChanged(this.entity_id);
break;
}
};
// override render function
module.appendDrawingInstructions = function(instructions_list) {
// display name over entity
this.API.drawTextBubble(instructions_list, 0, 3, 0, 0, 0, 0, 0.5, this.display_name);
// output speech bubbles and clear stack
for(var i=0; i<this.speech_stack.length; i++) {
this.API.fireSpeechBubble(instructions_list, this.speech_stack[i]);
//console.log("entity "+this.entity_id+" sent speech: "+this.speech_stack[i]);
}
};
module.socket = null; // this must be set manually!
// for each entity that we sent to the client, save its state counter and geometry state counter
// this way, we know if the entity data must be resent or not!
// key: entity_id, value: { state_counter: X }
module.tracked_entities_collection = {};
module.last_refresh_time = 0;
module.display_name = "bob";
// this is a stack of speech lines that we need to output
module.speech_stack = [];
},
[] // registered channels
);
};