Garbage Collection

塵も積もれば山

目次

Blog 利用状況

ニュース

C++とかC#とか数学ネタを投下していく予定です。

[その他のページ]
日々の四方山話を綴った日記出水の日記帳

書庫

日記カテゴリ

[C++]ブロックに定評のない読み込み

今、ブロックしないファイル読み込みをやっています。

普通にファイル読み込みを書いた場合、データを読み込む間はプログラムが止まります。
そこを止まらないように作りたいわけです。

まず、Request関数でファイルの読み込み要求を投げます。
あとは、Loading関数がtrueになるまで待機し、trueになったらGetBuffer関数でデータを得ます。

で、出来たのがこんな関数。
このUpdage関数は毎フレーム呼ばれることを想定して作成しています。

void Update(){
  switch(state){
  case 0:
    file.Request("data.dat");
    state++;
    break;
  case 1:
    if (file.Loading() == false) state++;
    break;
  case 2:
    config.LoadFromMemory(file.GetBuffer());
    state++;
  case 3:
    file2.Request(config.StageName(stage));
    state+;
  case 4:
    if (file2.Loading() == false) state++;
    break;
  case 5:
    stage.LoadFromFile(file2.GetBuffer());
    stageReady = true;
    state++;
    break;
  default:
    break;
  }
}

しかし、この関数、非常に書いてて苦痛です。
上のソースにはこんな問題点があります。

・コードの追加や削除が面倒
・無駄に1フレーム待つ場所がある

コードに追加や削除をする度に全体のcaseの数値を書き換えなければなりません。
それに、ひょんなことからstate++ を2回書いてしまうというバグの混入が考えられます。

また、上記のプログラム、case 2,3,4まではわざわざbreakする必要がありません。
もっといえば、ファイル読み込みの部分にキャッシュが搭載されていて、
Requestを投げたらすぐにLoading関数がtrueを返す設計の場合、無駄に待っていることになります。

この辺を少し改善したソースがこの通り

void Update(){
  switch(state){
  case 0:
    file.Request("data.dat");
  case 1: state = 1;
    if (file.Loading() == false) break;
  case 2: state = 2;
    config.LoadFromMemory(file.GetBuffer());
  case 3: state = 3;
    file2.Request(config.StageName(stage));
  case 4: state = 4;
    if (file2.Loading() == false) break;
  case 5: state = 5:
    stage.LoadFromFile(file2.GetBuffer());
    stageReady = true;
  default:state = 999;
    break;
  }
}

少し野暮ったいプログラムになりましたが、前のプログラムに会った
「無駄に待つ」、「state++を2回書いてしまう」という問題点は解決されました。

追加は相変わらず面倒ですが、stateが連番でなくても良いため削除は簡単になっています。
追加を楽にするために、1,2,3ではなく、10,20,30と番号をふったら良いかもしれません。
っていつのBASICや! RENUMよこせ、RENUM!!!

ということで、もっとスッキリ爽快なソースを紹介。

bool Update(){
  CoroutineBegin();  

  file.Request("data.dat");
  while(file.Loading()) yield;
  config.LoadFromMemory(file.GetBuffer());
  file2.Request(config.StageName(stage));
  while (file2.Loading()) yield;
  stage.LoadFromFile(file2.GetBuffer());
  stageReady = true;
  state = -1;

  CoroutineEnd();  
 return true;  
}

前回のコルーチンの登場です。
どうですか、このスッキリ具合。
ソースは短くなったし、追加、削除での番号振り直しもありません。

コルーチンの内部では暗黒儀式を行っているような気がしますが、
ほら、boostの内部でも暗黒儀式多いですしおすし。
私、脱いだらすごいんです、ということでひとつなんとか。

投稿日時 : 2010年5月2日 0:05

Feedback

# Illikebuisse boasj 2021/07/03 2:26 pharmaceptica.com

sildenafil 20 mg daily https://www.pharmaceptica.com/

# Illikebuisse emlit 2021/07/04 12:51 pharmacepticacom

sildenafil 80 mg https://www.pharmaceptica.com/

# Illikebuisse qqsyt 2021/07/04 14:54 www.pharmaceptica.com

hydroxchloriquine https://www.pharmaceptica.com/

# erectile linked diabetes 2021/07/11 7:26 hydroxocloroquine

hcqs 400 https://plaquenilx.com/# hydroxychloroquine cures

# re: [C++]?????????????? 2021/07/25 21:26 hydrochloquine

sulfur effects on body https://chloroquineorigin.com/# hydroxychloroquine sulfate tablets

# re: [C++]?????????????? 2021/08/07 2:16 hydroxychloroquine 200

chlorodine https://chloroquineorigin.com/# chloroquine phosphate vs hydroxychloroquine

# euyxtdvbhfky 2021/12/02 19:51 dwedayedmh

https://chloroquinesen.com/

# aralen for sale 2022/12/28 16:18 MorrisReaks

chloroquine phosphate 500 mg https://www.hydroxychloroquinex.com/

タイトル  
名前  
Url
コメント