-
멀티플레이어 게임 프로그래밍 - 코드 오류 수정프로그래밍/의문 2018. 2. 20. 12:13반응형
178p LinkingContext 코드 개량 부분 오류
// @comment: 없을 때 0을 반환하기보단, std::optinal(c++14)을 활용해 값이 있고 없음을 구분하도록 하는 게 더 좋을 거 같다.uint32_t GetNetworkID(const GameObject* inGameObject, bool inShouldCreateIfNotFound = true){auto it = mGameObjectToNetworkIdMap.find(inGameObject);if (it != mGameObjectToNetworkIdMap.end()){return it->second;}else if (inShouldCreateIfNotFound){uint32_t newNetworkId = AllocateId();AddGameObject(inGameObject, newNetworkId);return newNetworkId;}return 0;}std::uint32_t AddGameObject(GameObject* gameObject){const std::uint32_t id = AllocateId();AddGameObject(gameObject, id);return id;}원인
인자로 const GameObject*를 받는데, AddGameObject는 GameObject*를 받는다.
AddGameObject를 호출하려면 inGameObject의 상수성이 깨져야 하므로 오류가 발생한다.
수정된 코드
#pragma once#include <cstdint>#include <unordered_map>#include "GameObject.h"class LinkingContext{public:LinkingContext() : mNextNetworkId(1){}// @comment: 없을 때 0을 반환하기보단, std::optinal(c++14)을 활용해 값이 있고 없음을 구분하도록 하는 게 더 좋을 거 같다.uint32_t GetNetworkID(GameObject* inGameObject, bool inShouldCreateIfNotFound = true){auto it = mGameObjectToNetworkIdMap.find(inGameObject);if (it != mGameObjectToNetworkIdMap.end()){return it->second;}else if (inShouldCreateIfNotFound){uint32_t newNetworkId = AllocateId();AddGameObject(inGameObject, newNetworkId);return newNetworkId;}return 0;}GameObject* GetGameObject(std::uint32_t networkId){auto it = mNetworkIdToGameObjectMap.find(networkId);return it == mNetworkIdToGameObjectMap.end() ? nullptr : it->second;}std::uint32_t AddGameObject(GameObject* gameObject){const std::uint32_t id = AllocateId();AddGameObject(gameObject, id);return id;}void AddGameObject(GameObject* gameObject, std::uint32_t networkId){mNetworkIdToGameObjectMap[networkId] = gameObject;mGameObjectToNetworkIdMap[gameObject] = networkId;}void RemoveGameObject(std::uint32_t networkId){auto it = mNetworkIdToGameObjectMap.find(networkId);if (it == mNetworkIdToGameObjectMap.end()){return;}mGameObjectToNetworkIdMap.erase(it->second);mNetworkIdToGameObjectMap.erase(it);}void RemoveGameObject(const GameObject* gameObject){auto it = mGameObjectToNetworkIdMap.find(gameObject);if (it == mGameObjectToNetworkIdMap.end()){return;}mNetworkIdToGameObjectMap.erase(it->second);mGameObjectToNetworkIdMap.erase(it);}private:std::uint32_t AllocateId(){return mNextNetworkId++;}std::unordered_map<std::uint32_t, GameObject*> mNetworkIdToGameObjectMap;std::unordered_map<const GameObject*, std::uint32_t> mGameObjectToNetworkIdMap;std::uint32_t mNextNetworkId = 1;};const를 떼기 싫다면 Write 외부에서 LinkingContext에 등록하는 행위를 Write외부에서 하도록 하거나, GetNetworkID를 const 버전과 non const 버전을 각각 만들어서 const 버전에선 Add를 하지 않고 find만 하도록,
non const 버전에선 Add를 하도록 구현을 분리해야 한다.
추가적으로 LinkingContext에서처럼 인자가 포인터면서, 반드시 들어와야 하는 경우는 인자를 래퍼런스로 받도록 하는 게 더 낫다 생각한다.
uint32_t GetNetworkID(GameObject& inGameObject, bool inShouldCreateIfNotFound = true){auto it = mGameObjectToNetworkIdMap.find(&inGameObject);if (it != mGameObjectToNetworkIdMap.end()){return it->second;}else if (inShouldCreateIfNotFound){uint32_t newNetworkId = AllocateId();AddGameObject(inGameObject, newNetworkId);return newNetworkId;}return 0;}반응형'프로그래밍 > 의문' 카테고리의 다른 글
DB RETURN을 명시적으로 지정하지 않아 임의로 값이 바뀐 경우 (0) 2018.04.06 게임에서의 아이템 강화, n번 했을 때 성공할 확률은 어떻게 될까? (0) 2018.02.26 저장 프로시저 동시 호출로 인해 행 개수 조절에 실패한 경우 (0) 2017.12.19 비주얼 스튜디오, 64비트 테스트는 32비트 프로세스에서 실행할 수 없습니다. 오류 해결 (0) 2017.12.12 유니티 클라이언트와 c++ 서버 플랫 버퍼로 통신하기 성공~ (0) 2017.12.04