这里记录程序线执行流程

一、pak资产挂载流程

目前有两个挂载入口:

0.1加载本地pak资产 /Game/Blueprints/UI/CoreUI/WPT_AssetLibraryMenu.WPT_AssetLibraryMenu蓝图中ConstructSkuClass函数调用void UCPT_UnitSkuButton::RequestMountPak(const FString& LocalPakPath)函数进行pak挂载请求;

0.2下载云端资产 void FCPT_AssetDownloadService::OnDownloadFinished函数中调用void UCPT_UnitSkuButton::RequestMountPak(const FString& LocalPakPath)函数进行pak挂载请求。

挂载委托关系梳理:

UCPT_UnitSkuButton类 有代理:OnMountPakRequested(声明:DECLARE_DELEGATE_TwoParams(FOnMountPakRequested, UCPT_UnitSkuButton*, const FString&);) 有函数: void UCPT_UnitSkuButton::RequestMountPak(const FString& LocalPakPath) { OnMountPakRequested.ExecuteIfBound(this, LocalPakPath); }

UCPT_AssetLibraryMenu类 有代理:DE_MountPakRequested(声明DECLARE_DELEGATE_TwoParams(FOnPakMountRequested, UCPT_UnitSkuButton*, const FString&)) 有函数: void UCPT_AssetLibraryMenu::RegisterSkuButton(UCPT_UnitSkuButton* Button) { Button->OnMountPakRequested.BindLambda([this](UCPT_UnitSkuButton* Btn, const FString& PakPath) { DE_MountPakRequested.ExecuteIfBound(Btn, PakPath); }); }

UCPT_MainUI类 在函数void UCPT_MainUI::LoadLocalAssets()中进行了绑定: LeftMenuBar->AssetLibraryMenu->DE_MountPakRequested.BindUObject(this, &UCPT_MainUI::HandlePakMountRequested);

流程如下: 1、首先会在函数void UCPT_MainUI::LoadLocalAssets()中绑定DE_MountPakRequested代理。

2、然后在构建资产缩略图按钮时会调用RegisterSkuButton注册代理。

请求挂载:RequestMountPak -> 由于在(2)中绑定了lambda函数,所以会执行DE_MountPakRequested -> 由于在(1)中绑定代理,所以最终执行:HandlePakMountRequested。

流程图/拓扑图

  1. 整体挂载流程拓扑图
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
┌─────────────────────────────────────────────────────────────────────────────┐
                          Pak 资产挂载流程总览                                
├─────────────────────────────────────────────────────────────────────────────┤
                                                                             
  入口A:启动时加载本地pak                  入口B:下载云端资产                   
  ┌─────────────────────┐                  ┌──────────────────────┐          
   UCPT_MainUI::                          UCPT_UnitSkuButton::           
   LoadLocalAssets()                      RequestDownload()              
  └─────────┬───────────┘                  └──────────┬───────────┘          
                                                                           
             读取本地清单                      入队下载                       
             manifest_cache.json              FCPT_AssetDownloadService     
                                            ::EnqueueDownload()             
                                                                           
                                           ┌─────────▼──────────┐           
                                            线程池异步下载                 
                                            ExecuteDownload()              
                                            (HTTP GET .pak文件)            
                                           └─────────┬──────────┘           
                                                                           
                                           下载完成回调                       
                                                                           
                                           ┌─────────▼──────────┐           
                                            OnDownloadFinished()           
                                            设置状态 Mounting              
                                           └─────────┬──────────┘           
                                                                           
               ┌─────────────────────────────────────┘                      
                两种路径在此汇合                                              
                                                                             
  ┌─────────────────────────┐                                                 
   UCPT_UnitSkuButton::                                                     
   RequestMountPak()                                                        
  └────────────┬────────────┘                                                 
                触发 OnMountPakRequested 委托                                 
                                                                              
  ┌─────────────────────────┐    lambda 转发    ┌────────────────────────┐    
   AssetLibraryMenu::       ──────────────►   DE_MountPakRequested       
   RegisterSkuButton()                        └───────────┬────────────┘    
  └─────────────────────────┘                                                
                                                             委托绑定        
                                                                             
  ┌──────────────────────────────────────────────────────────────────┐       
   UCPT_MainUI::HandlePakMountRequested(Button, LocalPakPath)             
  └───────────────────────────┬──────────────────────────────────────┘       
                                                                            
                                                                            
  ┌──────────────────────────────────────────────────────────────────┐       
           UCPT_MainUI::MountPakFiles()  (底层挂载核心)                   
    1. UPakLoaderLibrary::IsValidPakFile()   验证pak文件                   
    2. UPakLoaderLibrary::MountPakFile()     挂载pak文件                   
    3. RegisterMountPoint("/PTPakDLC/")      注册虚拟挂载点                
    4. LoadPakAssetRegistryFile()             加载资产注册表                
    5. GetFilesInPak()                        枚举pak内文件                
    6. 过滤 "Blueprints/Sku" 路径  得到 GameClassPath                    
  └───────────────────────────┬──────────────────────────────────────┘       
                                                                            
                                                                            
  ┌──────────────────────────────────────────────────────────────────┐       
   UCPT_UnitSkuButton::HandleMountComplete(bSuccess, GameClassPath)       
                                                                          
    成功时:                                                              
      1. 保存 EntryInfo.GameClassPath / bDownloaded = true                
      2. SetButtonState(Downloaded)                                       
      3. 持久化到 manifest_cache.json                                     
      4. CastBaseClass(GameClassPath) 通知蓝图设置基类路径                
                                                                          
    失败时:                                                              
      SetButtonState(NeedsUpdate)                                         
  └──────────────────────────────────────────────────────────────────┘       
                                                                             
└─────────────────────────────────────────────────────────────────────────────┘
  1. 委托链路图
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
SkuButton                          AssetLibraryMenu                    MainUI
──────────                         ─────────────────                   ───────

RequestMountPak()
      │ ExecuteIfBound
OnMountPakRequested ─────► [lambda 中转] ─────► DE_MountPakRequested ─────► HandlePakMountRequested()
                                                              │                   │
                                                              │  绑定时机:         │
                                                              │  LoadLocalAssets()  │
                                                              │  中 BindUObject     │
                                                                          MountPakFiles()
                                                                          HandleMountComplete()
  1. 资产按钮状态机
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
                    ┌────────────────┐
                      NotDownloaded  ◄──────────────────────────────────┐
                    └───────┬────────┘                                    
                             用户点击角标                                 
                                                                         
                    ┌────────────────┐                                    
                         Queued                                         
                    └───────┬────────┘                                    
                             线程池开始下载                                
                                                                         
                    ┌────────────────┐                                    
                       Downloading   ◄── UpdateDownloadProgress()       
                    └───────┬────────┘     更新下载进度                    
                             下载完成                                     
                                                                         
                    ┌────────────────┐                                    
                        Mounting                                        
                    └───────┬────────┘                                    
                      ┌─────┴─────┐                                       
                                                                        
                   成功│        失败│                                      
                                                                        
              ┌────────────┐ ┌──────────────┐                             
               Downloaded    NeedsUpdate  ──── 下载失败时回到 ─────────┘
              └────────────┘ └──────────────┘     OnDownloadFailed()