【UnLua】ModuleLocator改造-創(chuàng)新互聯(lián)

【UnLua】Module Locator 改造

看起來簡單的東西,UnLua 做的不是很完備,實際項目使用時藏了一些坑,之前沒怎么上心,斷斷續(xù)續(xù)改,總還是有問題 ,今天徹底解決這個問題

創(chuàng)新互聯(lián)自2013年創(chuàng)立以來,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目成都網(wǎng)站設計、成都網(wǎng)站建設網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元棲霞做網(wǎng)站,已為上家服務,為棲霞各地企業(yè)和個人服務,聯(lián)系電話:13518219792Module Locator 是什么

Lua 接入引擎后一般需要 C++ 重寫 require

  • 比如調(diào)用引擎的資源管理器去加載 Lua 腳本文件(可以加密,壓縮)
  • 比如定制文件路徑 resolve 規(guī)則(可以 fallback 查找)

UnLua 提供了一個基類ULuaModuleLocator,有Locate接口返回 Lua 路徑

UCLASS()
class UNLUA_API ULuaModuleLocator : public UObject
{GENERATED_BODY()
public:
	// 定位 Object 對應的 Lua 文件路徑
    virtual FString Locate(const UObject* Object);
};

默認實現(xiàn)長這樣,返回UObject->Class->CDO->GetModuleName(),即一個 Object 的 UClass 實現(xiàn)了 UnLuaInterface,就綁定了Lua,運行時會去加載GetModuleName返回的 Lua 文件路徑

FString ULuaModuleLocator::Locate(const UObject* Object)
{const UObject* CDO;
    if (Object->HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
    {CDO = Object;
    }
    else
    {const auto Class = Cast(Object);
        CDO = Class ? Class->GetDefaultObject() : Object->GetClass()->GetDefaultObject();
    }

    if (CDO->HasAnyFlags(RF_NeedInitialization))
    {// CDO還沒有初始化完成
        return "";
    }

    if (!CDO->GetClass()->ImplementsInterface(UUnLuaInterface::StaticClass()))
    {return "";
    }

    return IUnLuaInterface::Execute_GetModuleName(CDO);
}

LyraWithUnLua Demo 里提供了一個實現(xiàn)ULyraLuaModuleLocator,核心是藍圖類使用藍圖資源路徑,自動生成 Lua 路徑

// 2. if this is blueprint, fallback to generate name by asset path
//	  NOTE will try to remove prefix W_, UI_, GA_
if (ModuleName.IsEmpty() && !Class->IsNative()  && !CheckSuperModuleName())
{// 藍圖類使用資源路徑
	ModuleName = Class->GetPackage()->GetName();
	ModuleName = ModuleName.Replace(TEXT("/"), TEXT("."));

	TArrayParts;
	ModuleName.ParseIntoArray(Parts, TEXT("."));
	if (Parts.Num() >0)
	{auto& LastPart = Parts[Parts.Num() - 1];
		int32 Index = 0;
		if (LastPart.FindChar('_', Index) && Index< 4)
		{	LastPart.RightChopInline(Index + 1);
		}
		ModuleName = FString::Join(Parts, TEXT("."));
	}
}
問題

ULyraLuaModuleLocator一開始很方便,但是這個接口設計犯了一個錯,就是一個接口干了兩個接口的活,導致用這個接口怎么也干不好,參考realloc,同時干mallocfree兩件事

ULyraLuaModuleLocator的問題在于,藍圖類構造了繼承鏈之后

這里用 C++ 代表 藍圖代碼

在基類上綁定 Lua,預期是只有基類綁定了 Lua,但是實際是派生類 也自動綁定了 Lua,運行時會找不到 Lua 文件,然后報錯

class BP_A : UnLuaInterface {GetModuleName =>"BP_A"; }
class BP_B : BP_A {GetModuleName =>""; }  // 派生,沒綁Lua
class BP_C_DataOnly : BP_B {GetModuleName =>""; }  // 派生,沒綁Lua
class BP_A : UnLuaInterface {GetModuleName =>"BP_A"; 
	virtual
}
class BP_B : BP_A {GetModuleName =>""; }  // 派生,沒綁Lua
class BP_C_DataOnly : BP_B {GetModuleName =>""; }  // 派生,沒綁Lua
解決

分兩個接口來做

  • 額外加一個按鈕自動填充 GetModuleName 路徑,使用ULyraLuaModuleLocator,只有這個按鈕會走這里
  • 運行時,編輯器跑ULuaModuleLocator,簡單,穩(wěn)定,快速
繼承相關的問題

【UnLua】Super 繼承和 override_zoloypzuo的博客-博客

這篇文章中,我們仔細討論了繼承的情況,建議閱讀,兩篇文章有關聯(lián)

小結

主要是編程上的注意

  • 分離 Editor 和 Runtime 行為
  • 一個接口只做一件事,不要同時負責寫入+讀取
  • Runtime 行為保持簡單,確定性,不要有潛規(guī)則,難以調(diào)試,容易隱藏問題

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

新聞標題:【UnLua】ModuleLocator改造-創(chuàng)新互聯(lián)
新聞來源:http://muchs.cn/article30/cdsiso.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供響應式網(wǎng)站、建站公司App開發(fā)、自適應網(wǎng)站網(wǎng)站改版、云服務器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設