https://api.unrealengine.com/INT/API/Runtime/Core/Serialization/FArchive/index.html

 

데이터를 전송하는 모든 매체는 아카이브 클래스 FArchive를 상속받아서 구현
언리얼은 입출력을 << 으로만 사용 (C++과 다른 점)

게임이 동작할 플랫폼에 맞도록 디스크나 메모리 및 다양한 매체등으로 객체를 전송해야 할텐데요, 
언리얼 엔진답게 이 부분에서 멀티플랫폼에서 동작하는 매체의 규약을 직접 만들었습니다.

이 클래스가 FArchive입니다. 

언리얼 엔진에서  파일, 메모리 등등 
데이터를 전송하는 모든 매체는 아카이브 클래스 FArchive를 상속받아서 구현합니다. 

이를 활용하기 위해 지난 강좌에서 제작한 WebConnecton 언리얼 오브젝트를 파일에 저장하고,
다시 빼오는 예제를 한번 만들어봅시다. 

WebConnection 언리얼 오브젝트는 Host와 URI의 멤버 변수를 가지고 있으므로,
이 정보를 파일에 저장했다가, 새로운 언리얼 오브젝트를 생성하고 이 데이터를 꺼내서 저장해봅시다.

아래는 이를 구현한 코드입니다.

 

//WebConnection.h 
UCLASS()
class WEBSERVICEK_API UWebConnection : public UObject
{
public:
	UPROPERTY()
	class UWebConnection* WebConnectionNew;
}

 

//ABGameInstance.cpp

void UABCGameInstance::Init()
{
	Super::Init();
	AB_LOG_CALLONLY(Warning);
    
    
    WebConnectionNew = NewObject<UWebConnection>(this);
	WebConnectionNew->Host = TEXT("127.0.0.7");
	WebConnectionNew->URI = TEXT("/");
	
    //경로설정
	FString FullPath = FString::Printf(TEXT("%s%s"), *FPaths::GameSavedDir(), TEXT("WebConnection.txt")); //경로에 파일을 만듬
	
    //롸이터 생성
	FArchive* ArWriter = IFileManager::Get().CreateFileWriter(*FullPath); //경로에 파일은 만든다
	
	if (ArWriter) //작성하고 종료
	{
		*ArWriter << WebConnectionNew->Host;
		*ArWriter << WebConnectionNew->URI;
		ArWriter->Close();
		delete ArWriter;
		ArWriter = NULL;
	}

	//리더 생성
	TSharedPtr<FArchive> FileReader = MakeShareable(IFileManager::Get().CreateFileReader(*FullPath)); //경로에 있는
	{
		FString Host;
		FString URI;
		*FileReader.Get() << Host;
		*FileReader.Get() << URI;
		FileReader->Close();
		AB_LOG(Warning, TEXT("WebConnection : Host %s , URI %s"), *Host, *URI);
	}
 }   
    

저장할 때에는 C++ 객체의 소멸을 사용했고,
불러들일 때에는 언리얼 엔진이 제공하는 공유포인터 라이브러리를 사용했습니다.

둘 간의 차이를 한번 비교해보시기 바랍니다. ( 공유포인터에 대한 내용은 다음 강좌에서 다루겠습니다. )

언리얼 에디터에서 세이브폴더라 함은, 프로젝트에 있는 Saved 폴더가 됩니다. 
그래서 
플레이를 눌러 실행한 후 탐색기에서 Saved 폴더를 확인하면 
WebConnection.txt 라는 파일이 생성되어 있는 것을 볼 수 있습니다. 

실행후 생성된 파일

추가로 에디터에서 로그를 살펴보면 파일로부터, 읽어들인 데이터 로그가 잘 찍혀있는 것을 확인할 수 있습니다. 

 

 


여기서 한가지 이상한 점이 있는데 일반 C++에서는 입출력을 << 와 >> 연산자를 구분해 사용했는데,  
언리얼에서는 특이하게 << 연산자만 사용한다는 점입니다.

언리얼에서는 데이터 입출력시에 항상 왼쪽 시프트 연산자만 사용하고,
아카이브의 처리시 현재 상태에 따라서 사용자가 분기해서 처리하도록 설계되어 있습니다. 
이후에 이 부분은 다시 살펴보도록 합시다. 

이번에는 구현에는 연산자에 인스턴스만 통채로 넘기게 만들고, 
클래스 선언에서 전송에 필요한 데이터를 지정하도록 변경해봅시다.

//ABGameInstance.cpp

void UABCGameInstance::Init()
{
	Super::Init();
	AB_LOG_CALLONLY(Warning);    
    
    WebConnection->TokenCompleteDelegate.AddDynamic(this, &UABGameInstance::RequestTokenComplete);
    WebConnection->RequestToken(TEXT("destiny")); 

    WebConnectionNew = NewObject<UWebConnection>(this);
    WebConnectionNew->Host = TEXT("127.0.0.7");
    WebConnectionNew->URI = TEXT("/"); 

    FString FullPath = FString::Printf(TEXT("%s%s"), *FPaths::GameSavedDir(), TEXT("WebConnection.txt"));

    FArchive* ArWriter = IFileManager::Get().CreateFileWriter(*FullPath);

    if (ArWriter)
    {
        *ArWriter << *WebConnectionNew; //추가
        ArWriter->Close();
        delete ArWriter;
        ArWriter = NULL;
    }

 
    TSharedPtr<FArchive> FileReader = MakeShareable(IFileManager::Get().CreateFileReader(*FullPath));

    if (FileReader.IsValid())
    {
        UWebConnection* WebConnectionFromFile = NewObject<UWebConnection>(this);  //추가
        *FileReader.Get() << *WebConnectionFromFile;                              //추가 
        FileReader->Close();
        AB_LOG(Warning, TEXT("WebConnection From File : Host %s , URI %s"), *WebConnectionFromFile->Host, *WebConnectionFromFile->URI); //추가
    }
}

 

현재 연산자 재정의가 안되어서 컴파일 오류가 나옴
WebConnection의 왼쪽 시프트 << 오퍼레이터를 전역함수 오버로딩 구문을 사용해 다음과 같이 선언해줍시다.

//WebConnection.h
class WEBSERVICE_API UWebConnection : public UObject
{
public:
	friend FArchive& operator<<(FArchive& Ar, UWebConnection& WC)
   {
        if (Ar.IsLoading())
        {
           UE_LOG(LogTemp, Warning, TEXT("Archive is Loading State"));
        }
        else if(Ar.IsSaving())
        {
            UE_LOG(LogTemp, Warning, TEXT("Archive is Saving State"));
        }
        else
        {
            return Ar;
        }
        return Ar << WC.Host << WC.URI;
   }
}   

이 선언에서 주의깊게 볼 부분은 아카이브의 함수 IsLoading과 IsSaving입니다.

이 함수를 사용하면 현재 아카이브의 상태가 저장 상태인지, 로딩 상태인지를 파악할 수 있습니다. 

'Unreal > Concept' 카테고리의 다른 글

unreal - code & blueprint  (0) 2020.12.08
언리얼 스마트포인터  (0) 2019.06.03
델리게이트 + 종류 및 함수 + 시그니처 + 바인딩  (0) 2019.05.30
UWorld  (0) 2019.05.30
World - 작성 중  (0) 2019.05.29

+ Recent posts