diff --git a/tgp-msg.c b/tgp-msg.c index b739cd7..04bec6e 100644 --- a/tgp-msg.c +++ b/tgp-msg.c @@ -159,6 +159,30 @@ static void tgp_msg_send_done (struct tgl_state *TLS, void *callback_extra, int } } +static gboolean tgp_msg_send_schedule_cb (gpointer data) { + connection_data *conn = data; + conn->out_timer = 0; + struct tgp_msg_sending *D = NULL; + + while ((D = g_queue_peek_head (conn->out_messages))) { + g_queue_pop_head (conn->out_messages); + tgl_do_send_message (D->TLS, D->to, D->msg, (int)strlen (D->msg), tgp_msg_send_done, NULL); + tgp_msg_sending_free (D); + } + return FALSE; +} + +static void tgp_msg_send_schedule (struct tgl_state *TLS, gchar *chunk, tgl_peer_id_t to) { + connection_data *conn = TLS->ev_base; + struct tgp_msg_sending *D = tgp_msg_sending_init (TLS, chunk, to); + g_queue_push_tail (conn->out_messages, D); + + if (conn->out_timer) { + purple_timeout_remove (conn->out_timer); + } + conn->out_timer = purple_timeout_add (0, tgp_msg_send_schedule_cb, conn); +} + static int tgp_msg_send_split (struct tgl_state *TLS, const char *message, tgl_peer_id_t to) { int max = TGP_DEFAULT_MAX_MSG_SPLIT_COUNT; if (max < 1) { @@ -172,8 +196,7 @@ static int tgp_msg_send_split (struct tgl_state *TLS, const char *message, tgl_p while (size > start) { int e = start + (int)TGP_MAX_MSG_SIZE; gchar *chunk = g_utf8_substring (message, start, e); - tgl_do_send_message (TLS, to, chunk, (int)strlen (chunk), tgp_msg_send_done, NULL); - g_free (chunk); + tgp_msg_send_schedule (TLS, chunk, to); start = e; } return 1; @@ -347,8 +370,7 @@ static time_t tgp_msg_oldest_relevant_ts (struct tgl_state *TLS) { return days > 0 ? tgp_time_n_days_ago (days) : 0; } -static void tgp_msg_process_ready (struct tgl_state *TLS) -{ +static void tgp_msg_process_in_ready (struct tgl_state *TLS) { connection_data *conn = TLS->ev_base; struct tgp_msg_loading *C; @@ -366,11 +388,10 @@ static void tgp_msg_on_loaded_photo (struct tgl_state *TLS, void *extra, int suc struct tgp_msg_loading *C = extra; C->data = filename; C->done = TRUE; - tgp_msg_process_ready (TLS); + tgp_msg_process_in_ready (TLS); } -void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M) -{ +void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M) { connection_data *conn = TLS->ev_base; struct tgp_msg_loading *C = tgp_msg_loading_init (TRUE, M); @@ -386,7 +407,6 @@ void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M) // TODO: load geo thumbnail } g_queue_push_tail (conn->new_messages, C); - tgp_msg_process_ready (TLS); + tgp_msg_process_in_ready (TLS); } - diff --git a/tgp-structs.c b/tgp-structs.c index 382a9cd..214c285 100644 --- a/tgp-structs.c +++ b/tgp-structs.c @@ -80,12 +80,27 @@ struct tgp_msg_loading *tgp_msg_loading_init (int done, struct tgl_message *M) { return C; } +struct tgp_msg_sending *tgp_msg_sending_init (struct tgl_state *TLS, gchar *M, tgl_peer_id_t to) { + struct tgp_msg_sending *C = malloc (sizeof (struct tgp_msg_sending)); + C->TLS = TLS; + C->msg = M; + C->to = to; + return C; +} + +void tgp_msg_sending_free (gpointer data) { + struct tgp_msg_sending *C = data; + g_free (C->msg); + free (C); +} + connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *gc, PurpleAccount *pa) { connection_data *conn = g_new0 (connection_data, 1); conn->TLS = TLS; conn->gc = gc; conn->pa = pa; conn->new_messages = g_queue_new (); + conn->out_messages = g_queue_new (); conn->pending_reads = g_queue_new (); return conn; } @@ -93,9 +108,11 @@ connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection * void *connection_data_free (connection_data *conn) { if (conn->write_timer) { purple_timeout_remove (conn->write_timer); } if (conn->login_timer) { purple_timeout_remove (conn->login_timer); } + if (conn->out_timer) { purple_timeout_remove (conn->out_timer); } tgp_g_queue_free_full (conn->pending_reads, pending_reads_free_cb); tgp_g_queue_free_full (conn->new_messages, tgp_msg_loading_free); + tgp_g_queue_free_full (conn->out_messages, tgp_msg_sending_free); tgp_g_list_free_full (conn->used_images, used_image_free); tgprpl_xfer_free_all (conn); tgl_free_all (conn->TLS); diff --git a/tgp-structs.h b/tgp-structs.h index b6fd044..20e3afd 100755 --- a/tgp-structs.h +++ b/tgp-structs.h @@ -33,10 +33,12 @@ typedef struct { PurpleConnection *gc; int updated; GQueue *new_messages; + GQueue *out_messages; GQueue *pending_reads; GList *used_images; guint write_timer; guint login_timer; + guint out_timer; int in_fallback_chat; } connection_data; @@ -65,6 +67,12 @@ struct tgp_msg_loading { void *data; }; +struct tgp_msg_sending { + struct tgl_state *TLS; + tgl_peer_id_t to; + gchar *msg; +}; + void pending_reads_send_all (GQueue *queue, struct tgl_state *TLS); void pending_reads_add (GQueue *queue, tgl_peer_id_t id); struct message_text *message_text_init (struct tgl_message *M, gchar *text); @@ -74,6 +82,7 @@ void *connection_data_free (connection_data *conn); connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *gc, PurpleAccount *pa); get_user_info_data* get_user_info_data_new (int show_info, tgl_peer_id_t peer); struct tgp_msg_loading *tgp_msg_loading_init (int done, struct tgl_message *M); +struct tgp_msg_sending *tgp_msg_sending_init (struct tgl_state *TLS, char *M, tgl_peer_id_t to); void tgp_msg_loading_free (gpointer data); - +void tgp_msg_sending_free (gpointer data); #endif