Collection Library Editer for Enbedded C というアイディア
最近私はC言語でプログラミングをしています。
組み込み環境にとても興味があり、近いうちに組み込み環境の為の自分用ユーティリティライブラリを作ろうと考えています。
そのなかで、単純なリストを使いたい場面がありました。
そこで自分で簡易的なものを実装することにしました。
私はプログラミングの知識を勉強するのは好きなのですが、
勉強した知識を使うということがあまりないのです。
つまり、単純なサンプルプログラムを実装する意欲がわかない怠け者なのです。
これが実装を決めた理由です。
まずはどのような実装にするか、案を練って以下のようなものになりました。
- リスト構造にアクセスするインタフェースを用意する
- インタフェースを使わずにリストにアクセスしない
- メモリ要領を(無闇に)意識したものにする
- 要素へのアクセス速度を意識したものにする
- 汎用リストコンテナを作ることにはこだわらない
これらのことを踏まえて、
描画した曲線をサンプリングして点列を取得し、
その点列を格納するためのリストを作りました。
その際に、いくつかの世にでているC用ライブラリを参考に実装しました。
以下にソースを紹介します。
まずはヘッダ。
// 型定義 /// 2次元座標値 typedef struct position_2d_int_t { int x; ///< x座標値 int y; ///< y座標値 } pos_2i_t; /// pos_list_tコンテナに格納する座標値 typedef struct position_cell_t { pos_2i_t pos; struct position_cell_t *next; } pos_cell_t; /// 座標値をリスト構造で格納するコンテナ typedef struct position_list_t { pos_cell_t *front; ///< 先頭の座標値を示すポインタ pos_cell_t *back; ///< listの最後の要素を示すポインタ } pos_list_t; /// 座標値リストのイテレータ(ただのポインタ) typedef pos_cell_t *pos_list_iterator; // pos_2i_tのインタフェース /// 座標値のセッタ void set_pos_2i( pos_2i_t *_pos, int _x, int _y ); // pos_listのインタフェース /// pos_listの初期化 void init_pos_list( pos_list_t *_p_list ); /// 座標値をpos_listへ末尾挿入 void push_back_pos( pos_list_t *_p_list, pos_2i_t _pos ); /// リストの中身を全て削除 void clear_pos_list( pos_list_t *_p_list ); // pos_list_iteratorのインタフェース /// 先頭のイテレータを取得 pos_list_iterator get_front_pos_it( pos_list_t _p_list ); /// 末尾のイテレータを取得 pos_list_iterator get_back_pos_it( pos_list_t _p_list ); /// iteratorの初期化 void init_pos_it( pos_list_iterator *_dest ); /// iteratorのセット void set_pos_it( pos_list_iterator *_dest, pos_list_iterator _src ); /// iteratorを一つ前進 void advance_pos_it( pos_list_iterator *_p_ite ); /// 次のノードが存在するときは1を返す int has_next_pos_it( pos_list_iterator _p_ite ); /// iteratorの指すノードの座標を取得 pos_2i_t get_pos_it( pos_list_iterator _p_ite );
上記のインタフェースを使えば以下のようなことができます。
以下のソースは、リストに入っている座標値を順に線でつなぐように描画するOpenGL用の関数です。
void draw_curve( pos_list_t _curve ) { if( _curve.front != NULL ) { pos_list_iterator it; init_pos_it( &it ); set_pos_it( &it, get_front_pos_it( _curve ) ); pos_2i_t temp; glBegin( GL_LINE_STRIP );{ for( ; has_next_pos_it( it ); advance_pos_it( &it ) ) { temp = get_pos_it( it ); glVertex2d( temp.x, temp.y ); } };glEnd(); } }
実装してみて思ったことをまとめます。
- pos_2i_tの中身を変更しようとすると、インタフェースを複数変更しなければならず、大変
- pos_2i_t以外の型もリストにするには、似たようなソースを記述しなければならない
既存のC用ライブラリでは、それぞれ実装が細かく違います。
汎用コンテナをCの流儀で記述しようというものや、
マクロをふんだんに使ったものなどバリエーションも豊富。
リスト構造は使われ方によって柔軟に形を変えるものなんだなと思いました。
そこで、タイトルのとおり、自分の欲しい「リスト」を
手早くソースファイルとして出力するためのツールが欲しいなと思いました。
手作業で編集すればデバッグも大変です。
似たようなソースをたくさん用意しなければならない状況でも
テンプレートを出力してくれるツールさえあれば
苦労も少しは減るかもしれません。
より具体的なアイディアが思いついたり、
もしくは、より積極的なツールをつくるべき理由が見つかれば
CLEECという名前で開発を始めたいと考えています。