2012-02-13 2 views
2

У меня есть структура для определения графики функции в моем 2D-движке. В этом есть серия SDL_Rects под названием «middle, left_edge, top_left_corner» и т. Д. В части моего кода я инициализирую их с помощью ряда типов аргументов в командной строке сценариев/командной строки, которые хранятся в виде вектора из std :: строк.Избегание кода вставки кода, инициализирующего ряд SDL_Rects в Struct

В качестве стиля и избегания глупых ошибок из-за повторения (и для устранения любых ошибок 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

Я знаю, это звучит как глупый вопрос - но я всегда нервничаю, когда мое программирование чувствует, как я делаю работу Слова в " Form Printing " – lochok

+0

Можете ли вы разместить образец кода сценария, который инициализирует прямоугольники? – Asaf

+0

Банк 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'), чтобы свернуть четыре оператора init в один, но это на самом деле не улучшает код, и даже не делает его значительно короче. –

+0

Думаю, я понимаю, почему первое является предпочтительным решением ... Спасибо за вашу помощь! – lochok

Смежные вопросы