Skip to content
isdnetworks
Go back

값을 하나 늘렸더니 다른 데서 안 잡혔다

Cocos2d-x 클라이언트에 아이템 종류를 하나 더 넣었다. 상점 목록에 나오고 구매도 되는데 InventoryLayer 에서는 빈칸으로 보였다.

Table of contents

Open Table of contents

늘린 곳과 안 늘린 곳

enum ItemType 에 한 줄 넣고 ShopLayerswitch 에도 넣었다. 인벤토리 쪽에도 같은 모양이 있었고 거기는 안 건드렸다.

const char* invIcon(ItemType t) {
    switch (t) {
    case ITEM_WEAPON:  return "inv_weapon.png";
    case ITEM_ARMOR:   return "inv_armor.png";
    case ITEM_POTION:  return "inv_potion.png";
    }
    return "";     // 새 값은 여기로 온다
}

grep -rn "ItemType" --include=*.cpp 로 찾으니 일곱 군데였다. 아이콘과 정렬 순서와 판매 가능 여부와 창고 보관 여부와 효과 적용과 UserDefault.xml 저장 형식과 서버 전송 코드다. 일곱을 다 고쳐야 새 종류 하나가 완성된다. 한 군데를 놓치면 그 기능만 빠진다.

조용히 빠지는 것이 문제였다

빈 문자열을 돌려주면 GCC 가 아무 말도 안 하고 실행도 된다. CCSprite 가 빈 이름으로 만들어져 화면만 이상하다.

빠진 값을 눈에 띄게 만들었다. CCLOG 를 남기고 물음표 그림을 돌려준다. 빈칸은 못 알아채도 그것은 알아챈다.

컴파일러가 잡게 했다

default 를 아예 빼면 GCC 가 빠진 값을 경고한다. -Wall 에 들어 있는 -Wswitch 다.

warning: enumeration value 'ITEM_COSTUME' not handled in switch [-Wswitch]

default 가 있으면 이 경고가 안 나온다. 안전해 보이는 default 가 검사를 없애는 것이다.

-Wswitch-enum 이라는 것도 있었다. 이쪽은 default 가 있어도 빠진 값을 짚어 준다.

warning: enumeration values 'ITEM_ARMOR', 'ITEM_POTION', and 'ITEM_COSTUME'
  not explicitly handled in switch [-Wswitch-enum]

다만 이건 모든 switch 에 다 걸려서 시끄러웠다. 켜지 않았다.

그래서 switch 를 두 부류로 나눴다. 모든 값을 반드시 처리해야 하는 곳은 default 없이 두고 -Wswitch 에 맡긴다. JSON 으로 받은 값처럼 모르는 값이 들어올 수 있는 곳은 default 로 받고 CCLOG 를 남긴다. 앞쪽이 다섯이고 뒤쪽이 둘이었다.

표로 모으는 방법도 봤다

switch 를 일곱 군데 두는 대신 한 곳에 모으는 방법도 봤다.

static const ItemMeta ITEM_META[] = {
    { ITEM_WEAPON,  "icon_weapon.png",  "inv_weapon.png",  10, true  },
    { ITEM_COSTUME, "icon_costume.png", "inv_costume.png", 40, false },
};

새 종류가 줄 하나가 되고 빠뜨릴 자리가 없다. 전부 옮기지는 않았고 값을 돌려주기만 하는 것은 표로 갔으며 조건에 따라 계산이 들어가는 것은 분기로 남겼다.

enum 값을 배열 첨자로 쓰는 자리도 같이 봤다. ITEM_TYPE_MAX 를 쓰고 있으면 따라 늘지만 숫자를 직접 박아 뒀으면 새 값에서 범위를 넘는다. 그건 CCAssert 로 막았다.

정리


Share this post on:

Previous Post
한 자리에 계산값과 손으로 넣은 값이 섞였다
Next Post
화면을 오갈수록 죽었다