Skip to content
isdnetworks
Go back

하나를 눌렀는데 여러 곳이 바뀌었다

아이템을 쓰면 소모되고 효과가 붙고 통계가 올라간다. 효과 적용이 실패하는 경우가 있었는데 그때 아이템은 이미 없어져 있었다.

Table of contents

Open Table of contents

순서대로 바꾸고 있었다

한 함수 안에서 네 가지를 차례로 하고 있었다.

inventory.remove(itemId);        // 1. 소모
player.applyEffect(itemId);      // 2. 효과
stats.itemUsed++;                // 3. 통계
saveData();                      // 4. 저장

두 번째가 실패해도 첫 번째는 이미 됐다. 아이템은 사라지고 효과는 없다. 예외로 빠져나가는 방법도 그때는 없었다. NDK 는 예외를 기본으로 끄고 Application.mkAPP_CPPFLAGS += -fexceptions 를 넣어야 열린다. 우리는 안 열어 뒀으니 실패는 반환값으로만 온다.

확인을 앞으로 모았다

바꾸기 전에 확인할 것을 다 확인하고 그다음에 바꾸게 했다.

if (!inventory.has(itemId))        return false;
if (!player.canApply(itemId))      return false;
if (player.isEffectActive(itemId)) return false;

inventory.remove(itemId);
player.applyEffect(itemId);

변경 단계에 들어가면 끝까지 간다. 실패할 만한 것을 앞에서 다 걸렀기 때문이다. 전부를 이렇게 만들 수는 없다. 다만 대부분의 실패는 조건 확인으로 걸러졌다.

바꾸기 전 상태를 들고 있었다

그래도 중간에 실패하는 경우가 있었다. 바꾸기 전 상태를 들고 있다가 되돌리게 했다.

ItemSnapshot snap = inventory.snapshot(itemId);
inventory.remove(itemId);
if (!player.applyEffect(itemId)) {
    inventory.restore(snap);
    return false;
}

되돌리는 코드도 실패할 수 있으니 완전하지는 않다. 다만 확인을 앞으로 모으는 것과 같이 쓰니 실제로 되돌리는 일이 거의 없었다.

저장 시점과 변경 목록

저장이 매번 도는 것도 봤다. 아이템을 연속으로 쓰면 저장이 여러 번이다. 파일을 쓰는 일이라 느리고 그 도중에 앱이 꺼지면 파일이 깨진다.

바뀐 것을 표시만 해 두고 CCScheduler 에 걸어 몇 초에 한 번 저장하게 했다. 화면을 나갈 때와 AndroidonPause() 를 부를 때는 즉시 저장한다.

동작마다 무엇을 건드리는지도 적어 봤다. 아이템 사용이 넷이고 캐릭터 강화가 넷이며 스테이지 클리어가 여섯이었다. 목록을 만들고 나서 어디를 먼저 손볼지가 정해졌다.

순서에도 규칙을 뒀다. 확인을 먼저 하고 되돌리기 쉬운 메모리를 바꾸고 파일과 서버를 마지막에 둔다. 서버로 보낸 것은 되돌리기가 가장 어렵다.

정리


Share this post on:

Previous Post
상태를 바꾸면 값 두 개가 같이 움직였다
Next Post
한 번 재 보고 계획을 버렸다