ResourceService

리소스와 관련된 기능을 제공하는 서비스입니다.

# Methods

[{"index":"void ClearCaches()","0":"불러온 모든 리소스를 캐시에서 제거합니다. 리소스를 메모리에서 해제하려면 ClearCaches() 함수로 캐시를 먼저 제거한 후 UnloadUnusedResources() 함수를 사용합니다."}]

[{"index":"ResourceType GetTypeAndWait(string RUID) (Yield)","0":"RUID의 리소스 타입을 반환합니다."}]

[{"index":"AnimationClip LoadAnimationClipAndWait(string RUID) (Yield)","0":"애니메이션 클립 리소스를 불러옵니다. 불러온 리소스는 캐싱되어 메모리에서 해제되지 않고, 필요 시 재사용됩니다. 수행하는 동안 스크립트 실행을 중단합니다."}]

[{"index":"Sprite LoadSpriteAndWait(string RUID) (Yield)","0":"스프라이트 리소스를 불러옵니다. 불러온 리소스는 캐싱되어 메모리에서 해제되지 않고, 필요 시 재사용됩니다. 수행하는 동안 스크립트 실행을 중단합니다."}]

[{"index":"void PreloadAsync(List ruidList, func> completeCallback)","0":"ruidList에 지정된 RUID들을 미리 불러옵니다. 불러온 리소스는 캐싱되어 메모리에서 해제되지 않고 필요 시 재사용됩니다. 비동기로 실행되며, 작업이 완료되면 completeCallback으로 전달된 함수가 호출되고 로드 결과를 ruidList에 지정한 리소스 RUID와 동일한 순서대로 반환합니다."}]

[{"index":"void PreloadTileSetAsync(string tileSetId, func completeCallback)","0":"타일 셋에 속한 모든 Sprite 리소스들을 미리 로드합니다. tileSetId는 TileDataSet 엔트리의 Id입니다. 비동기로 실행되며, 작업이 완료되면 completeCallback으로 전달된 함수가 호출되고 로드 결과를 반환합니다."}]

[{"index":"void RemoveCaches(List ruidList)","0":"불러온 리소스를 캐시에서 제거합니다. ruidList는 제거할 리소스들의 RUID입니다. 리소스를 메모리에서 해제하려면 이 함수로 캐시를 먼저 제거한 후 UnloadUnusedResources 함수를 사용하세요."}]

[{"index":"void RequestSpriteUploadAsync(RawImage rawImage, func callbackFunction) (ClientOnly)","0":"RawImage를 스프라이트로 변환해 서버에 업로드하고 RUID를 발급받습니다. callbackFunction의 첫 번째 매개 변수는 에러 코드, 두 번째는 발급된 RUID입니다."}]

[{"index":"void SetSpriteUploadValidationCallback(func -> boolean callbackFunction) (ServerOnly)","0":"클라이언트에서 리소스 업로드를 요청했을 때 이를 허용할지 여부를 결정하는 함수를 등록합니다. 요청을 허가하려면 true를 반환하고, 아닌 경우 false를 반환합니다."}]

[{"index":"void UnloadUnusedResources(float pendingTimeSeconds)","0":"메모리에서 리소스를 해제합니다. 해제 대상인 리소스는 pendingTimeSeconds 동안 사용되지 않았으며, 캐시에서 제거된 모든 리소스입니다. 시간 단위는 초입니다."}]

##### inherited from Service:

[{"index":"EventHandlerBase ConnectEvent(string key, IScriptFunction eventHandler)","0":"이벤트를 연결합니다. 이 서비스에서 타입의 이름이 key인 이벤트가 발생하면, 핸들러로 통지받습니다. 핸들러는 event 매개 변수를 전달받습니다."}]

[{"index":"EventHandlerBase ConnectEvent(Type eventType, IScriptFunction eventHandler)","0":"이벤트를 연결합니다. 이 서비스에서 타입이 eventType인 이벤트가 발생하면, 핸들러로 통지받습니다. 핸들러는 event 매개 변수를 전달받습니다."}]

[{"index":"boolean DisconnectEvent(string key, EventHandlerBase eventHandler)","0":"타입의 이름이 key인 이벤트와 핸들러와의 이벤트 연결을 끊습니다."}]

[{"index":"boolean DisconnectEvent(Type eventType, EventHandlerBase eventHandler)","0":"타입이 eventType인 이벤트와 핸들러와의 연결을 끊습니다."}]

[{"index":"void SendEvent(EventType sendEvent)","0":"이벤트를 발생시킵니다."}]

# Events

[{"index":"ResourceUploadEvent","0":"월드 플레이 중 생성된 리소스 업로드에 성공했을 때 ResourceService에서 발생하는 이벤트입니다. 이 이벤트는 리소스가 업로드된 월드의 모든 서버에서 발생합니다."}]

# Examples

#### PreloadAsync

`PreloadAsync()` 함수를 이용하여 리소스 목록을 로드하고, 리소스 로드 중에는 로딩 화면을 보여주는 예제입니다. `ShowLoadingScreen()`,`HideLoadingScreen()` 함수 정의는 생략되었습니다.
    
    
    @Component
    script LoadingScreenPreloader extends Component
        @ExecSpace("ClientOnly")
        method void ResourceLoadWithLoadingScreen()
        -- 유저에게 로딩 화면을 보여줍니다. 
        self:ShowLoadingScreen()
    
        -- 로드할 리소스 목록입니다.
        local ruids = {
        	"6d1a308b27164b02921d812b05c78cba",
        	 "0516d7594a394561893e04de713cfb6a",
        	 "ce55606c96d94c059227f2956a1ae786",
        	 "b64e41d2e3774276aa7db7bdb74410b9",
        	 "df9ce4abd6e24a619e72e6f592a28ce7"
        }
    
        -- 리소스 목록 로드를 시작합니다. 로드가 완료되면 로딩 화면을 숨기는 콜백이 실행됩니다.
        _ResourceService:PreloadAsync(ruids, function()
    
         -- 로딩 화면을 숨깁니다. 
         	self:HideLoadingScreen()
        end)
        end
    end
    

#### SetSpriteUploadValidationCallback

`ResourceService`를 이용해 스크린샷을 스프라이트 리소스로 만들어 업로드하는 예제입니다. 유저가 스크린샷을 업로드 했을 때 업로드를 허용하는 함수를 먼저 만들어야 합니다. 업로드 허용 결정 함수는 월드가 생성될 때 등록되고 계속해서 유지되어야 하므로 Logic의 함수로 작성하는 것을 권장합니다. 한 업로드 허용 판단은 서버에서 진행되므로 함수 등록도 서버에서 수행되어야 합니다. 이 예제는 업로드 허가를 받은 유저인지 확인하고 허용 여부를 결정합니다.
    
    
    @Component
    script SpriteUploadValidator extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
        -- 스프라이트 업로드 허용 여부 결정 콜백을 등록합니다.
        _ResourceService:SetSpriteUploadValidationCallback(self.ValidateSpriteUpload)
        end
    
        @ExecSpace("ServerOnly")
        method boolean ValidateSpriteUpload(string userId)
        if self:IsAuthorizedUser(userId) == false then
        	-- 스프라이트 업로드를 막습니다.
        	return false
        end
    
        -- 스프라이트 업로드를 허용합니다.
        return true
        end
    end
    

클라이언트는 `ScreenshotService`를 이용해 스크린샷을 찍어 데이터화 하고, 이를 `ResourceService`를 통해 업로드해 스프라이트 리소스로 만듭니다.
    
    
    @Component
    script ScreenshotSpriteUploader extends Component
        @ExecSpace("ClientOnly")
        method void CaptureScreenshotAndUpload()
        -- 스크린샷을 찍어 데이터화합니다.
        local screenshotError, pixelData = _ScreenshotService:CaptureFullScreenAsPixelDataAndWait()
    
        -- 스크린샷을 찍는 과정에서 오류가 발생했는지 확인합니다.
        	if screenshotError ~= ScreenshotError.Success then
        	log_error("Failed to capture screenshot. error: " .. tostring(screenshotError))
        	return
        end
    
        -- 스크린샷 데이터를 업로드하여 스프라이트 리소스로 만듭니다.
        -- 업로드가 완료되면 콜백으로 지정한 OnScreenshotUploaded 함수가 호출됩니다.
        _ResourceService:RequestSpriteUploadAsync(pixelData, self.OnScreenshotUploaded)
        end
    
        @ExecSpace("ClientOnly")
        method void OnScreenshotUploaded(any resourceUploadError, string ruid)
        -- 스크린샷 업로드 과정에서 오류가 발생했는지 확인합니다.
        if resourceUploadError ~= ResourceUploadError.Success then
         	log_error("Failed to upload screenshot. error: " .. tostring(resourceUploadError))
        	return
        end
    
        -- 업로드에 성공했다면 스크린샷으로 만들어진 스프라이트 리소스의 RUID를 전달받습니다.
        -- 전달받은 RUID를 SpriteRendererComponent 에 지정하여 스프라이트를 확인합니다.
        self.Entity.SpriteRendererComponent.SpriteRUID = ruid
        end
    end
    

리소스 업로드에 성공했을 때 `ResourceService`에서 `ResourceUploadEvent`가 발생합니다. `ResourceUploadEvent`를 이용하여 리소스 업로드 시 서버에서 할 일을 지정할 수 있습니다. `ResourceUploadEvent`는 리소스가 업로드된 월드의 모든 서버에서 발생한다는 점 주의 바랍니다. 이 예제에서는 업로드된 리소스의 RUID와 업로드한 유저의 ID를 기록, 이후 플레이에서도 사용할 수 있도록 합니다. 예제와 같은 상황에서는 `UserId`에 해당하는 유저가 이 서버에 접속해 있는지 확인해 여러 서버에서 중복으로 기록되지 않도록 해야 합니다.
    
    
    @Component
    script ResourceUploadRegister extends Component
        @EventSender("Service", "ResourceService")
        handler HandleResourceUploadEvent(ResourceUploadEvent event)
        -- Parameters
        local RUID = event.RUID
        local UserId = event.UserId
        --------------------------------------------------------
    
        -- 리소스 업로드에 성공했을 때 서버에서 발생하는 이벤트입니다.
        local userEntity = _UserService:GetUserEntityByUserId(UserId)
    
        if _EntityService:IsValid(userEntity) then
        	self:RecordUploadedResource(RUID, UserId)
        end
        end
    end
    

#### GetTypeAndWait

리소스 타입을 확인하는 예제입니다.
    
    
    @Component
    script AssetTypeInitializer extends Component
        method void OnBeginPlay()
        -- sprite
        local type = _ResourceService:GetTypeAndWait('f55cd1b715c14593a97caff8b147d544')
        log(type)
    
        -- animationclip
        local type2 = _ResourceService:GetTypeAndWait('235ede11f6a24ecb85f6271833d06ba0')
        log(type2)
        end
    end
    

#### RemoveCaches

이전 리소스를 제거하고, 필요한 리소스를 불러오는 예제입니다.
    
    
    @Component
    script SkillResourceManager extends Component
        @ExecSpace("ClientOnly")
        method void UpgradeSkill(string id)
        -- 스킬의 제거 및 추가를 담당하는 함수들을 호출합니다.
        self:RemoveSkill(self.currentId)
        self.currentId = id
        self:AddSkill(self.currentId)
    
        local oldRuids = self.currentRuids
        -- 이전 스킬에서 사용하던 리소스들을 캐시에서 해제합니다.
        _ResourceService:RemoveCaches(oldRuids)
    
        -- 캐싱 되지 않고 사용하지도 않는 리소스들을 메모리에서 해제합니다.
        _ResourceService:UnloadUnusedResources(0)
    
        -- 로드 할 리소스 목록을 가지고 옵니다.
        local newRuids = self:GetRuids(id)
    
        self.currentRuids = newRuids
        self.currentId = id
    
        -- 리소스 목록 로드를 시작합니다. 로드가 완료되면 이후 동작을 담당하는 함수를 호출합니다.
        _ResourceService:PreloadAsync(newRuids, function()
        	self:AfterLoadSkillResource()
        end)
        end
    
        @ExecSpace("ClientOnly")
        method table GetRuids(string id)
        -- ruids 정보가 초기화되지 않은 경우 초기화합니다.
        if self.cachedRuidsById == nil then
        	self:InitializeRuids()
        end
    
        local ruids = self.cachedRuidsById[id]
        return ruids
        end
    end
    

#### ClearCaches

로비 맵으로 이동할 때 캐싱된 모든 리소스를 캐시에서 비우는 예제입니다.
    
    
    @Component
    script MapTransitionCacheClearer extends Component
        @ExecSpace("ClientOnly")
        method void BeforeMoveLobbyMap()
        -- 캐싱된 모든 리소스를 캐시에서 해제합니다.
        _ResourceService:ClearCaches()
    
        -- 맵 이동 시 UnloadUnusedResources()는 내부적으로 자동 호출됩니다.
        -- _ResourceService:UnloadUnusedResources(0)
        end
    end
    

# SeeAlso

  * SpriteRendererComponent
  * DataStorageService
  * ScreenshotService
  * [스크린샷과 동적 스프라이트](/docs?postId=829)