void startTicker(void) { #if defined(USE_TIMER_CREATE) { struct itimerspec it; it.it_value.tv_sec = TimeToSeconds(itimer_interval); it.it_value.tv_nsec = TimeToNS(itimer_interval) % 1000000000; it.it_interval = it.it_value; if (timer_settime(timer, 0, &it, NULL) != 0) { sysErrorBelch("timer_settime"); stg_exit(EXIT_FAILURE); } } #else { struct itimerval it; it.it_value.tv_sec = TimeToSeconds(itimer_interval); it.it_value.tv_usec = TimeToUS(itimer_interval) % 1000000; it.it_interval = it.it_value; if (setitimer(ITIMER_REAL, &it, NULL) != 0) { sysErrorBelch("setitimer"); stg_exit(EXIT_FAILURE); } } #endif }
static void *itimer_thread_func(void *_handle_tick) { TickProc handle_tick = _handle_tick; uint64_t nticks; int timerfd = -1; #if defined(USE_TIMERFD_FOR_ITIMER) && USE_TIMERFD_FOR_ITIMER struct itimerspec it; it.it_value.tv_sec = TimeToSeconds(itimer_interval); it.it_value.tv_nsec = TimeToNS(itimer_interval) % 1000000000; it.it_interval = it.it_value; timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timerfd == -1) { sysErrorBelch("timerfd_create"); stg_exit(EXIT_FAILURE); } if (!TFD_CLOEXEC) { fcntl(timerfd, F_SETFD, FD_CLOEXEC); } if (timerfd_settime(timerfd, 0, &it, NULL)) { sysErrorBelch("timerfd_settime"); stg_exit(EXIT_FAILURE); } #endif while (!exited) { if (USE_TIMERFD_FOR_ITIMER) { if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { if (errno != EINTR) { sysErrorBelch("Itimer: read(timerfd) failed"); } } } else { if (usleep(TimeToUS(itimer_interval)) != 0 && errno != EINTR) { sysErrorBelch("usleep(TimeToUS(itimer_interval) failed"); } } // first try a cheap test if (stopped) { ACQUIRE_LOCK(&mutex); // should we really stop? if (stopped) { waitCondition(&start_cond, &mutex); } RELEASE_LOCK(&mutex); } else { handle_tick(0); } } if (USE_TIMERFD_FOR_ITIMER) close(timerfd); closeMutex(&mutex); closeCondition(&start_cond); return NULL; }
void SpellParser::ParseInstantOverTime(std::shared_ptr<DamageHealSpellEffectBase> spDamageOrHealEffect) { CString cszToken = m_tokenizer.Next(); if (cszToken == _T("instant")) { spDamageOrHealEffect->Instant(true); } else if (cszToken == _T("over-time")) { spDamageOrHealEffect->Instant(false); spDamageOrHealEffect->Duration(TimeToSeconds(m_tokenizer.Next())); cszToken = m_tokenizer.Next(); if (cszToken != _T("tick-time")) throw Exception(_T("tick-time must follow over-time in spell description"), __FILE__, __LINE__); spDamageOrHealEffect->TickTime(TimeToSeconds(m_tokenizer.Next())); } else throw Exception(_T("only instant or over-time are allowed for damage spells"), __FILE__, __LINE__); }
static bool isInRange(ScheduleTimeDate *begin, ScheduleTimeDate *end) { RTC1_TTIME currTime; uint32_t beginSeconds, endSeconds, currSeconds; #if PL_HAS_DATE_SUPPORT /* check date */ if (!isInDateRange(begin, end)) { return FALSE; } #endif /* check time */ if (RTC1_GetRTCTime(&currTime)!=ERR_OK) { return FALSE; /* error case */ } beginSeconds = TimeToSeconds(begin->time.hour, begin->time.min, begin->time.sec); endSeconds = TimeToSeconds(end->time.hour, end->time.min, end->time.sec); currSeconds = TimeToSeconds(currTime.hour, currTime.min, currTime.sec); if (beginSeconds<=endSeconds) { /* normal case, not crossing midnight */ return currSeconds>=beginSeconds && currSeconds<=endSeconds; } else { /* crossing midnight */ return currSeconds<=endSeconds || currSeconds>=beginSeconds; } }
std::shared_ptr<Spell> SpellParser::Parse(LPCTSTR pszText) { m_tokenizer = StringTokenizer(pszText); unsigned int uiSpellId = ParseUint(m_tokenizer.Next()); unsigned int uiCooldown = 0; unsigned int uiCastTime = 0; bool bStackable = false; unsigned int uiRange = 0; bool bArea = false; std::vector<std::shared_ptr<SpellEffect>> vecEffects; CString cszToken; while (!m_tokenizer.IsEmpty()) { cszToken = m_tokenizer.Next(); if (cszToken == _T("cooldown")) { uiCooldown = TimeToSeconds(m_tokenizer.Next()); } else if (cszToken == _T("cast-time")) { uiCastTime = TimeToSeconds(m_tokenizer.Next()); } else if (cszToken == _T("stackable")) { bStackable = true; } else if (cszToken == _T("range")) { uiRange = ParseUint(m_tokenizer.Next()); } else if (cszToken == _T("area")) { bArea = true; } else if (cszToken == _T("effect")) { ATLVERIFY(_T("[") == m_tokenizer.Next()); vecEffects.push_back(ParseEffect()); } } if (vecEffects.empty()) throw Exception(_T("error parsing spell: no effect specified"), __FILE__, __LINE__); std::shared_ptr<Spell> spSpell(new Spell(uiSpellId, vecEffects[0])); spSpell->Cooldown(uiCooldown); spSpell->CastTime(uiCastTime); spSpell->Stackable(bStackable); spSpell->Range(uiRange); spSpell->AreaSpell(bArea); if (vecEffects.size() > 2) throw Exception(_T("error parsing spell: too many effects specified"), __FILE__, __LINE__); if (vecEffects.size() == 2) spSpell->Effect2(vecEffects[1]); return spSpell; }