2012-02-13 8 views
2

私の2Dエンジンでは、フィーチャのグラフィックスを定義する構造体があります。その中には、 "middle、left_edge、top_left_corner"などの一連のSDL_Rectがあります。私のコードの一部では、一連の引数型をスクリプトエンジン/コマンドラインに初期化しています。のstd :: stringsの。構造体に一連のSDL_Rectを初期化するコピー貼り付けコードを避ける

スタイルの問題として、繰り返しによる愚かな間違いを避けて(そして間違いを9回修正する必要があります)、このコードをクリーンアップする方法はありますか?またはこれは合理的でしょうか?

//RectZeroes is just an SDL_Rect of {0,0,0,0} to ensure that it is initialised 

     SDL_Rect middle = RectZeroes; 
     if (args.size() >= 6) 
     { 
      middle.x = boost::lexical_cast<int>(args[3]); 
      middle.y = boost::lexical_cast<int>(args[4]); 
      middle.w = boost::lexical_cast<int>(args[5]); 
      middle.h = boost::lexical_cast<int>(args[6]); 
     } 

     SDL_Rect left_edge = RectZeroes; 
     if (args.size() >= 10) 
     { 
      left_edge.x = boost::lexical_cast<int>(args[7]); 
      left_edge.y = boost::lexical_cast<int>(args[8]); 
      left_edge.w = boost::lexical_cast<int>(args[9]); 
      left_edge.h = boost::lexical_cast<int>(args[10]); 
     } 
//And so on 
+0

私はそれは愚かな質問のように音を知っている - しかし、私のプログラミングは、私は「Wordのの仕事をやっているように感じたとき、私はいつも緊張しますフォーム印刷 " – lochok

+0

長方形を初期化するサンプルスクリプトコードを投稿できますか? – Asaf

+0

Bank AddFeatureStyle「ディスクリプタ」「LeftTrayEdge.png」3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 - そのために私がやった簡単なスクリプト言語(コマンドラインスタイルのインタプリタよりも多くのもの) - 最初の3の後のすべてが長方形です。スクリプトは必ずしもうまく人間が読めるようになるとは限りません。このような小さなCSV形式のMyDodgyScriptコンバータを作成して、テーブルのような実際のスプレッドシートを使うことができます。 – lochok

答えて

2

私はこれが楽しいコードではないことに同意します。繰り返しを避けるには、常にプログラミングと同じようにしてください。をカプセル化します。この場合、構造体をカプセル化して適切なコンストラクタを与え、boost::lexical_cast<int>(x)の周りに薄いラッパーを書きます。

それとも、あなたがSDL_Rectをラップ避けたいならば、初期化子の機能記述:その後、

template <typename TString> 
int parse_int(TString const& value) { return boost::lexical_cast<int>(value); } 

void init_sdl_rect_from_args(
    SDL_Rect& rect, std::vector<std::string> const& args, unsigned offset) 
{ 
    rect.x = parse_int(args[offset + 0]); 
    rect.y = parse_int(args[offset + 1]); 
    rect.w = parse_int(args[offset + 2]); 
    rect.h = parse_int(args[offset + 3]); 
} 

をそして:

SDL_Rect middle = RectZeroes; 
if (args.size() >= 6) 
    init_sdl_rect_from_args(middle, args, 3); 

SDL_Rect left_edge = RectZeroes; 
if (args.size() >= 10) 
    init_sdl_rect_from_args(left_edge, args, 7); 

いっそのこと、初期化子リターン構築構造を作ります。これは、(初期化子で、つまり)それがさらに便利に使用できるようになります:

SDL_Rect rect_from_args(std::vector<std::string> const& args, unsigned offset) { 
    SDL_Rect rect; 
    rect.x = parse_int(args[offset + 0]); 
    rect.y = parse_int(args[offset + 1]); 
    rect.w = parse_int(args[offset + 2]); 
    rect.h = parse_int(args[offset + 3]); 
    return rect; 
} 

SDL_Rect middle = (args.size() >= 6) ? rect_from_args(args, 3) : RectZeroes; 
SDL_Rect left_edge = (args.size() >= 10) ? rect_from_args(args, 7) : RectZeroes; 
+0

なぜこれがマクロでなければならないのですか?なぜSDL_Rect stringsToRect(ベクトル v、int offset) 'という関数だけではありませんか? –

+0

@Banthar私はばかだから。更新を参照してください。 BOOST.PP( 'BOOST_PP_SEQ_FOR_EACH_I')を使って4つのinit文を1つに折りたたみたいと思っていましたが、実際にはコードを大幅に改善することはできません。 –

+0

私はなぜ前者が好ましい解決策であるのか理解していると思います...助けてくれてありがとう! – lochok

関連する問題