int sampgdk_timer_set(long interval, bool repeat, sampgdk_timer_callback callback, void *param) { struct sampgdk_timer timer; int slot; int error; assert(callback != NULL); timer.is_set = true; timer.interval = interval; timer.repeat = repeat; timer.callback = callback; timer.param = param; timer.started = sampgdk_timer_clock(); timer.plugin = sampgdk_plugin_address_to_handle(callback); slot = find_slot(); if (slot >= 0) { sampgdk_array_set(&timers, slot, &timer); } else { error = sampgdk_array_append(&timers, &timer); if (error < 0) { return -error; } slot = timers.count - 1; } /* Timer IDs returned by the SA:MP's SetTimer() API begin * with 1, and so do they here. */ return slot + 1; }
int sampgdk_array_insert_ordered(struct sampgdk_array *a, void *elem, int (*comp)(const void *x, const void *y)) { int index; for (index = 0; index < a->count; index++) { if (comp(sampgdk_array_get(a, index), elem) >= 0) { return sampgdk_array_insert_single(a, index, elem); } } return sampgdk_array_append(a, elem); }
int sampgdk_callback_register(const char *name, sampgdk_callback_handler handler) { int error; struct sampgdk_callback info; struct sampgdk_callback *ptr; int index; assert(name != NULL); assert(handler != NULL); /* This is rather an exception than a rule. */ sampgdk_callback_init(); ptr = sampgdk_callback_find(name); if (ptr != NULL) { ptr->handler = handler; return 0; } info.name = malloc(strlen(name) + 1); if (info.name == NULL) { return -ENOMEM; } strcpy(info.name, name); info.handler = handler; /* Maintain element order (by name). */ for (index = 0; index < callbacks.count; index++) { ptr = (struct sampgdk_callback *)sampgdk_array_get(&callbacks, index); if (strcmp(ptr->name, name) >= 0) { error = sampgdk_array_insert_single(&callbacks, index, &info); break; } } /* Append to the end. */ if (index == callbacks.count) { error = sampgdk_array_append(&callbacks, &info); } if (error < 0) { free(info.name); return error; } return 0; }
int sampgdk_timer_set(int interval, bool repeat, sampgdk_timer_callback callback, void *param) { struct _sampgdk_timer_info timer; int slot; int error; int timerid; assert(callback != NULL); timer.is_set = true; timer.interval = interval; timer.repeat = repeat; timer.callback = (void *)callback; timer.param = param; timer.started = _sampgdk_timer_now(); timer.plugin = sampgdk_plugin_get_handle((void *)callback); if (timer.started == 0) { return 0; /* error already logged */ } slot = _sampgdk_timer_find_slot(); if (slot >= 0) { sampgdk_array_set(&_sampgdk_timers, slot, &timer); } else { error = sampgdk_array_append(&_sampgdk_timers, &timer); if (error < 0) { sampgdk_log_error("Error setting timer: %s", strerror(-error)); return 0; } slot = _sampgdk_timers.count - 1; } /* Timer IDs returned by the SA:MP's SetTimer() API begin * with 1, and so do they here. */ timerid = slot + 1; sampgdk_log_debug("Created timer: ID = %d, interval = %d, repeat = %s", timerid, interval, repeat ? "true" : "false"); return timerid; }