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"
30 void EntityState::create(std::vector
<EntityVariable
> &typeinfo
, int time
)
34 for (unsigned int i
= 0; i
< typeinfo
.size(); i
++)
36 typeinfo
[i
].write(&data
);
40 void EntityVariable::write(Buffer
*buffer
)
45 buffer
->writeInt(*(int*)ptr
);
48 buffer
->writeWord(*(short*)ptr
);
51 buffer
->writeByte(*(char*)ptr
);
54 buffer
->writeFloat(*(float*)ptr
);
57 buffer
->writeFloat(*(double*)ptr
);
63 void EntityVariable::read(Buffer
*buffer
)
68 *(int*)ptr
= buffer
->readInt();
71 *(short*)ptr
= buffer
->readWord();
74 *(char*)ptr
= buffer
->readByte();
77 *(float*)ptr
= buffer
->readFloat();
80 *(double*)ptr
= buffer
->readFloat();
96 bool Entity::init(std::string type
)
101 bool Entity::destroy(void)
106 bool Entity::saveState(EntityState
*state
)
108 state
->create(variables
, Game::get()->getTime());
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
);
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);
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
)
140 int val1
= from
->data
.readInt();
141 int val2
= to
->data
.readInt();
145 buffer
->writeInt(val2
);
151 short val1
= from
->data
.readWord();
152 short val2
= to
->data
.readWord();
156 buffer
->writeWord(val2
);
162 char val1
= from
->data
.readByte();
163 char val2
= to
->data
.readByte();
167 buffer
->writeByte(val2
);
174 float val1
= from
->data
.readFloat();
175 float val2
= to
->data
.readFloat();
176 if (fabs(val1
- val2
) > 0.001)
179 buffer
->writeFloat(val2
);
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();
198 bool Entity::sendFullUpdate(Buffer
*buffer
)
202 bool Entity::sendDeltaUpdate(Buffer
*buffer
, int time1
, int time2
)
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;
220 char *dest
= to
->data
.getData() + to
->data
.getPosition();
221 switch (variables
[i
].type
)
224 to
->data
.setPosition(1, true);
225 *dest
= buffer
->readByte();
228 to
->data
.setPosition(2, true);
229 *(short*)dest
= buffer
->readWord();
234 to
->data
.setPosition(4, true);
235 *(int*)dest
= buffer
->readInt();
243 // Skip the variable in the state buffer
244 switch (variables
[i
].type
)
247 to
->data
.setPosition(1, true);
250 to
->data
.setPosition(2, true);
255 to
->data
.setPosition(4, true);
264 EntityState
*Entity::getState(int time
)
266 EntityState
*state
= 0;
267 std::list
<EntityState
*>::iterator it
;
268 // Search past states
270 while (it
!= past
.end())
272 if ((*it
)->timestamp
== time
)
281 // Search future state
283 while (it
!= future
.end())
285 if ((*it
)->timestamp
== time
)
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;
310 //char *dest = state->data.getData() + state->data.getPosition();
311 switch (variables
[i
].type
)
314 if (updatebuffer
->readByte() != state
->data
.readByte())
316 printf("Byte differs.\n");
317 updatebuffer
->setPosition(bufferposition
);
322 if (updatebuffer
->readWord() != state
->data
.readWord())
324 printf("Word differs.\n");
325 updatebuffer
->setPosition(bufferposition
);
333 int a
= updatebuffer
->readInt();
334 int b
= state
->data
.readInt();
337 printf("Int differs (%d vs %d).\n", a
, b
);
338 updatebuffer
->setPosition(bufferposition
);
342 printf("Int ok (%d vs %d).\n", a
, b
);
351 // Skip the variable in the state buffer
352 switch (variables
[i
].type
)
355 state
->data
.setPosition(1, true);
358 state
->data
.setPosition(2, true);
363 state
->data
.setPosition(4, true);
370 updatebuffer
->setPosition(bufferposition
);
374 void Entity::discardStates(bool future
, bool past
)
376 std::list
<EntityState
*>::iterator it
;
377 // Delete states in the future
380 it
= this->future
.begin();
381 while (it
!= this->future
.end())
386 this->future
.clear();
388 // Delete states from the past
391 it
= this->past
.begin();
392 while (it
!= this->past
.end())
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
409 printf("Deleting %d.\n", (*past
.rbegin())->timestamp
);
410 delete *past
.rbegin();
411 std::list
<EntityState
*>::iterator it
= past
.end();
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
;
425 printf("Inserting %d\n", newstate
->timestamp
);
426 past
.push_front(newstate
);
429 bool Entity::reset(int time
, bool deletefuture
)
431 EntityState
*newstate
= 0;
432 std::list
<EntityState
*>::iterator it
;
435 while (it
!= past
.end())
437 if ((*it
)->timestamp
== time
)
447 while (it
!= future
.end())
449 if ((*it
)->timestamp
== time
)
459 // Switch to selected state
460 restoreState(newstate
);
461 // Rearrange states so that the lists are valid again
463 while (it
!= past
.end())
465 if ((*it
)->timestamp
> time
)
467 EntityState
*state
= *it
;
470 future
.push_back(state
);
478 while (it
!= future
.end())
480 if ((*it
)->timestamp
<= time
)
482 EntityState
*state
= *it
;
483 it
= future
.erase(it
);
484 past
.push_front(state
);
489 // Delete rest of future states
493 while (it
!= future
.end())
502 bool Entity::rewind(void)
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
)
520 if (it
== past
.end())
527 if (!state1
|| !state2
) return false;
528 // Write delta update into buffer
529 sendDeltaUpdate(buffer
, state1
, state2
);
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
)
545 if (it
== past
.end())
552 if (!state1
|| !state2
) return false;
554 applyDeltaUpdate(buffer
, state1
, state2
);
557 restoreState(state2
);
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
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
;
598 lastcommands
.erase(lastcommands
.begin());
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
)
621 void Entity::setID(int id
)
625 int Entity::getID(void)
630 void Entity::update(float msecs
)
634 std::string
Entity::getType(void)
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;