ソフトウェア設計及び演習2016

GDK2016::タイムアウト

タイムアウト

  • 一定の時間間隔で関数を呼び出す
  • プログラムを終了させる前に、イベントを停止させる必要がある
    • 停止せずに終了すると、まれにcoreを吐く
    • 終了処理中にもタイムアウトが発生して、既に解放されたものを使おうとするためらしい

タイムアウトの設定

guint g_timeout_add (guint interval,
                     GSourceFunc function,
                     gpointer data);
gboolean g_source_remove (guint tag);
30msごとにmove_sprite(draw_animation)を呼ぶ
  • my_animation_ball関数
anime->timeout = g_timeout_add(30, (GSourceFunc)move_sprite, anime);

/* 終了時のコールバックを設定 */
g_signal_connect(G_OBJECT(window), "delete_event",
                 G_CALLBACK(cb_delete_event), (gpointer)anime);
  • move_sprite関数
/* スプライトを動かす */
static gint
move_sprite(gpointer data)
{
  anime_pack *anime = (anime_pack *)data;

  gint x = anime->x,   y = anime->y;
  gint dx = anime->dx, dy = anime->dy;
  gint s_width = anime->s_width;
  gint s_height = anime->s_height;

  /* スプライトの座標を更新 */
  x += dx; y += dy;
  /* 端まで行ったら跳ね返す */
  if(x < 0)                 { x += 0 - x;                 dx = -dx; }
  if(y < 0)                 { y += 0 - y;                 dy = -dy; }
  if(x > WIDTH - s_width)   { x += WIDTH - s_width - x;   dx = -dx; }
  if(y > HEIGHT - s_height) { y += HEIGHT - s_height - y; dy = -dy; }

  anime->x = x;   anime->y = y;
  anime->dx = dx; anime->dy = dy;

  /* ドローイングエリアを更新 */
  draw_animation(anime);

  return TRUE;
}
  • 呼び出された関数が、FALSEを返すまで繰り返し呼び出す
    • FALSEを返したら止まる
  • cb_delete_event関数
/* 終了処理 */
static gint
cb_delete_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
  anime_pack *anime = (anime_pack *)data;

  /* timeoutイベントを停止させる */
  if(anime->timeout) g_source_remove(anime->timeout);
  if(anime->s_timeout) g_source_remove(anime->s_timeout);

  /* 続けてdestroyを実行 */
  return FALSE;
}
  • 戻り値をFALSEにすると、続けてdestroyを実行
  • 戻り値をTRUEにすると、終了しない
    • 「本当に終了しますか? Y or N」のようなプログラムは、delete_eventのコールバックに書く


最終更新日:2016/05/27 14:48:09