comparison engine/core/model/structures/instance.cpp @ 181:56ac89189bc4

fixed time handling in fife: - the time scaling method was unreliable when changing the time factors (jumping in the moment of the change) - replaced much calls to SDL_GetTicks with TimerManager::instance()->getTime() - some other time related cleanup
author spq@33b003aa-7bff-0310-803a-e67f0ece8222
date Sat, 31 Jan 2009 04:15:43 +0000
parents 64e7fe3d4288
children 3d0cc4545938
comparison
equal deleted inserted replaced
180:66bd7f8c541e 181:56ac89189bc4
30 // First block: files included from the FIFE root src directory 30 // First block: files included from the FIFE root src directory
31 // Second block: files included from the same folder 31 // Second block: files included from the same folder
32 #include "util/log/logger.h" 32 #include "util/log/logger.h"
33 #include "util/base/exception.h" 33 #include "util/base/exception.h"
34 #include "util/math/fife_math.h" 34 #include "util/math/fife_math.h"
35 #include "util/time/timemanager.h"
35 #include "model/metamodel/grids/cellgrid.h" 36 #include "model/metamodel/grids/cellgrid.h"
36 #include "model/metamodel/abstractpather.h" 37 #include "model/metamodel/abstractpather.h"
37 #include "model/metamodel/action.h" 38 #include "model/metamodel/action.h"
38 #include "model/metamodel/timeprovider.h" 39 #include "model/metamodel/timeprovider.h"
39 #include "model/structures/layer.h" 40 #include "model/structures/layer.h"
50 ActionInfo(AbstractPather* pather, const Location& curloc): 51 ActionInfo(AbstractPather* pather, const Location& curloc):
51 m_action(NULL), 52 m_action(NULL),
52 m_target(NULL), 53 m_target(NULL),
53 m_speed(0), 54 m_speed(0),
54 m_repeating(false), 55 m_repeating(false),
55 m_action_start_time(SDL_GetTicks()), 56 m_action_start_time(0),
56 m_prev_call_time(m_action_start_time), 57 m_prev_call_time(0),
57 m_pather_session_id(-1), 58 m_pather_session_id(-1),
58 m_pather(pather), 59 m_pather(pather),
59 m_leader(NULL) {} 60 m_leader(NULL) {}
60 61
61 ~ActionInfo() { 62 ~ActionInfo() {
76 bool m_repeating; 77 bool m_repeating;
77 // action start time (ticks) 78 // action start time (ticks)
78 unsigned int m_action_start_time; 79 unsigned int m_action_start_time;
79 // ticks since last call 80 // ticks since last call
80 unsigned int m_prev_call_time; 81 unsigned int m_prev_call_time;
81 // current time for action processing (set by Instance::update), optimized to avoid multiple calls to GetTicks
82 unsigned int m_cur_time;
83 // session id for pather 82 // session id for pather
84 int m_pather_session_id; 83 int m_pather_session_id;
85 // pather 84 // pather
86 AbstractPather* m_pather; 85 AbstractPather* m_pather;
87 // leader for follow activity 86 // leader for follow activity
91 class SayInfo { 90 class SayInfo {
92 public: 91 public:
93 SayInfo(const std::string& txt, unsigned int duration): 92 SayInfo(const std::string& txt, unsigned int duration):
94 m_txt(txt), 93 m_txt(txt),
95 m_duration(duration), 94 m_duration(duration),
96 m_start_time(SDL_GetTicks()) { 95 m_start_time(0) {}
97 } 96
98 std::string m_txt; 97 std::string m_txt;
99 unsigned int m_duration; 98 unsigned int m_duration;
100 unsigned int m_start_time; 99 unsigned int m_start_time;
101 }; 100 };
102 101
249 if (!m_activity->m_actioninfo->m_action) { 248 if (!m_activity->m_actioninfo->m_action) {
250 delete m_activity->m_actioninfo; 249 delete m_activity->m_actioninfo;
251 m_activity->m_actioninfo = NULL; 250 m_activity->m_actioninfo = NULL;
252 throw NotFound(std::string("action ") + action_name + " not found"); 251 throw NotFound(std::string("action ") + action_name + " not found");
253 } 252 }
253 m_activity->m_actioninfo->m_prev_call_time = m_activity->m_actioninfo->m_action_start_time = getRuntime();
254 } 254 }
255 255
256 void Instance::move(const std::string& action_name, const Location& target, const double speed) { 256 void Instance::move(const std::string& action_name, const Location& target, const double speed) {
257 initializeChanges(); 257 initializeChanges();
258 initalizeAction(action_name); 258 initalizeAction(action_name);
284 delete m_activity->m_sayinfo; 284 delete m_activity->m_sayinfo;
285 m_activity->m_sayinfo = NULL; 285 m_activity->m_sayinfo = NULL;
286 286
287 if (text != "") { 287 if (text != "") {
288 m_activity->m_sayinfo = new SayInfo(text, duration); 288 m_activity->m_sayinfo = new SayInfo(text, duration);
289 m_activity->m_sayinfo->m_start_time = getRuntime();
289 } 290 }
290 } 291 }
291 292
292 const std::string* Instance::getSayText() const { 293 const std::string* Instance::getSayText() const {
293 if (m_activity && m_activity->m_sayinfo) { 294 if (m_activity && m_activity->m_sayinfo) {
306 307
307 bool Instance::process_movement() { 308 bool Instance::process_movement() {
308 FL_DBG(_log, "Moving..."); 309 FL_DBG(_log, "Moving...");
309 ActionInfo* info = m_activity->m_actioninfo; 310 ActionInfo* info = m_activity->m_actioninfo;
310 // timeslice for this movement 311 // timeslice for this movement
311 unsigned int timedelta = scaleTime(getTotalTimeMultiplier(), info->m_cur_time - info->m_prev_call_time); 312 unsigned int timedelta = m_activity->m_timeprovider->getGameTime() - info->m_prev_call_time;
312 FL_DBG(_log, LMsg("timedelta ") << timedelta << " prevcalltime " << info->m_prev_call_time); 313 FL_DBG(_log, LMsg("timedelta ") << timedelta << " prevcalltime " << info->m_prev_call_time);
313 // how far we can travel 314 // how far we can travel
314 double distance_to_travel = (static_cast<double>(timedelta) / 1000.0) * info->m_speed; 315 double distance_to_travel = (static_cast<double>(timedelta) / 1000.0) * info->m_speed;
315 FL_DBG(_log, LMsg("dist ") << distance_to_travel); 316 FL_DBG(_log, LMsg("dist ") << distance_to_travel);
316 317
329 return true; 330 return true;
330 } 331 }
331 return false; 332 return false;
332 } 333 }
333 334
334 InstanceChangeInfo Instance::update(unsigned int curticks) { 335 InstanceChangeInfo Instance::update() {
335 if (!m_activity) { 336 if (!m_activity) {
336 return ICHANGE_NO_CHANGES; 337 return ICHANGE_NO_CHANGES;
337 } 338 }
338 m_activity->update(*this); 339 m_activity->update(*this);
339 if (!m_activity->m_timeprovider) { 340 if (!m_activity->m_timeprovider) {
340 bindTimeProvider(); 341 bindTimeProvider();
341 } 342 }
342
343 if (curticks == 0) {
344 curticks = SDL_GetTicks();
345 }
346 ActionInfo* info = m_activity->m_actioninfo; 343 ActionInfo* info = m_activity->m_actioninfo;
347 if (info) { 344 if (info) {
348 info->m_cur_time = curticks; 345 FL_DBG(_log, "updating instance");
349 FL_DBG(_log, LMsg("updating instance, ticks = ") << curticks);
350 346
351 if (info->m_target) { 347 if (info->m_target) {
352 FL_DBG(_log, "action contains target for movement"); 348 FL_DBG(_log, "action contains target for movement");
353 // update target if needed 349 // update target if needed
354 if (info->m_leader && (info->m_leader->getLocationRef() != *info->m_target)) { 350 if (info->m_leader && (info->m_leader->getLocationRef() != *info->m_target)) {
359 FL_DBG(_log, "movement finished"); 355 FL_DBG(_log, "movement finished");
360 finalizeAction(); 356 finalizeAction();
361 } 357 }
362 } else { 358 } else {
363 FL_DBG(_log, "action does not contain target for movement"); 359 FL_DBG(_log, "action does not contain target for movement");
364 if (scaleTime(getTotalTimeMultiplier(), curticks - info->m_action_start_time) >= info->m_action->getDuration()) { 360 if (m_activity->m_timeprovider->getGameTime() - info->m_action_start_time >= info->m_action->getDuration()) {
365 if (info->m_repeating) { 361 if (info->m_repeating) {
366 info->m_action_start_time = curticks; 362 info->m_action_start_time = m_activity->m_timeprovider->getGameTime();
367 } else { 363 } else {
368 finalizeAction(); 364 finalizeAction();
369 } 365 }
370 } 366 }
371 } 367 }
372 368
373 m_activity->m_actioninfo->m_prev_call_time = curticks; 369 m_activity->m_actioninfo->m_prev_call_time = m_activity->m_timeprovider->getGameTime();
374 } 370 }
375 if (m_activity->m_sayinfo) { 371 if (m_activity->m_sayinfo) {
376 if (m_activity->m_sayinfo->m_duration > 0) { 372 if (m_activity->m_sayinfo->m_duration > 0) {
377 if (scaleTime(getTotalTimeMultiplier(), curticks - m_activity->m_sayinfo->m_start_time) > m_activity->m_sayinfo->m_duration) { 373 if (m_activity->m_timeprovider->getGameTime() >= m_activity->m_sayinfo->m_start_time + m_activity->m_sayinfo->m_duration) {
378 say(""); 374 say("");
379 } 375 }
380 } 376 }
381 } 377 }
382 return m_changeinfo; 378 return m_changeinfo;
430 //m_facinglocation->setLayerCoordinates(ModelCoordinate(1,0)); 426 //m_facinglocation->setLayerCoordinates(ModelCoordinate(1,0));
431 } 427 }
432 return *m_facinglocation; 428 return *m_facinglocation;
433 } 429 }
434 430
435 int Instance::getActionRuntime() const { 431 unsigned int Instance::getActionRuntime() {
436 if (m_activity && m_activity->m_actioninfo) { 432 if (m_activity && m_activity->m_actioninfo) {
437 return SDL_GetTicks() - m_activity->m_actioninfo->m_action_start_time; 433 if(!m_activity->m_timeprovider)
438 } 434 bindTimeProvider();
439 return -1; 435 return m_activity->m_timeprovider->getGameTime() - m_activity->m_actioninfo->m_action_start_time;
440 } 436 }
441 437 return getRuntime();
438 }
439
442 void Instance::bindTimeProvider() { 440 void Instance::bindTimeProvider() {
443 float multiplier = 1.0; 441 float multiplier = 1.0;
444 if (m_activity->m_timeprovider) { 442 if (m_activity->m_timeprovider) {
445 multiplier = m_activity->m_timeprovider->getMultiplier(); 443 multiplier = m_activity->m_timeprovider->getMultiplier();
446 } 444 }
456 if (!m_activity->m_timeprovider) { 454 if (!m_activity->m_timeprovider) {
457 m_activity->m_timeprovider = new TimeProvider(NULL); 455 m_activity->m_timeprovider = new TimeProvider(NULL);
458 } 456 }
459 m_activity->m_timeprovider->setMultiplier(multiplier); 457 m_activity->m_timeprovider->setMultiplier(multiplier);
460 } 458 }
461 459
462 void Instance::refresh() { 460 void Instance::refresh() {
463 initializeChanges(); 461 initializeChanges();
464 bindTimeProvider(); 462 bindTimeProvider();
465 } 463 }
466 464
467 void Instance::setTimeMultiplier(float multip) { 465 void Instance::setTimeMultiplier(float multip) {
468 initializeChanges(); 466 initializeChanges();
469 if (!m_activity->m_timeprovider) { 467 if (!m_activity->m_timeprovider) {
470 bindTimeProvider(); 468 bindTimeProvider();
471 } 469 }
472 m_activity->m_timeprovider->setMultiplier(multip); 470 m_activity->m_timeprovider->setMultiplier(multip);
473 } 471 }
474 472
475 float Instance::getTimeMultiplier() { 473 float Instance::getTimeMultiplier() {
476 if (m_activity && m_activity->m_timeprovider) { 474 if (m_activity && m_activity->m_timeprovider) {
477 return m_activity->m_timeprovider->getMultiplier(); 475 return m_activity->m_timeprovider->getMultiplier();
478 } 476 }
479 return 1.0; 477 return 1.0;
480 } 478 }
481 479
482 float Instance::getTotalTimeMultiplier() { 480 float Instance::getTotalTimeMultiplier() {
483 if (m_activity && m_activity->m_timeprovider) { 481 if (m_activity && m_activity->m_timeprovider) {
484 return m_activity->m_timeprovider->getTotalMultiplier(); 482 return m_activity->m_timeprovider->getTotalMultiplier();
485 } 483 }
484 if (m_location.getLayer()) {
485 Map* map = m_location.getLayer()->getMap();
486 if (map && map->getTimeProvider()) {
487 return map->getTimeProvider()->getTotalMultiplier();
488 }
489 }
486 return 1.0; 490 return 1.0;
487 } 491 }
492
493 unsigned int Instance::getRuntime() {
494 if (m_activity) {
495 if(!m_activity->m_timeprovider)
496 bindTimeProvider();
497 return m_activity->m_timeprovider->getGameTime();
498 }
499 if (m_location.getLayer()) {
500 Map* map = m_location.getLayer()->getMap();
501 if (map && map->getTimeProvider()) {
502 return map->getTimeProvider()->getGameTime();
503 }
504 }
505 return TimeManager::instance()->getTime();
506 }
488 } 507 }
489