mirror of
https://github.com/irssi/irssi.git
synced 2024-09-01 04:14:16 -04:00
added signal_continue() for continuing signal emission with new parameters.
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2730 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
4b45f190a2
commit
da867d4d68
@ -39,6 +39,7 @@ typedef struct {
|
||||
|
||||
int emitting; /* signal is being emitted */
|
||||
int stop_emit; /* this signal was stopped */
|
||||
int continue_emit; /* this signal emit was continued elsewhere */
|
||||
int remove_count; /* hooks were removed from signal */
|
||||
|
||||
SignalHook *hooks;
|
||||
@ -51,6 +52,7 @@ void *signal_user_data;
|
||||
|
||||
static GHashTable *signals;
|
||||
static Signal *current_emitted_signal;
|
||||
static SignalHook *current_emitted_hook;
|
||||
|
||||
#define signal_ref(signal) ++(signal)->refcount
|
||||
#define signal_unref(signal) (signal_unref_full(signal, TRUE))
|
||||
@ -208,12 +210,13 @@ static void signal_hooks_clean(Signal *rec)
|
||||
}
|
||||
}
|
||||
|
||||
static int signal_emit_real(Signal *rec, int params, va_list va)
|
||||
static int signal_emit_real(Signal *rec, int params, va_list va,
|
||||
SignalHook *first_hook)
|
||||
{
|
||||
const void *arglist[SIGNAL_MAX_ARGUMENTS];
|
||||
Signal *prev_emitted_signal;
|
||||
SignalHook *hook;
|
||||
int i, stopped, stop_emit_count;
|
||||
SignalHook *hook, *prev_emitted_hook;
|
||||
int i, stopped, stop_emit_count, continue_emit_count;
|
||||
|
||||
for (i = 0; i < SIGNAL_MAX_ARGUMENTS; i++)
|
||||
arglist[i] = i >= params ? NULL : va_arg(va, const void *);
|
||||
@ -221,18 +224,22 @@ static int signal_emit_real(Signal *rec, int params, va_list va)
|
||||
/* signal_stop_by_name("signal"); signal_emit("signal", ...);
|
||||
fails if we compare rec->stop_emit against 0. */
|
||||
stop_emit_count = rec->stop_emit;
|
||||
continue_emit_count = rec->continue_emit;
|
||||
|
||||
signal_ref(rec);
|
||||
|
||||
stopped = FALSE;
|
||||
rec->emitting++;
|
||||
|
||||
for (hook = rec->hooks; hook != NULL; hook = hook->next) {
|
||||
prev_emitted_signal = current_emitted_signal;
|
||||
prev_emitted_hook = current_emitted_hook;
|
||||
current_emitted_signal = rec;
|
||||
|
||||
for (hook = first_hook; hook != NULL; hook = hook->next) {
|
||||
if (hook->func == NULL)
|
||||
continue; /* removed */
|
||||
|
||||
prev_emitted_signal = current_emitted_signal;
|
||||
current_emitted_signal = rec;
|
||||
current_emitted_hook = hook;
|
||||
#if SIGNAL_MAX_ARGUMENTS != 6
|
||||
# error SIGNAL_MAX_ARGUMENTS changed - update code
|
||||
#endif
|
||||
@ -240,7 +247,8 @@ static int signal_emit_real(Signal *rec, int params, va_list va)
|
||||
hook->func(arglist[0], arglist[1], arglist[2], arglist[3],
|
||||
arglist[4], arglist[5]);
|
||||
|
||||
current_emitted_signal = prev_emitted_signal;
|
||||
if (rec->continue_emit != continue_emit_count)
|
||||
rec->continue_emit--;
|
||||
|
||||
if (rec->stop_emit != stop_emit_count) {
|
||||
stopped = TRUE;
|
||||
@ -248,14 +256,16 @@ static int signal_emit_real(Signal *rec, int params, va_list va)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
current_emitted_signal = prev_emitted_signal;
|
||||
current_emitted_hook = prev_emitted_hook;
|
||||
|
||||
rec->emitting--;
|
||||
signal_user_data = NULL;
|
||||
|
||||
if (!rec->emitting) {
|
||||
if (rec->stop_emit != 0) {
|
||||
/* signal_stop() used too many times */
|
||||
rec->stop_emit = 0;
|
||||
}
|
||||
g_assert(rec->stop_emit == 0);
|
||||
g_assert(rec->continue_emit == 0);
|
||||
|
||||
if (rec->remove_count > 0)
|
||||
signal_hooks_clean(rec);
|
||||
@ -278,7 +288,7 @@ int signal_emit(const char *signal, int params, ...)
|
||||
rec = g_hash_table_lookup(signals, GINT_TO_POINTER(signal_id));
|
||||
if (rec != NULL) {
|
||||
va_start(va, params);
|
||||
signal_emit_real(rec, params, va);
|
||||
signal_emit_real(rec, params, va, rec->hooks);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
@ -296,13 +306,35 @@ int signal_emit_id(int signal_id, int params, ...)
|
||||
rec = g_hash_table_lookup(signals, GINT_TO_POINTER(signal_id));
|
||||
if (rec != NULL) {
|
||||
va_start(va, params);
|
||||
signal_emit_real(rec, params, va);
|
||||
signal_emit_real(rec, params, va, rec->hooks);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
return rec != NULL;
|
||||
}
|
||||
|
||||
void signal_continue(int params, ...)
|
||||
{
|
||||
Signal *rec;
|
||||
va_list va;
|
||||
|
||||
rec = current_emitted_signal;
|
||||
if (rec == NULL || rec->emitting <= rec->continue_emit)
|
||||
g_warning("signal_continue() : no signals are being emitted currently");
|
||||
else {
|
||||
va_start(va, params);
|
||||
|
||||
/* stop the signal */
|
||||
if (rec->emitting > rec->stop_emit)
|
||||
rec->stop_emit++;
|
||||
|
||||
/* re-emit */
|
||||
rec->continue_emit++;
|
||||
signal_emit_real(rec, params, va, current_emitted_hook->next);
|
||||
va_end(va);
|
||||
}
|
||||
}
|
||||
|
||||
/* stop the current ongoing signal emission */
|
||||
void signal_stop(void)
|
||||
{
|
||||
|
@ -43,6 +43,9 @@ void signal_remove_id(int signal_id, SIGNAL_FUNC func, void *user_data);
|
||||
int signal_emit(const char *signal, int params, ...);
|
||||
int signal_emit_id(int signal_id, int params, ...);
|
||||
|
||||
/* continue currently emitted signal with different parameters */
|
||||
void signal_continue(int params, ...);
|
||||
|
||||
/* stop the current ongoing signal emission */
|
||||
void signal_stop(void);
|
||||
/* stop ongoing signal emission by signal name */
|
||||
|
@ -76,6 +76,25 @@ CODE:
|
||||
}
|
||||
signal_emit(signal, items-1, p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
|
||||
void
|
||||
signal_continue(...)
|
||||
CODE:
|
||||
void *p[SIGNAL_MAX_ARGUMENTS];
|
||||
int n;
|
||||
|
||||
memset(p, 0, sizeof(p));
|
||||
for (n = 0; n < items && n < SIGNAL_MAX_ARGUMENTS; n++) {
|
||||
if (SvPOKp(ST(n)))
|
||||
p[n] = SvPV(ST(n), PL_na);
|
||||
else if (irssi_is_ref_object(ST(n)))
|
||||
p[n] = irssi_ref_object(ST(n));
|
||||
else if (SvROK(ST(n)))
|
||||
p[n] = (void *) SvIV((SV*)SvRV(ST(n)));
|
||||
else
|
||||
p[n] = NULL;
|
||||
}
|
||||
signal_continue(items, p[0], p[1], p[2], p[3], p[4], p[5]);
|
||||
|
||||
void
|
||||
signal_add(...)
|
||||
CODE:
|
||||
|
Loading…
Reference in New Issue
Block a user