配置讀取流程
配置讀取的本質就是把xml文件中的數據讀取到程序中定義的數據結構中去。
開始讀取配置
首先要提醒的是,在讀取的過程中,我們必須做嚴格的檢查,對讀取失敗的情況給出易讀的說明。通常情況,讀取失敗意味着進程終止。
當程序啓動後,首先要做的事情就是加載配置,遊戲中的代碼硬編碼配置較少,大部分都是通過配置文件來動態獲取的。
配置之間也會有依賴關係,比如大部分的邏輯配置都依賴於物品配置,解決依賴的辦法就是讓物品配置先於邏輯配置加載。在World::InitGameWorld
方法中就是全部遊戲配置的加載步驟,其調用順序是:
ServerLogic::Start
World::Start
World::InitGameWorld
...
LogicConfigManager::Init
yourconfig::Init // 你自己要實現的配置
我們大部分的配置都屬於邏輯配置,它們被統一放在了(LogicConfigManager)裏面管理。
定義配置結構體
我們需要把配置表的內容抽象成代碼中數據結構。我們的配置表就是一張行列二維表,因此用數組抽象是最合適的。
比如,有這樣的配置結構:
cs | cs | cs | cs | cs |
---|---|---|---|---|
寵物id | 激活所需物品 | 攻擊 | 防禦 | 血量 |
id | active_item_id | gongji | fangyu | maxhp |
0 | 26000 | 100 | 100 | 100 |
1 | 26001 | 200 | 200 | 200 |
2 | 26002 | 300 | 300 | 300 |
前兩行是說明,真正有效的內容從第三行開始。cs代表配置內容生成到客戶端(c)和服務端(s),中文的說明是給策劃看的。
我們可以用這樣的數據結構來抽象這個配置:
struct PetConfigItem
{
PetConfigItem():
id(0),
active_item_id(),
gongji(0), fangyu(0),
maxhp(0){}
int id; // 寵物id
ItemID active_item_id; // 激活所需物品
int gongji; // 攻擊
int fangyu; // 防禦
int maxhp; // 血量
};
static const int MAX_PET_COUNT = 8;
PetConfigItem m_petconfig_list[MAX_PET_COUNT]; // 寵物配置
提供獲取配置的接口
配置讀取完畢後,必須提供一個接口訪問配置內容。這個接口的返回值必須是一個const指針(或引用)。
比如要獲取一個寵物配置項,可以這樣編寫接口:
inline bool IsValidPetID(int id)
{
// 保證是合法的、不會導致數組越界的id
// ...
}
const PetConfigItem* GetPetConfigItem(int id)
{
if (IsValidPetID(id))
{
return &m_petconfig_list[id];
}
return nullptr;
}
在實際編程中,建議把這樣有關數組下標判斷的工作放到一個簡單的inline函數中去。因爲你可能在許多地方要做這樣的判斷工作,而且一旦出現錯誤,後果非常嚴重。