void Timer::pollTimers() { // Generate messages for timers if (!timers.empty()) { int t = ji_clock; int count; for (Timers::iterator it=timers.begin(), end=timers.end(); it != end; ++it) { Timer* timer = *it; if (timer && timer->m_lastTime >= 0) { count = 0; while (t - timer->m_lastTime > timer->m_interval) { timer->m_lastTime += timer->m_interval; ++count; /* we spend too much time here */ if (ji_clock - t > timer->m_interval) { timer->m_lastTime = ji_clock; break; } } if (count > 0) { ASSERT(timer->m_owner != NULL); Message* msg = new TimerMessage(count, timer); msg->addRecipient(timer->m_owner); Manager::getDefault()->enqueueMessage(msg); } } } } }
Timer::~Timer() { Timers::iterator it = std::find(timers.begin(), timers.end(), this); ASSERT(it != timers.end()); timers.erase(it); // Remove messages of this timer in the queue Manager::getDefault()->removeMessagesForTimer(this); }
/** * Clears and releases all existing timers. */ void clearTimers() { // this has to be called at a different time // than fini, that's why it's a separate method for( Timers::iterator iTimer = gTimers.begin(); iTimer != gTimers.end(); iTimer++ ) { Py_DECREF( iTimer->function ); Py_DECREF( iTimer->arguments ); } gTimers.clear(); }
Timer::~Timer() { assert_ui_thread(); auto it = std::find(timers.begin(), timers.end(), this); ASSERT(it != timers.end()); if (it != timers.end()) timers.erase(it); // Stop the timer and remove it from the message queue. stop(); }
void main() { /*CLoggingStream errors(L"errorLogs"); g_Scripts.reset(new Scripting::Scripts(errors, "D:\\Development\\C++\\Phasor - Copy\\Release")); g_Scripts->OpenScript("lua_test"); g_Scripts->OpenScript("lua_test1"); //Scripting::OpenScript("lua_test1"); Scripting::PhasorCaller caller; caller.AddArg("hello"); Scripting::Result result = caller.Call("funca"); caller.AddArg("hello_again"); caller.Call("funca"); std::cout << result.size() << std::endl; g_Scripts->CloseScript("lua_test"); g_Scripts->CloseScript("lua_test1");*/ /*PhasorThread thread; thread.run(); std::unique_ptr<PhasorThreadEvent> e = TestEvent::Create(0); thread.InvokeInAux(std::move(e)); for (int i =0; i < 100000; i++) { thread.ProcessEvents(); Sleep(5); //if (count == 100) break; } thread.close(); while (!thread.has_closed()) { Sleep(10); }*/ Timers timers; timer_t timer = TestTimer::Create(1000); timers.AddTimer(std::move(timer)); timer_t timer1 = TestTimer1::Create(1000, timer->GetID()); timer_t timer2 = TestTimer1::Create(1000, timer1->GetID()); timers.AddTimer(std::move(timer2)); timers.AddTimer(std::move(timer1)); while (1) { timers.Process(); Sleep(20); } }
void Timer::pollTimers() { assert_ui_thread(); // Generate messages for timers if (running_timers != 0) { ASSERT(!timers.empty()); base::tick_t t = base::current_tick(); for (auto timer : timers) { if (timer && timer->isRunning()) { int64_t count = ((t - timer->m_lastTick) / timer->m_interval); if (count > 0) { timer->m_lastTick += count * timer->m_interval; ASSERT(timer->m_owner != nullptr); Message* msg = new TimerMessage(count, timer); msg->setRecipient(timer->m_owner); Manager::getDefault()->enqueueMessage(msg); } } } } }
Timer::Timer(int interval, Widget* owner) : m_owner(owner ? owner: Manager::getDefault()) , m_interval(interval) , m_lastTime(-1) { ASSERT(m_owner != NULL); timers.push_back(this); }
Timer::Timer(int interval, Widget* owner) : m_owner(owner ? owner: Manager::getDefault()) , m_interval(interval) , m_running(false) , m_lastTick(0) { ASSERT(m_owner != nullptr); assert_ui_thread(); timers.push_back(this); }
void ApplicationEntryPoint() { BOOL result; //RAM RamTest ( (UINT32*)RAMTestBase, (UINT32)RAMTestSize, (ENDIAN_TYPE)ENDIANESS, BUS_WIDTH ); TimedEvents eventsTest; //UART usartTest ( COMTestPort, 9600, USART_PARITY_NONE, 8, USART_STOP_BITS_ONE, USART_FLOW_NONE ); GPIO gpioTest ( GPIOTestPin ); //SPI spiTest ( SPIChipSelect, SPIModule, g_EEPROM_STM95x ); Timers timersTest ( DisplayInterval, TimerDuration ); do { //result = RamTest.Execute ( STREAM__OUT ); result = eventsTest.Execute( STREAM__OUT ); //result = usartTest.Execute ( STREAM__OUT ); result = gpioTest.Execute ( STREAM__OUT ); //result = spiTest.Execute ( STREAM__OUT ); result = timersTest.Execute( STREAM__OUT ); } while(FALSE); // run only once! while(TRUE); }
/** * This function adds a script 'timer' to be called next tick * * It is used by routines which want to make script calls but can't * because they're in the middle of something scripts might mess up * (like iterating over the scene to tick or draw it) * * The optional age parameter specifies the age of the call, * i.e. how far in the past it wanted to be made. * Older calls are called back first. * * @note: This function steals the references to both fn and args */ void callNextFrame( PyObject * fn, PyObject * args, const char * reason, double age ) { TimerHandle handle; if(!gFreeTimerHandles.empty()) { handle = gFreeTimerHandles.top(); handle.issueCount++; gFreeTimerHandles.pop(); } else { if (gTimers.size() >= USHRT_MAX) { PyErr_SetString( PyExc_TypeError, "callNextFrame: Callback handle overflow." ); return; } handle.id = gTimers.size() + 1; handle.issueCount = 1; } TimerRecord newTR = { getTotalGameTime() - age, fn, args, reason, { handle.i32 } }; gTimers.push_back( newTR ); }
void OnServerClose() { *g_PhasorLog << "Closing the server..." << endl; halo::game::cleanupPlayers(true); g_Scripts.reset(); g_Timers.RemoveAllTimers(); g_Thread.close(); for (int i = 0; i < 100; i++) { if (g_Thread.has_closed()) break; Sleep(10); } scriptOutput.reset(); g_PhasorLog.reset(); g_ScriptsLog.reset(); g_GameLog.reset(); g_RconLog.reset(); g_PrintStream.reset(); ExitProcess(0); }
namespace ui { typedef std::list<Timer*> Timers; static Timers timers; // Registered timers Timer::Timer(int interval, Widget* owner) : m_owner(owner ? owner: Manager::getDefault()) , m_interval(interval) , m_lastTime(-1) { ASSERT(m_owner != NULL); timers.push_back(this); } Timer::~Timer() { Timers::iterator it = std::find(timers.begin(), timers.end(), this); ASSERT(it != timers.end()); timers.erase(it); // Remove messages of this timer in the queue Manager::getDefault()->removeMessagesForTimer(this); } bool Timer::isRunning() const { return (m_lastTime >= 0); } void Timer::start() { m_lastTime = ji_clock; } void Timer::stop() { m_lastTime = -1; } void Timer::tick() { onTick(); } void Timer::setInterval(int interval) { m_interval = interval; } void Timer::onTick() { // Fire Tick signal. Tick(); } void Timer::pollTimers() { // Generate messages for timers if (!timers.empty()) { int t = ji_clock; int count; for (Timers::iterator it=timers.begin(), end=timers.end(); it != end; ++it) { Timer* timer = *it; if (timer && timer->m_lastTime >= 0) { count = 0; while (t - timer->m_lastTime > timer->m_interval) { timer->m_lastTime += timer->m_interval; ++count; /* we spend too much time here */ if (ji_clock - t > timer->m_interval) { timer->m_lastTime = ji_clock; break; } } if (count > 0) { ASSERT(timer->m_owner != NULL); Message* msg = new TimerMessage(count, timer); msg->addRecipient(timer->m_owner); Manager::getDefault()->enqueueMessage(msg); } } } } } void Timer::checkNoTimers() { ASSERT(timers.empty()); } } // namespace ui
namespace Script { /** * Store a callback function that can tell caller the total time that * game has been running. The application should call setTotalGameTimeFn * to set this up. */ TotalGameTimeFn s_totalGameTimeFn = NULL; /** * Set the callback function. */ void setTotalGameTimeFn( TotalGameTimeFn fn ) { s_totalGameTimeFn = fn; } /** * Get total amount of time that game has been running. */ double getTotalGameTime() { return s_totalGameTimeFn(); } /** * This union is used by the BigWorld client callback * system. It provides a handle to a callback request. */ union TimerHandle { uint32 i32; struct { uint16 id; uint16 issueCount; }; }; typedef std::stack<TimerHandle> TimerHandleStack; TimerHandleStack gFreeTimerHandles; /** * This structure is used by the BigWorld client callback * system. It records a single callback request. */ struct TimerRecord { /** * This method returns whether or not the input record occurred later than * this one. * * @return True if input record is earlier (higher priority), * false otherwise. */ bool operator <( const TimerRecord & b ) const { return b.time < this->time; } double time; ///< The time of the record. PyObject * function; ///< The function associated with the record. PyObject * arguments; ///< The arguments associated with the record. const char * source; ///< The source of this timer record TimerHandle handle; ///< The handle issued for this callback. }; typedef std::list<TimerRecord> Timers; Timers gTimers; /** * Clears and releases all existing timers. */ void clearTimers() { // this has to be called at a different time // than fini, that's why it's a separate method for( Timers::iterator iTimer = gTimers.begin(); iTimer != gTimers.end(); iTimer++ ) { Py_DECREF( iTimer->function ); Py_DECREF( iTimer->arguments ); } gTimers.clear(); } /** * This function calls any script timers which have expired by now */ void tick( double timeNow ) { const int MAX_TIMER_CALLS_PER_FRAME = 1000; Timers timersToCall; Timers::iterator iter = gTimers.begin(); while ( iter != gTimers.end() ) { if ( iter->time <= timeNow ) { timersToCall.push_back( *iter ); iter = gTimers.erase( iter ); } else { ++iter; } } // Using a reverse iterator, since the TimerRecord comparison operator causes // the sorted list to be in reverse order (earlier timers are later in the list). stable_sort( timersToCall.begin(), timersToCall.end() ); int numExpired = 0; Timers::reverse_iterator revIter = timersToCall.rbegin(); for ( ; revIter != timersToCall.rend() && numExpired < MAX_TIMER_CALLS_PER_FRAME; ++revIter ) { TimerRecord& timer = *revIter; gFreeTimerHandles.push( timer.handle ); Script::call( timer.function, timer.arguments, timer.source ); // Script::call decrefs timer.function and timer.arguments for us numExpired++; } if (numExpired >= MAX_TIMER_CALLS_PER_FRAME) { // If there are too many to run this frame, put the remainder back into the main list. for ( ; revIter != timersToCall.rend(); ++revIter ) { TimerRecord& timer = *revIter; gTimers.push_back( timer ); } //ERROR_MSG( "BigWorldClientScript::tick: Loop interrupted because" // " too many timers (> %d) wanted to expire this frame!", // numExpired ); } } /** * This function adds a script 'timer' to be called next tick * * It is used by routines which want to make script calls but can't * because they're in the middle of something scripts might mess up * (like iterating over the scene to tick or draw it) * * The optional age parameter specifies the age of the call, * i.e. how far in the past it wanted to be made. * Older calls are called back first. * * @note: This function steals the references to both fn and args */ void callNextFrame( PyObject * fn, PyObject * args, const char * reason, double age ) { TimerHandle handle; if(!gFreeTimerHandles.empty()) { handle = gFreeTimerHandles.top(); handle.issueCount++; gFreeTimerHandles.pop(); } else { if (gTimers.size() >= USHRT_MAX) { PyErr_SetString( PyExc_TypeError, "callNextFrame: Callback handle overflow." ); return; } handle.id = gTimers.size() + 1; handle.issueCount = 1; } TimerRecord newTR = { getTotalGameTime() - age, fn, args, reason, { handle.i32 } }; gTimers.push_back( newTR ); } }
/** * This function calls any script timers which have expired by now */ void tick( double timeNow ) { const int MAX_TIMER_CALLS_PER_FRAME = 1000; Timers timersToCall; Timers::iterator iter = gTimers.begin(); while ( iter != gTimers.end() ) { if ( iter->time <= timeNow ) { timersToCall.push_back( *iter ); iter = gTimers.erase( iter ); } else { ++iter; } } // Using a reverse iterator, since the TimerRecord comparison operator causes // the sorted list to be in reverse order (earlier timers are later in the list). stable_sort( timersToCall.begin(), timersToCall.end() ); int numExpired = 0; Timers::reverse_iterator revIter = timersToCall.rbegin(); for ( ; revIter != timersToCall.rend() && numExpired < MAX_TIMER_CALLS_PER_FRAME; ++revIter ) { TimerRecord& timer = *revIter; gFreeTimerHandles.push( timer.handle ); Script::call( timer.function, timer.arguments, timer.source ); // Script::call decrefs timer.function and timer.arguments for us numExpired++; } if (numExpired >= MAX_TIMER_CALLS_PER_FRAME) { // If there are too many to run this frame, put the remainder back into the main list. for ( ; revIter != timersToCall.rend(); ++revIter ) { TimerRecord& timer = *revIter; gTimers.push_back( timer ); } //ERROR_MSG( "BigWorldClientScript::tick: Loop interrupted because" // " too many timers (> %d) wanted to expire this frame!", // numExpired ); } }
CAFKDetection::CAFKDetection(s_player& player, Timers& timers) : player(player), timers(timers), move_count(0), afk_duration(0) { timer_ptr timer(new CAFKDetectionEvent(60000,*this)); timer_id = timers.AddTimer(std::move(timer)); }
bool Timer::haveTimers() { return !timers.empty(); }
void Timer::checkNoTimers() { ASSERT(timers.empty()); }
namespace ui { typedef std::vector<Timer*> Timers; static Timers timers; // Registered timers static int running_timers = 0; Timer::Timer(int interval, Widget* owner) : m_owner(owner ? owner: Manager::getDefault()) , m_interval(interval) , m_running(false) , m_lastTick(0) { ASSERT(m_owner != nullptr); assert_ui_thread(); timers.push_back(this); } Timer::~Timer() { assert_ui_thread(); auto it = std::find(timers.begin(), timers.end(), this); ASSERT(it != timers.end()); if (it != timers.end()) timers.erase(it); // Stop the timer and remove it from the message queue. stop(); } void Timer::start() { assert_ui_thread(); m_lastTick = base::current_tick(); if (!m_running) { m_running = true; ++running_timers; } } void Timer::stop() { assert_ui_thread(); if (m_running) { m_running = false; --running_timers; // Remove messages of this timer in the queue. The expected behavior // is that when we stop a timer, we'll not receive more messages // about it (even if there are enqueued messages waiting in the // message queue). Manager::getDefault()->removeMessagesForTimer(this); } } void Timer::tick() { assert_ui_thread(); onTick(); } void Timer::setInterval(int interval) { m_interval = interval; } void Timer::onTick() { // Fire Tick signal. Tick(); } void Timer::pollTimers() { assert_ui_thread(); // Generate messages for timers if (running_timers != 0) { ASSERT(!timers.empty()); base::tick_t t = base::current_tick(); for (auto timer : timers) { if (timer && timer->isRunning()) { int64_t count = ((t - timer->m_lastTick) / timer->m_interval); if (count > 0) { timer->m_lastTick += count * timer->m_interval; ASSERT(timer->m_owner != nullptr); Message* msg = new TimerMessage(count, timer); msg->setRecipient(timer->m_owner); Manager::getDefault()->enqueueMessage(msg); } } } } } bool Timer::haveTimers() { return !timers.empty(); } bool Timer::haveRunningTimers() { return (running_timers != 0); } } // namespace ui