struct timer *timer_add_ms(plugin_t *plugin, const char *name, unsigned int period, int persist, int (*function)(int, void *), void *data) { struct timer *t; struct timeval tv; /* wylosuj now± nazwê, je¶li nie mamy */ if (!name) debug_error("timer_add() without name\n"); t = xmalloc(sizeof(struct timer)); gettimeofday(&tv, NULL); tv.tv_sec += (period / 1000); tv.tv_usec += ((period % 1000) * 1000); if (tv.tv_usec >= 1000000) { tv.tv_usec -= 1000000; tv.tv_sec++; } memcpy(&(t->ends), &tv, sizeof(tv)); t->name = xstrdup(name); t->period = period; t->persist = persist; t->function = function; t->data = data; t->plugin = plugin; timers_add(t); return t; }
int _mtx_sleep(mtx_t * mtx, long timeout, char * whr) #endif { int retval; if (MTX_OPT(mtx, MTX_OPT_DINT)) goto fail; if (timeout > 0) { KASSERT(current_thread->wait_tim < 0, "Can't have multiple wait timers per thread"); current_thread->wait_tim = timers_add(mtx_wakeup, mtx, TIMERS_FLAG_ONESHOT, timeout); if (current_thread->wait_tim < 0) return -EWOULDBLOCK; retval = mtx_lock(mtx); timers_release(current_thread->wait_tim); current_thread->wait_tim = -1; } else if (mtx->mtx_type == MTX_TYPE_SPIN) { retval = mtx_lock(mtx); } else { fail: MTX_TYPE_NOTSUP(); return -ENOTSUP; } return retval; }
JSBool js_event_start_wait_func(JSContext *cx,JSObject *j_obj,uintN argc,jsval *argv,jsval *rval) { if (!timers_add(&js.attach,JSVAL_TO_INT(argv[0]),JSVAL_TO_INT(argv[1]),NULL,timer_mode_single)) { *rval=JSVAL_FALSE; } else { *rval=JSVAL_TRUE; } return(JS_TRUE); }
JSBool js_event_chain_func(JSContext *cx,JSObject *j_obj,uintN argc,jsval *argv,jsval *rval) { char chain_func_name[64]; script_value_to_string(argv[1],chain_func_name,64); if (!timers_add(&js.attach,JSVAL_TO_INT(argv[0]),0,chain_func_name,timer_mode_chain)) { *rval=JSVAL_FALSE; } else { *rval=JSVAL_TRUE; } return(JS_TRUE); }
static void timers_migrate_2(void) { if (! persist_exists(PERSIST_TIMER_START)) { return; } int block_number = 0; TimerBlockTiny* block = malloc(sizeof(TimerBlockTiny)); persist_read_data(PERSIST_TIMER_START, block, sizeof(TimerBlockTiny)); uint8_t timer_count = block->total_timers; for (int t = 0; t < timer_count; t += 1) { if (t > 0 && t % TIMER_BLOCK_SIZE == 0) { block_number += 1; if (NULL != block) { free(block); block = NULL; } block = malloc(sizeof(TimerBlockTiny)); persist_read_data(PERSIST_TIMER_START + block_number, block, sizeof(TimerBlockTiny)); } TimerTiny* timer_tiny = &block->timers[t % TIMER_BLOCK_SIZE]; int seconds_elapsed = time(NULL) - block->save_time; Timer* timer = malloc(sizeof(Timer)); timer->id = timer_tiny->id; timer->current_time = timer_tiny->current_time; timer->length = timer_tiny->length; timer->repeat = timer_tiny->repeat; timer->repeat_count = timer_tiny->repeat_count; timer->status = timer_tiny->status; timer->vibration = timer_tiny->vibration; timer->type = timer_tiny->type; timer->wakeup_id = timer_tiny->wakeup_id; timer->timer = NULL; strcpy(timer->label, timer_tiny->label); timer_restore(timer, seconds_elapsed); timers_add(timer); } if (NULL != block) { free(block); } }
JSBool js_event_start_wait_random_func(JSContext *cx,JSObject *j_obj,uintN argc,jsval *argv,jsval *rval) { int min,max,tick; min=JSVAL_TO_INT(argv[0]); max=JSVAL_TO_INT(argv[1]); tick=random_int(abs(max-min))+min; if (!timers_add(&js.attach,tick,JSVAL_TO_INT(argv[2]),NULL,timer_mode_single)) { *rval=JSVAL_FALSE; } else { *rval=JSVAL_TRUE; } return(JS_TRUE); }
JSValueRef js_event_start_timer_func(JSContextRef cx,JSObjectRef func,JSObjectRef j_obj,size_t argc,const JSValueRef argv[],JSValueRef *exception) { int script_idx; char err_str[256]; if (!script_check_param_count(cx,func,argc,2,exception)) return(script_null_to_value(cx)); if (!script_check_fail_in_construct(cx,func,j_obj,exception)) return(script_null_to_value(cx)); script_idx=(int)JSObjectGetPrivate(j_obj); if (!timers_add(script_idx,script_value_to_int(cx,argv[0]),script_value_to_int(cx,argv[1]),NULL,timer_mode_repeat,err_str)) { *exception=script_create_exception(cx,err_str); return(script_bool_to_value(cx,FALSE)); } return(script_bool_to_value(cx,TRUE)); }
void timers_restore(void) { if (! persist_exists(PERSIST_TIMERS_VERSION)) { timers_migrate_1(); return; } if (TIMERS_VERSION_TINY == persist_read_int(PERSIST_TIMERS_VERSION)) { timers_migrate_2(); return; } timers_clear(); time_t now = time(NULL); uint16_t seconds_elapsed = 0; TimerBlock* block = NULL; if (persist_exists(PERSIST_TIMER_START)) { block = malloc(sizeof(TimerBlock)); persist_read_data(PERSIST_TIMER_START, block, sizeof(TimerBlock)); uint8_t num_timers = block->total_timers; uint8_t block_offset = 0; seconds_elapsed = now - block->save_time; for (uint8_t t = 0; t < num_timers; t += 1) { if (! block) { block = malloc(sizeof(TimerBlock)); persist_read_data(PERSIST_TIMER_START + block_offset, block, sizeof(TimerBlock)); } Timer* timer = timer_clone(&block->timers[t % TIMER_BLOCK_SIZE]); timers_add(timer); timer_restore(timer, seconds_elapsed); if (t % TIMER_BLOCK_SIZE == (TIMER_BLOCK_SIZE - 1)) { free(block); block = NULL; block_offset += 1; } } if (block) { free(block); block = NULL; } } }
JSValueRef js_event_start_wait_random_func(JSContextRef cx,JSObjectRef func,JSObjectRef j_obj,size_t argc,const JSValueRef argv[],JSValueRef *exception) { int min,max,tick,script_idx; char err_str[256]; if (!script_check_param_count(cx,func,argc,3,exception)) return(script_null_to_value(cx)); if (!script_check_fail_in_construct(cx,func,j_obj,exception)) return(script_null_to_value(cx)); script_idx=(int)JSObjectGetPrivate(j_obj); min=script_value_to_int(cx,argv[0]); max=script_value_to_int(cx,argv[1]); tick=random_int(abs(max-min))+min; if (!timers_add(script_idx,tick,script_value_to_int(cx,argv[2]),NULL,timer_mode_single,err_str)) { *exception=script_create_exception(cx,err_str); return(script_bool_to_value(cx,FALSE)); } return(script_bool_to_value(cx,TRUE)); }
void storage_load(){ APP_LOG(APP_LOG_LEVEL_INFO,"storage_load()"); if(!persist_exists(STORAGE_KEY_VERSION)){ APP_LOG(APP_LOG_LEVEL_WARNING,"no version"); return; } if(persist_read_int(STORAGE_KEY_VERSION)!=STORAGE_VERSION){ APP_LOG(APP_LOG_LEVEL_WARNING,"wrong version"); return; } if(!persist_exists(STORAGE_KEY_COUNT)){ APP_LOG(APP_LOG_LEVEL_ERROR,"no count"); return; } uint8_t storage_count=(uint8_t)persist_read_int(STORAGE_KEY_COUNT); APP_LOG(APP_LOG_LEVEL_INFO,"storage count: %d",storage_count); Timer* timer; int result; for(uint8_t i=0;i<storage_count;i++){ if(!persist_exists(STORAGE_KEY_DATA+i)){ APP_LOG(APP_LOG_LEVEL_ERROR,"missing timer %d in storage %d",i,STORAGE_KEY_DATA+i); continue; } timer=timer_create(); result=persist_read_data(STORAGE_KEY_DATA+i,timer,sizeof(Timer)); if(result<0){ APP_LOG(APP_LOG_LEVEL_ERROR,"read error timer %d in storage %d",i,STORAGE_KEY_DATA+i); timer_destroy(timer); continue; } timers_add(timer); APP_LOG(APP_LOG_LEVEL_INFO,"loaded timer %d",i); } APP_LOG(APP_LOG_LEVEL_INFO,"loaded"); }
static void timers_migrate_1(void) { if (! persist_exists(PERSIST_TIMER_START)) { return; } int block = 0; OldTimerBlock* timerBlock = malloc(sizeof(OldTimerBlock)); persist_read_data(PERSIST_TIMER_START, timerBlock, sizeof(OldTimerBlock)); uint8_t timer_count = timerBlock->count; for (int t = 0; t < timer_count; t += 1) { if (t > 0 && t % TIMER_BLOCK_SIZE == 0) { block += 1; if (NULL != timerBlock) { free(timerBlock); timerBlock = NULL; } timerBlock = malloc(sizeof(OldTimerBlock)); persist_read_data(PERSIST_TIMER_START + block, timerBlock, sizeof(OldTimerBlock)); } OldTimer* old_timer = &timerBlock->timers[t % TIMER_BLOCK_SIZE]; int seconds_elapsed = time(NULL) - timerBlock->time; Timer* timer = malloc(sizeof(Timer)); timer->id = old_timer->id; timer->current_time = old_timer->time_left; timer->length = old_timer->length; timer->repeat = old_timer->repeat ? TIMER_REPEAT_INFINITE : 0; switch (old_timer->status) { case OLD_TIMER_STATUS_STOPPED: timer->status = TIMER_STATUS_STOPPED; break; case OLD_TIMER_STATUS_RUNNING: timer->status = TIMER_STATUS_RUNNING; break; case OLD_TIMER_STATUS_PAUSED: timer->status = TIMER_STATUS_PAUSED; break; case OLD_TIMER_STATUS_FINISHED: timer->status = TIMER_STATUS_DONE; break; } switch (old_timer->vibrate) { case OLD_TIMER_VIBRATION_OFF: timer->vibration = TIMER_VIBE_NONE; break; case OLD_TIMER_VIBRATION_SHORT: timer->vibration = TIMER_VIBE_SHORT; break; case OLD_TIMER_VIBRATION_LONG: timer->vibration = TIMER_VIBE_LONG; break; case OLD_TIMER_VIBRATION_DOUBLE: timer->vibration = TIMER_VIBE_DOUBLE; break; case OLD_TIMER_VIBRATION_TRIPLE: timer->vibration = TIMER_VIBE_TRIPLE; break; case OLD_TIMER_VIBRATION_CONTINUOUS: timer->vibration = TIMER_VIBE_SOLID; break; } switch (old_timer->direction) { case OLD_TIMER_DIRECTION_DOWN: timer->type = TIMER_TYPE_TIMER; break; case OLD_TIMER_DIRECTION_UP: timer->type = TIMER_TYPE_STOPWATCH; break; } timer->wakeup_id = -1; timer->timer = NULL; timer_restore(timer, seconds_elapsed); timers_add(timer); } if (NULL != timerBlock) { free(timerBlock); } }
status_t timers_restore(void) { timers_clear(); if (! persist_exists(STORAGE_TIMER_START)) { return 0; } int block = 0; TimerBlock* timerBlock = malloc(sizeof(TimerBlock)); persist_read_data(STORAGE_TIMER_START, timerBlock, sizeof(TimerBlock)); uint8_t timer_count = timerBlock->count; int seconds_elapsed = 0; if (settings()->resume_timers) { int save_time = timerBlock->time; seconds_elapsed = time(NULL) - save_time; } for (int t = 0; t < timer_count; t += 1) { if (t > 0 && t % TIMER_BLOCK_SIZE == 0) { block += 1; free_safe(timerBlock); timerBlock = malloc(sizeof(TimerBlock)); persist_read_data(STORAGE_TIMER_START + block, timerBlock, sizeof(TimerBlock)); } Timer* timer = timer_clone(&timerBlock->timers[t % TIMER_BLOCK_SIZE]); timers_add(timer); timer->app_timer = NULL; if (! settings()->resume_timers) { timer_reset(timer); continue; } if (TIMER_STATUS_RUNNING != timer->status) { continue; } if (TIMER_DIRECTION_UP == timer->direction) { timer->time_left += seconds_elapsed; } else { if (true == timer->repeat) { timer->time_left -= (seconds_elapsed % timer->length); if (timer->time_left <= 0) { timer->time_left += timer->length; } } else { timer->time_left -= seconds_elapsed; if (0 >= timer->time_left) { timer->time_left = 0; timer->status = TIMER_STATUS_FINISHED; continue; } } } timer_resume(timer); } free_safe(timerBlock); return 0; }
Timer* timers_add_timer() { if(timers_count()>=TIMERS_MAX_COUNT){ return NULL; } return timers_select(timers_add(timer_create_timer())); }