nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "Nux.h" 00024 #include "TimerProc.h" 00025 #include "WindowCompositor.h" 00026 #include "WindowThread.h" 00027 00028 class BaseWindow; 00029 00030 namespace nux 00031 { 00032 00033 typedef struct 00034 { 00035 long sec; // seconds 00036 long usec; // and microseconds 00037 } TimeStruct; 00038 00042 static bool TimeIsGreater (TimeStruct t1, TimeStruct t2); 00043 static void TimeRightNow (TimeStruct *tv); 00044 static void Addmillisecs (TimeStruct *tv, unsigned int milliseconds); 00045 //static t_u32 TimeDiff(TimeStruct t1, TimeStruct t2); 00046 00047 static NThreadSafeCounter TimerUID = 0x01234567; 00048 00049 class TimerObject 00050 { 00051 public: 00052 TimerObject(); 00053 00054 bool operator == (const TimerObject &timer_object); 00055 00057 TimeStruct when; 00058 void *CallbackData; 00059 TimerFunctor *TimerCallback; 00060 00062 float Param; 00063 float ProgressDelta; 00064 int Type; 00065 int ScheduledIteration; 00066 int ProgressIterationCount; 00067 int Period; 00068 int Duration; 00069 int ElapsedTime; 00070 bool MarkedForRemoval; 00071 BaseWindow *Window; 00072 TimerObject *next; 00073 TimerObject *prev; 00074 t_u32 glibid; 00075 t_u32 uid; 00076 }; 00077 00078 TimerObject::TimerObject() 00079 { 00080 Type = 0; 00081 CallbackData = 0; 00082 TimerCallback = 0; 00083 Param = 0; 00084 Period = 0; 00085 Duration = 0; 00086 ElapsedTime = 0; 00087 ScheduledIteration = 0; 00088 ProgressIterationCount = 0; 00089 MarkedForRemoval = 0; 00090 Window = 0; 00091 next = 0; 00092 prev = 0; 00093 glibid = 0; 00094 uid = 0; 00095 } 00096 00097 TimerHandle::TimerHandle() 00098 { 00099 m_d = 0; 00100 } 00101 00102 TimerHandle::TimerHandle (TimerObject *timer_object) 00103 { 00104 m_d = timer_object; 00105 } 00106 00107 TimerHandle::~TimerHandle() 00108 { 00109 m_d = 0; 00110 } 00111 00112 TimerHandle::TimerHandle (const TimerHandle &timer_handle) 00113 { 00114 m_d = timer_handle.m_d; 00115 } 00116 00117 TimerHandle &TimerHandle::operator = (const TimerHandle &timer_handle) 00118 { 00119 m_d = timer_handle.m_d; 00120 return *this; 00121 } 00122 00123 bool TimerHandle::IsValid() const 00124 { 00125 return m_d != 0; 00126 } 00127 00128 float TimerHandle::GetProgress() const 00129 { 00130 if (m_d) 00131 return m_d->Param; 00132 return 0.0f; 00133 } 00134 00135 float TimerHandle::GetProgressDelta() const 00136 { 00137 if (m_d) 00138 return m_d->ProgressDelta; 00139 return 0; 00140 } 00141 00142 int TimerHandle::GetScheduledIterationCount() const 00143 { 00144 if (m_d) 00145 return m_d->ScheduledIteration; 00146 return 0; 00147 } 00148 00149 int TimerHandle::GetProgressIterationCount() const 00150 { 00151 if (m_d) 00152 return m_d->ProgressIterationCount; 00153 return 0; 00154 } 00155 00156 int TimerHandle::GetElapsedTimed() const 00157 { 00158 if (m_d) 00159 return m_d->ElapsedTime; 00160 return 0; 00161 } 00162 00164 TimerHandler::TimerHandler() 00165 { 00166 m_timer_object_queue = 0; 00167 m_IsProceesingTimers = false; 00168 } 00169 00170 TimerHandler::~TimerHandler() 00171 { 00172 00173 } 00174 00175 void TimerHandler::StartEarlyTimerObjects() 00176 { 00177 std::list<TimerObject*>::iterator it; 00178 for (it = _early_timer_objects.begin(); it != _early_timer_objects.end(); it++) 00179 { 00180 TimerObject *timer_object = *it; 00181 TimeRightNow(&timer_object->when); 00182 Addmillisecs(&timer_object->when, timer_object->Period); 00183 00184 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) 00185 timer_object->glibid = GetWindowThread ()->AddGLibTimeout (timer_object->Period); 00186 #endif 00187 } 00188 00189 _early_timer_objects.clear(); 00190 } 00191 00192 TimerHandle TimerHandler::AddTimerHandler (unsigned int Period, TimerFunctor *Callback, void *Data, WindowThread* window_thread) 00193 { 00194 TimerObject *timer_object = new TimerObject(); 00195 00196 TimeRightNow(&timer_object->when); 00197 Addmillisecs(&timer_object->when, Period); 00198 00199 timer_object->CallbackData = Data; 00200 timer_object->TimerCallback = Callback; 00201 timer_object->Period = Period; 00202 timer_object->Type = TIMERTYPE_PERIODIC; 00203 if (window_thread) 00204 timer_object->Window = window_thread->GetWindowCompositor ().GetProcessingTopView(); 00205 else 00206 timer_object->Window = GetWindowCompositor ().GetProcessingTopView(); 00207 00208 AddHandle (timer_object); 00209 00210 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) 00211 { 00212 if (window_thread) 00213 timer_object->glibid = window_thread->AddGLibTimeout (Period); 00214 else 00215 timer_object->glibid = GetWindowThread ()->AddGLibTimeout (Period); 00216 00217 if (timer_object->glibid == 0) 00218 { 00219 _early_timer_objects.push_back(timer_object); 00220 // Probably trying to set a timeout before Glib main context and loop have been created. 00221 // Sometimes later, this timer will be examined when ExecTimerHandler is called. 00222 // This happens when trying to set a callback before the mainloop has been initialized. 00223 } 00224 00225 //nuxDebugMsg(TEXT("[TimerHandler::AddTimerHandler] Adding Timeout ID: %d"), timer_object->glibid); 00226 } 00227 #endif 00228 00229 TimerHandle handle (timer_object); 00230 return handle; 00231 } 00232 00233 TimerHandle TimerHandler::AddPeriodicTimerHandler (unsigned int Period, int Duration, TimerFunctor *Callback, void *Data) 00234 { 00235 TimerObject *timer_object = new TimerObject(); 00236 TimeRightNow (&timer_object->when); 00237 Addmillisecs (&timer_object->when, Period); 00238 timer_object->CallbackData = Data; 00239 timer_object->TimerCallback = Callback; 00240 00241 timer_object->Period = Period; 00242 timer_object->Duration = (Duration < 0) ? -1 : Duration; 00243 timer_object->Type = TIMERTYPE_DURATION; 00244 AddHandle (timer_object); 00245 00246 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) 00247 { 00248 timer_object->glibid = GetWindowThread ()->AddGLibTimeout (Period); 00249 00250 if (timer_object->glibid == 0) 00251 { 00252 _early_timer_objects.push_back(timer_object); 00253 // Probably trying to set a timeout before Glib main context and loop have been created. 00254 // Sometimes later, this timer will be examined when ExecTimerHandler is called. 00255 // This happens when trying to set a callback before the mainloop has been initialized. 00256 } 00257 00258 //nuxDebugMsg(TEXT("[TimerHandler::AddTimerHandler] Adding Timeout ID: %d"), timer_object->glibid); 00259 } 00260 #endif 00261 00262 TimerHandle handle (timer_object); 00263 return handle; 00264 } 00265 00266 TimerHandle TimerHandler::AddCountIterationTimerHandler (unsigned int Period, int NumberOfIterations, TimerFunctor *Callback, void *Data) 00267 { 00268 TimerObject *timer_object = new TimerObject(); 00269 TimeRightNow (&timer_object->when); 00270 Addmillisecs (&timer_object->when, Period); 00271 timer_object->CallbackData = Data; 00272 timer_object->TimerCallback = Callback; 00273 00274 timer_object->Period = Period; 00275 timer_object->ScheduledIteration = (NumberOfIterations < 0) ? -1 : NumberOfIterations; 00276 timer_object->Type = TIMERTYPE_ITERATION; 00277 AddHandle (timer_object); 00278 00279 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) 00280 { 00281 timer_object->glibid = GetWindowThread ()->AddGLibTimeout (Period); 00282 00283 if (timer_object->glibid == 0) 00284 { 00285 _early_timer_objects.push_back(timer_object); 00286 // Probably trying to set a timeout before Glib main context and loop have been created. 00287 // Sometimes later, this timer will be examined when ExecTimerHandler is called. 00288 // This happens when trying to set a callback before the mainloop has been initialized. 00289 } 00290 00291 //nuxDebugMsg(TEXT("[TimerHandler::AddTimerHandler] Adding Timeout ID: %d"), timer_object->glibid); 00292 } 00293 #endif 00294 TimerHandle handle (timer_object); 00295 return handle; 00296 } 00297 00298 // Sort timers and add them to the queue 00299 TimerObject *TimerHandler::AddHandle (TimerObject *timer_object) 00300 { 00301 // If the queue is empty or the new timer will expire sooner than the first timer in the queue 00302 // then add the new timer at the start of the queue. 00303 if ( (m_timer_object_queue == NULL) || TimeIsGreater (m_timer_object_queue->when, timer_object->when) ) 00304 { 00305 // Add the timer timer_object at the head of the queue 00306 timer_object->next = m_timer_object_queue; 00307 00308 if (m_timer_object_queue) 00309 m_timer_object_queue->prev = timer_object; 00310 00311 timer_object->prev = 0; 00312 m_timer_object_queue = timer_object; 00313 return timer_object; 00314 } 00315 00316 // Give the Timer a unique ID; 00317 timer_object->uid = TimerUID.GetValue(); 00318 TimerUID.Increment(); 00319 00320 TimerObject *tmp = m_timer_object_queue; 00321 00322 while (tmp->next != NULL) 00323 { 00324 // Is the time to wait for tmp->next to expire smaller than for timer_object 00325 if (TimeIsGreater (timer_object->when, tmp->next->when) ) 00326 { 00327 // keep searching 00328 tmp = tmp->next; 00329 } 00330 else 00331 { 00332 timer_object->next = tmp->next; 00333 tmp->next->prev = timer_object; 00334 tmp->next = timer_object; 00335 timer_object->prev = tmp; 00336 return timer_object; 00337 } 00338 } 00339 00340 tmp->next = timer_object; 00341 timer_object->next = NULL; 00342 timer_object->prev = tmp; 00343 return timer_object; 00344 } 00345 00346 t_u32 TimerHandler::GetNumPendingHandler() 00347 { 00348 t_u32 count = 0; 00349 TimerObject *head = m_timer_object_queue; 00350 00351 while (head) 00352 { 00353 count++; 00354 head = head->next; 00355 } 00356 00357 return count; 00358 } 00359 00360 bool TimerHandler::RemoveTimerHandler (TimerHandle &timer_object) 00361 { 00362 NUX_RETURN_VALUE_IF_NULL (timer_object.m_d, false); 00363 NUX_RETURN_VALUE_IF_NULL (m_timer_object_queue, false); 00364 00365 TimerObject *tmp; 00366 00367 tmp = m_timer_object_queue; 00368 00369 while (tmp) 00370 { 00371 if ( (tmp == timer_object.m_d) && (tmp->uid == timer_object.m_d->uid) ) 00372 { 00373 if (!m_IsProceesingTimers) 00374 { 00375 if (tmp->next) 00376 tmp->next->prev = tmp->prev; 00377 00378 if (tmp->prev) 00379 tmp->prev->next = tmp->next; 00380 00381 if ( (timer_object.m_d == m_timer_object_queue) && (timer_object.m_d->uid == m_timer_object_queue->uid) ) 00382 m_timer_object_queue = timer_object.m_d->next; 00383 00384 NUX_SAFE_DELETE (timer_object.m_d); 00385 } 00386 else 00387 { 00388 timer_object.m_d->MarkedForRemoval = true; 00389 } 00390 00391 return true; 00392 } 00393 00394 tmp = tmp->next; 00395 } 00396 00397 return false; 00398 } 00399 00400 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) 00401 int TimerHandler::ExecTimerHandler (t_u32 timer_id) 00402 #else 00403 int TimerHandler::ExecTimerHandler() 00404 #endif 00405 { 00406 NUX_RETURN_VALUE_IF_NULL (m_timer_object_queue, 0); 00407 00408 bool repeat = false; 00409 TimerObject *timer_object = m_timer_object_queue; 00410 TimeStruct now; 00411 00412 int timer_executed = 0; 00413 00414 TimeRightNow (&now); 00415 00416 m_IsProceesingTimers = true; 00417 00418 while (timer_object != NULL) 00419 { 00420 #if (defined(NUX_OS_LINUX) || defined(NUX_USE_GLIB_LOOP_ON_WINDOWS)) && (!defined(NUX_DISABLE_GLIB_LOOP)) 00421 00422 if ( (/*TimeIsGreater (now, timer_object->when) ||*/ (timer_object->glibid == timer_id) ) && (timer_object->MarkedForRemoval == false) ) 00423 #else 00424 if (TimeIsGreater (now, timer_object->when) ) 00425 #endif 00426 { 00427 long elaps = now.sec - timer_object->when.sec; 00428 long uelaps = now.usec - timer_object->when.usec; 00429 00430 if (uelaps < 0) 00431 { 00432 uelaps += 1000000; 00433 //nuxAssert(elaps > 0); 00434 elaps -= 1; 00435 } 00436 00437 timer_object->ElapsedTime += timer_object->Period; //elaps * 1000 + uelaps / 1000; // milliseconds 00438 00439 if (timer_object->Type == TIMERTYPE_PERIODIC) 00440 { 00441 timer_object->ProgressDelta = float (timer_object->ElapsedTime) / float (timer_object->Period) - timer_object->Param; 00442 // Clamp progress delta so (timer_object->Param + timer_object->ProgressDelta) <= 1.0f 00443 if (timer_object->Param + timer_object->ProgressDelta > 1.0f) 00444 timer_object->ProgressDelta = 1.0f - timer_object->Param; 00445 00446 timer_object->Param = float (timer_object->ElapsedTime) / float (timer_object->Period); 00447 } 00448 else if (timer_object->Type == TIMERTYPE_DURATION) 00449 { 00450 timer_object->ProgressDelta = float (timer_object->ElapsedTime) / float (timer_object->Duration) - timer_object->Param; 00451 // Clamp progress delta so (timer_object->Param + timer_object->ProgressDelta) <= 1.0f 00452 if (timer_object->Param + timer_object->ProgressDelta > 1.0f) 00453 timer_object->ProgressDelta = 1.0f - timer_object->Param; 00454 00455 if(timer_object->ProgressDelta < 0.0f) 00456 timer_object->ProgressDelta = 0.0f; 00457 00458 timer_object->Param = float (timer_object->ElapsedTime) / float (timer_object->Duration); 00459 } 00460 else if (timer_object->Type == TIMERTYPE_ITERATION) 00461 { 00462 timer_object->ProgressIterationCount += 1; 00463 int duration = timer_object->Period * timer_object->ScheduledIteration; 00464 00465 timer_object->ProgressDelta = float (timer_object->ElapsedTime) / float (duration) - timer_object->Param; 00466 // Clamp progress delta so (timer_object->Param + timer_object->ProgressDelta) <= 1.0f 00467 if (timer_object->Param + timer_object->ProgressDelta > 1.0f) 00468 timer_object->ProgressDelta = 1.0f - timer_object->Param; 00469 00470 timer_object->Param = float (timer_object->ElapsedTime) / float (duration); 00471 } 00472 else 00473 { 00474 nuxAssertMsg (0, TEXT ("[TimerHandler::ExecTimerHandler] Unknown timer type.") ); 00475 } 00476 00477 if (timer_object->Param > 1.0f) 00478 timer_object->Param = 1.0f; 00479 00480 timer_object->MarkedForRemoval = false; 00481 00482 if (timer_object->TimerCallback != 0) 00483 { 00484 GetWindowCompositor().SetProcessingTopView(timer_object->Window); 00485 timer_object->TimerCallback->OnTimerExpired.emit(timer_object->CallbackData); 00486 GetWindowCompositor().SetProcessingTopView (NULL); 00487 // Reset glibid to 0. glibid is not null, if this element ever happened to be at the head of the queue 00488 // and we set a timer for it. 00489 //nuxDebugMsg(TEXT("[TimerHandler::ExecTimerHandler] Executed Timeout ID: %d"), timer_object->glibid); 00490 //timer_object->glibid = 0; 00491 } 00492 00493 TimerObject *expired_handler = 0; 00494 00495 if (timer_object->MarkedForRemoval) 00496 { 00497 // RemoveTimerHandler was called during the callback execution 00498 expired_handler = timer_object; 00499 } 00500 else if (timer_object->Type == TIMERTYPE_PERIODIC) 00501 { 00502 expired_handler = timer_object; 00503 } 00504 else if ( (timer_object->Type == TIMERTYPE_DURATION) && (timer_object->Param >= 1.0f) ) 00505 { 00506 expired_handler = timer_object; 00507 } 00508 else if ( (timer_object->Type == TIMERTYPE_ITERATION) && (timer_object->ProgressIterationCount >= timer_object->ScheduledIteration) ) 00509 { 00510 expired_handler = timer_object; 00511 } 00512 00513 if (expired_handler) 00514 { 00515 if (timer_object->next) 00516 timer_object->next->prev = timer_object->prev; 00517 00518 if (timer_object->prev) 00519 timer_object->prev->next = timer_object->next; 00520 00521 if ( (timer_object == m_timer_object_queue) && (timer_object->uid == m_timer_object_queue->uid) ) 00522 { 00523 // timer_object is the first element of the queue. 00524 m_timer_object_queue = timer_object->next; 00525 00526 if (m_timer_object_queue) 00527 { 00528 m_timer_object_queue->prev = 0; 00529 } 00530 } 00531 00532 timer_object = timer_object->next; 00533 00534 delete expired_handler; 00535 } 00536 else 00537 { 00538 repeat = true; 00539 //timer_object = timer_object->next; 00540 } 00541 00542 timer_executed++; 00543 break; 00544 } 00545 else 00546 { 00547 timer_object = timer_object->next; 00548 } 00549 } 00550 00551 // // Look at the head of the queue and set a glib timeout for the first element, if one wasn't set already. 00552 // if(m_timer_object_queue && (m_timer_object_queue->glibid == 0)) 00553 // { 00554 // // How long (in milliseconds) between now and the moment the timeout expires? 00555 // t_u32 time_difference = TimeDiff(now, m_timer_object_queue->when); 00556 // 00557 // m_timer_object_queue->glibid = GetWindowThread ()->AddGLibTimeout(time_difference); 00558 // //nuxDebugMsg(TEXT("[TimerHandler::ExecTimerHandler] Adding Timeout ID: %d"), m_timer_object_queue->glibid); 00559 // } 00560 00561 // Purge handles that have been marked for removal 00562 timer_object = m_timer_object_queue; 00563 00564 while (timer_object) 00565 { 00566 if (timer_object->MarkedForRemoval) 00567 { 00568 TimerObject *expired_handler = timer_object; 00569 00570 if (timer_object->next) 00571 timer_object->next->prev = timer_object->prev; 00572 00573 if (timer_object->prev) 00574 timer_object->prev->next = timer_object->next; 00575 else 00576 { 00577 // timer_object is the first element of the queue. 00578 m_timer_object_queue = timer_object->next; 00579 00580 if (m_timer_object_queue) 00581 { 00582 m_timer_object_queue->prev = 0; 00583 } 00584 } 00585 00586 timer_object = timer_object->next; 00587 delete expired_handler; 00588 } 00589 else 00590 { 00591 timer_object = timer_object->next; 00592 } 00593 } 00594 00595 m_IsProceesingTimers = false; 00596 //return timer_executed; 00597 return repeat; 00598 } 00599 00600 bool TimerHandler::FindTimerHandle (TimerHandle &timer_object) 00601 { 00602 TimerObject *tmp = m_timer_object_queue; 00603 00604 while (tmp) 00605 { 00606 if (tmp == timer_object.m_d && (tmp->uid == timer_object.m_d->uid) ) 00607 { 00608 return true; 00609 } 00610 00611 tmp = tmp->next; 00612 } 00613 00614 return false; 00615 } 00616 00617 //---------------------------------------------------------------------------- 00618 int TimerHandler::DelayUntilNextTimerExpires() 00619 { 00620 TimeStruct now; 00621 TimeStruct delay; 00622 00623 if (m_timer_object_queue == NULL) 00624 { 00625 // The return value of this function is only valid if there _are_ timers active. 00626 return 0; 00627 } 00628 else 00629 { 00630 TimeRightNow (&now); 00631 00632 if (TimeIsGreater (now, m_timer_object_queue->when) ) 00633 { 00634 return 0; 00635 } 00636 else 00637 { 00638 delay.sec = m_timer_object_queue->when.sec - now.sec; 00639 delay.usec = m_timer_object_queue->when.usec - now.usec; 00640 00641 // make sure that usec cannot be less than -1000000 before applying this code 00642 if (delay.usec < 0) 00643 { 00644 delay.usec += 1000000; 00645 delay.sec--; 00646 } 00647 00648 return (delay.sec * 1000000 + delay.usec) / 1000; // return delay in milliseconds 00649 } 00650 } 00651 } 00652 00653 /*t_u32 TimeDiff( TimeStruct t1, TimeStruct t2) 00654 { 00655 t_s32 sec; 00656 t_s32 usec; 00657 if(t1.sec >= t2.sec) 00658 { 00659 sec = t1.sec - t2.sec; 00660 usec = t1.usec - t2.usec; 00661 while((usec < 0) && (sec > 0)) 00662 { 00663 usec += 1000000; 00664 sec -= 1; 00665 } 00666 if(usec < 0) 00667 usec = -usec; 00668 } 00669 00670 if(t1.sec < t2.sec) 00671 { 00672 sec = t2.sec - t1.sec; 00673 usec = t2.usec - t1.usec; 00674 while((usec < 0) && (sec > 0)) 00675 { 00676 usec += 1000000; 00677 sec -= 1; 00678 } 00679 if(usec < 0) 00680 usec = -usec; 00681 } 00682 return sec*1000 + usec/1000; // time diff is millisecond 00683 }*/ 00684 00685 bool TimeIsGreater ( TimeStruct t1, TimeStruct t2) 00686 { 00687 if ( (t1.sec > t2.sec) || ( (t1.sec == t2.sec) && (t1.usec > t2.usec) ) ) 00688 return true; 00689 00690 if ( (t1.sec == t2.sec) && (t1.usec == t2.usec) ) 00691 return true; 00692 00693 return false; 00694 } 00695 00696 void TimeRightNow (TimeStruct *tv) 00697 { 00698 #if defined(NUX_OS_WINDOWS) 00699 struct _timeb timebuffer; 00700 // Time in seconds since midnight (00:00:00), January 1, 1970, coordinated universal time (UTC). 00701 _ftime (&timebuffer); 00702 tv->sec = timebuffer.time; 00703 tv->usec = timebuffer.millitm * 1000; 00704 #elif defined(NUX_OS_LINUX) 00705 timeval unix_timeval; 00706 gettimeofday (&unix_timeval, NULL); 00707 tv->sec = unix_timeval.tv_sec; 00708 tv->usec = unix_timeval.tv_usec; 00709 #else 00710 #error TimeRightNow is not implemented for this platform. 00711 #endif 00712 } 00713 00714 void Addmillisecs (TimeStruct *tv, unsigned int milliseconds) 00715 { 00716 tv->usec += milliseconds * 1000; 00717 tv->sec += tv->usec / 1000000; 00718 tv->usec = tv->usec % 1000000; 00719 } 00720 00721 00722 }