D言語でタスクシステムのようなもの

アバター
馬場自由
記事: 15
登録日時: 12年前

D言語でタスクシステムのようなもの

投稿記事 by 馬場自由 » 12年前

D言語自体はちょろっと触ってすぐ手放したんですが(
タスクシステムを実装したコードを掘り当てたのでここに載せておきます。
多分Dのver2.59あたりじゃなかったかな、覚えてませんが。
C++との違いは、クラスの継承で生じるメモリの面倒な部分を考えなくて良い所。
C++では多重継承がかなり厄介で、そのあたりを考えるとちょっと複雑になりますが、
Dは元から多重継承がないのでラクですね。
最近はタスクシステムもワークエリアを動的に変える実装が流行りのようですが、
古式ゆかしい固定型で実装してました。

CODE:

import std.stdio, std.string;
import std.c.string;

import rzGameCore;

//========================================================================
// タスクの根底構造
// 全ての動体はこのCMoverクラスを継承する
// そうしないとタスクリストで動かない
//========================================================================

class CMover {
protected:
  uint Time = 0;
public:
  void Draw(){}
  bool Move(){return true;}

  // タスクリストのメモリ上へインスタンスを生成
  new(size_t t) {
    void *p = Game.TaskList.Create().Memory.ptr;
    return p;
  }

  // Moveがfalseを返したら削除
  delete(void *p) {
    // L.Remove(Id);
  }
}

//========================================================================
// タスクリスト
//========================================================================
class CList {
protected:

//------------------------------------------------------------------------
// タスク
//------------------------------------------------------------------------
  struct STask {

    // 次タスクへのポインタ
    STask *next;

    // 前タスクへのポインタ
    STask *prev;

    // タスクID
    int Id;

    // ワークエリアメモリ
    void[] Memory;
  }

//------------------------------------------------------------------------
// メンバ変数
//------------------------------------------------------------------------
  // 現在アクティブになってるタスクの数
  uint NumActive = 0;

  // タスクリストの長さ
  int ListLength;

  // ワークエリアメモリの最大サイズ
  int WorkAreaMemorySize;

public:

//------------------------------------------------------------------------
// 外からアクセスできる変数
//------------------------------------------------------------------------
  // 待機タスクリスト
  STask[] Wait;

  // 実行タスクリスト
  STask *Active;

  //======================================================================
  // コンストラクタ
  //======================================================================
  this(in int list_length, in int work_area_size = 1024) {
    ListLength = list_length;
    WorkAreaMemorySize = work_area_size;

    // メモリアライメントを計算
    if(work_area_size % 8 != 0) 
      throw new Exception("wrong memory alignment");

    //--------------------------------------------------------------------
    // タスクリスト本体とタスクのワークエリアメモリを確保
    //--------------------------------------------------------------------
    Wait = new STask[list_length + 1];
    for(int i = 0; i = NumActive) {

      // 待機タスクを探して取り出す
      STask *t = Wait.ptr.next;
      t.prev.next = t.next;
      t.next.prev = t.prev;
      NumActive++;

      // アクティブタスクへ挿入する
      t.prev = Active.prev;
      t.next = Active;
      t.next.prev = t.prev.next = t;
      return t;
    }
    return null;
  } // end Create()

  //======================================================================
  // アクティブリストからタスクを取り出して待機リストへ繋ぐ
  //======================================================================
  void Remove(STask *t) {

    if(NumActive >= 1) {
      // アクティブタスクを取り出す
      t.prev.next = t.next;
      t.next.prev = t.prev;

      // 待機タスクへ挿入する
      t.prev = Wait.ptr;
      t.next = Wait.ptr.next;
      t.next.prev = t.prev.next = t;
      NumActive--;
    }
  } // end Remove()
} // end CList


D言語用のコード装飾もあったのか・・・!

コメントはまだありません。