- Partly implemented client side prediction (still unstable).
[peakengine.git] / engine / src / core / Entity.cpp
blob2194f3acb6793a1612af23d7d6a20edc16f069ed
1 /*
2 Copyright (C) 2009 Mathias Gottschlag
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in the
6 Software without restriction, including without limitation the rights to use,
7 copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8 Software, and to permit persons to whom the Software is furnished to do so,
9 subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 #include "core/Entity.h"
23 #include "core/Buffer.h"
24 #include "core/Game.h"
26 #include <math.h>
28 namespace peak
30 void EntityState::create(std::vector<EntityVariable> &typeinfo, int time)
32 timestamp = time;
33 data.clear();
34 for (unsigned int i = 0; i < typeinfo.size(); i++)
36 typeinfo[i].write(&data);
40 void EntityVariable::write(Buffer *buffer)
42 switch (type)
44 case EVT_Int32:
45 buffer->writeInt(*(int*)ptr);
46 break;
47 case EVT_Int16:
48 buffer->writeWord(*(short*)ptr);
49 break;
50 case EVT_Int8:
51 buffer->writeByte(*(char*)ptr);
52 break;
53 case EVT_Float:
54 buffer->writeFloat(*(float*)ptr);
55 break;
56 case EVT_Double:
57 buffer->writeFloat(*(double*)ptr);
58 break;
59 default:
60 break;
63 void EntityVariable::read(Buffer *buffer)
65 switch (type)
67 case EVT_Int32:
68 *(int*)ptr = buffer->readInt();
69 break;
70 case EVT_Int16:
71 *(short*)ptr = buffer->readWord();
72 break;
73 case EVT_Int8:
74 *(char*)ptr = buffer->readByte();
75 break;
76 case EVT_Float:
77 *(float*)ptr = buffer->readFloat();
78 break;
79 case EVT_Double:
80 *(double*)ptr = buffer->readFloat();
81 break;
82 default:
83 break;
87 Entity::Entity()
89 lastcommandtime = 0;
90 lastcommandid = 0;
92 Entity::~Entity()
96 bool Entity::init(std::string type)
98 this->type = type;
99 return true;
101 bool Entity::destroy(void)
103 return false;
106 bool Entity::saveState(EntityState *state)
108 state->create(variables, Game::get()->getTime());
109 return true;
111 bool Entity::restoreState(EntityState *state)
113 state->data.setPosition(0);
114 for (unsigned int i = 0; i < variables.size(); i++)
116 variables[i].read(&state->data);
118 return false;
120 bool Entity::sendDeltaUpdate(Buffer *buffer, EntityState *from, EntityState *to)
122 from->data.setPosition(0);
123 to->data.setPosition(0);
124 // Write empty mask first (we fill it in later)
125 unsigned int maskpos = buffer->getDataSize();
126 int masksize = (variables.size() + 7) / 8;
127 for (int i = 0; i < masksize; i++)
129 buffer->writeByte(0);
131 // Write variables
132 for (unsigned int i = 0; i < variables.size(); i++)
134 bool changed = false;
135 // Check whether variable changed and write value into buffer
136 switch (variables[i].type)
138 case EVT_Int32:
140 int val1 = from->data.readInt();
141 int val2 = to->data.readInt();
142 if (val1 != val2)
144 changed = true;
145 buffer->writeInt(val2);
147 break;
149 case EVT_Int16:
151 short val1 = from->data.readWord();
152 short val2 = to->data.readWord();
153 if (val1 != val2)
155 changed = true;
156 buffer->writeWord(val2);
158 break;
160 case EVT_Int8:
162 char val1 = from->data.readByte();
163 char val2 = to->data.readByte();
164 if (val1 != val2)
166 changed = true;
167 buffer->writeByte(val2);
169 break;
171 case EVT_Float:
172 case EVT_Double:
174 float val1 = from->data.readFloat();
175 float val2 = to->data.readFloat();
176 if (fabs(val1 - val2) > 0.001)
178 changed = true;
179 buffer->writeFloat(val2);
181 break;
183 default:
184 break;
186 if (changed)
188 // Set needed bit in the mask
189 unsigned char *data = (unsigned char*)buffer->getData();
190 data += maskpos + (i / 8);
191 *data |= 1 << (i % 8);
194 unsigned char *data = (unsigned char*)buffer->getData();
195 data += maskpos;
196 return true;
198 bool Entity::sendFullUpdate(Buffer *buffer)
200 return true;
202 bool Entity::sendDeltaUpdate(Buffer *buffer, int time1, int time2)
204 return false;
206 bool Entity::applyDeltaUpdate(Buffer *buffer, EntityState *from, EntityState *to)
208 to->data.setPosition(0);
209 // Get mask which contains the changed variables
210 int masksize = (variables.size() + 7) / 8;
211 unsigned char *mask = (unsigned char*)buffer->getData();
212 mask += buffer->getPosition();
213 buffer->setPosition(masksize, true);
214 // Loop through the variables and set them if they got changed
215 for (unsigned int i = 0; i < variables.size(); i++)
217 bool changed = (mask[i / 8] & (1 << (i % 8))) != 0;
218 if (changed)
220 char *dest = to->data.getData() + to->data.getPosition();
221 switch (variables[i].type)
223 case EVT_Int8:
224 to->data.setPosition(1, true);
225 *dest = buffer->readByte();
226 break;
227 case EVT_Int16:
228 to->data.setPosition(2, true);
229 *(short*)dest = buffer->readWord();
230 break;
231 case EVT_Int32:
232 case EVT_Float:
233 case EVT_Double:
234 to->data.setPosition(4, true);
235 *(int*)dest = buffer->readInt();
236 break;
237 default:
238 break;
241 else
243 // Skip the variable in the state buffer
244 switch (variables[i].type)
246 case EVT_Int8:
247 to->data.setPosition(1, true);
248 break;
249 case EVT_Int16:
250 to->data.setPosition(2, true);
251 break;
252 case EVT_Int32:
253 case EVT_Float:
254 case EVT_Double:
255 to->data.setPosition(4, true);
256 break;
257 default:
258 break;
262 return true;
264 EntityState *Entity::getState(int time)
266 EntityState *state = 0;
267 std::list<EntityState*>::iterator it;
268 // Search past states
269 it = past.begin();
270 while (it != past.end())
272 if ((*it)->timestamp == time)
274 state = *it;
275 break;
277 it++;
279 if (!state)
281 // Search future state
282 it = future.begin();
283 while (it != future.end())
285 if ((*it)->timestamp == time)
287 state = *it;
288 break;
290 it++;
293 return state;
295 bool Entity::checkState(EntityState *state, Buffer *updatebuffer)
297 int bufferposition = updatebuffer->getPosition();
298 state->data.setPosition(0);
299 // Get mask which contains the changed variables
300 int masksize = (variables.size() + 7) / 8;
301 unsigned char *mask = (unsigned char*)updatebuffer->getData();
302 mask += updatebuffer->getPosition();
303 updatebuffer->setPosition(masksize, true);
304 // Loop through the variables and set them if they got changed
305 for (unsigned int i = 0; i < variables.size(); i++)
307 bool changed = (mask[i / 8] & (1 << (i % 8))) != 0;
308 if (changed)
310 //char *dest = state->data.getData() + state->data.getPosition();
311 switch (variables[i].type)
313 case EVT_Int8:
314 if (updatebuffer->readByte() != state->data.readByte())
316 printf("Byte differs.\n");
317 updatebuffer->setPosition(bufferposition);
318 return false;
320 break;
321 case EVT_Int16:
322 if (updatebuffer->readWord() != state->data.readWord())
324 printf("Word differs.\n");
325 updatebuffer->setPosition(bufferposition);
326 return false;
328 break;
329 case EVT_Int32:
330 case EVT_Float:
331 case EVT_Double:
333 int a = updatebuffer->readInt();
334 int b = state->data.readInt();
335 if (a != b)
337 printf("Int differs (%d vs %d).\n", a, b);
338 updatebuffer->setPosition(bufferposition);
339 return false;
341 else
342 printf("Int ok (%d vs %d).\n", a, b);
344 break;
345 default:
346 break;
349 else
351 // Skip the variable in the state buffer
352 switch (variables[i].type)
354 case EVT_Int8:
355 state->data.setPosition(1, true);
356 break;
357 case EVT_Int16:
358 state->data.setPosition(2, true);
359 break;
360 case EVT_Int32:
361 case EVT_Float:
362 case EVT_Double:
363 state->data.setPosition(4, true);
364 break;
365 default:
366 break;
370 updatebuffer->setPosition(bufferposition);
371 return true;
374 void Entity::discardStates(bool future, bool past)
376 std::list<EntityState*>::iterator it;
377 // Delete states in the future
378 if (future)
380 it = this->future.begin();
381 while (it != this->future.end())
383 delete *it;
384 it++;
386 this->future.clear();
388 // Delete states from the past
389 if (past)
391 it = this->past.begin();
392 while (it != this->past.end())
394 delete *it;
395 it++;
397 this->past.clear();
401 bool Entity::save(void)
403 printf("States: %d\n", (int)(past.size() + future.size()));
404 if (past.size() + future.size() >= maxstates)
406 // Delete oldest state
407 if (past.size() > 0)
409 printf("Deleting %d.\n", (*past.rbegin())->timestamp);
410 delete *past.rbegin();
411 std::list<EntityState*>::iterator it = past.end();
412 it--;
413 past.erase(it);
415 else
417 printf("Deleting %d.\n", (*future.begin())->timestamp);
418 delete *future.begin();
419 future.erase(past.begin());
422 // Save current state
423 EntityState *newstate = new EntityState;
424 saveState(newstate);
425 printf("Inserting %d\n", newstate->timestamp);
426 past.push_front(newstate);
427 return true;
429 bool Entity::reset(int time, bool deletefuture)
431 EntityState *newstate = 0;
432 std::list<EntityState*>::iterator it;
433 // Get state to use
434 it = past.begin();
435 while (it != past.end())
437 if ((*it)->timestamp == time)
439 newstate = *it;
440 break;
442 it++;
444 if (!newstate)
446 it = future.begin();
447 while (it != future.end())
449 if ((*it)->timestamp == time)
451 newstate = *it;
452 break;
454 it++;
457 if (!newstate)
458 return false;
459 // Switch to selected state
460 restoreState(newstate);
461 // Rearrange states so that the lists are valid again
462 it = past.begin();
463 while (it != past.end())
465 if ((*it)->timestamp > time)
467 EntityState *state = *it;
468 it = past.erase(it);
469 if (!deletefuture)
470 future.push_back(state);
471 else
472 delete state;
473 continue;
475 it++;
477 it = future.begin();
478 while (it != future.end())
480 if ((*it)->timestamp <= time)
482 EntityState *state = *it;
483 it = future.erase(it);
484 past.push_front(state);
485 continue;
487 it++;
489 // Delete rest of future states
490 if (deletefuture)
492 it = future.begin();
493 while (it != future.end())
495 delete *it;
496 it++;
498 future.clear();
500 return true;
502 bool Entity::rewind(void)
504 return false;
506 bool Entity::update(Buffer *buffer)
508 int currenttime = Game::get()->getTime();
509 EntityState *state1 = 0;
510 EntityState *state2 = 0;
511 if (past.size() == 0) return false;
512 // Get two states to compare
513 std::list<EntityState*>::iterator it = past.begin();
514 while (it != past.end())
516 if ((*it)->timestamp == currenttime)
518 state2 = *it;
519 it++;
520 if (it == past.end())
521 break;
522 state1 = *it;
523 break;
525 it++;
527 if (!state1 || !state2) return false;
528 // Write delta update into buffer
529 sendDeltaUpdate(buffer, state1, state2);
530 return true;
532 bool Entity::injectUpdate(int time, Buffer *buffer, bool apply)
534 EntityState *state1 = 0;
535 EntityState *state2 = 0;
536 if (past.size() == 0) return false;
537 // Get two states to compare
538 std::list<EntityState*>::iterator it = past.begin();
539 while (it != past.end())
541 if ((*it)->timestamp == time)
543 state2 = *it;
544 it++;
545 if (it == past.end())
546 break;
547 state1 = *it;
548 break;
550 it++;
552 if (!state1 || !state2) return false;
553 // Apply update
554 applyDeltaUpdate(buffer, state1, state2);
555 if (apply)
557 restoreState(state2);
559 return true;
562 void Entity::sendCommand(EntityCommand *command)
564 // FIXME: Causes problems if both server and client send commands
565 if (!Game::get()->isServer())
566 command->id = ++lastcommandid;
567 else if (command->id)
568 lastcommandid = command->id;
569 //command->timestamp = Game::get()->getTime();
570 lastcommands.push_back(command);
571 lastcommandtime = command->timestamp;
572 if (!Game::get()->isServer())
574 // Send command to server
575 Buffer msg;
576 msg.writeByte(1);
577 msg.writeWord(getID());
578 msg.writeWord(command->id);
579 msg += command->data;
580 Game::get()->sendServerData(&msg, true);
581 applyCommand(command);
584 void Entity::applyCommand(EntityCommand *command)
587 void Entity::applyNextCommand(void)
589 if (Game::get()->isServer())
591 while (lastcommands.size() != 0)
593 EntityCommand *cmd = *lastcommands.begin();
594 if (cmd->timestamp <= Game::get()->getTime())
596 lastcommandtime = cmd->timestamp;
597 applyCommand(cmd);
598 lastcommands.erase(lastcommands.begin());
600 else break;
603 else
607 void Entity::applyCommand(int time)
609 std::list<EntityCommand*>::iterator it = lastcommands.begin();
610 while (it != lastcommands.end())
612 EntityCommand *cmd = *it;
613 if (cmd->timestamp == time)
615 applyCommand(cmd);
617 it++;
621 void Entity::setID(int id)
623 this->id = id;
625 int Entity::getID(void)
627 return id;
630 void Entity::update(float msecs)
634 std::string Entity::getType(void)
636 return type;
639 void Entity::add(Model *model, unsigned int flags)
641 variables.push_back(EntityVariable(EVT_Object3D, model));
643 void Entity::add(int *variable, unsigned int flags)
645 variables.push_back(EntityVariable(EVT_Int32, variable));
647 void Entity::add(float *variable, unsigned int flags)
649 variables.push_back(EntityVariable(EVT_Float, variable));
651 void Entity::add(unsigned char *variable, unsigned int flags)
653 variables.push_back(EntityVariable(EVT_Int8, variable));
655 void Entity::finalize(void)
659 unsigned int Entity::maxstates = 20;