2013年5月26日 星期日

原生屬性定義語法

當你需要在UnrealScript類別中定義非UnrealScript型別的欄位時,就會需要使用原生屬性語法,當然你只能在原生類別中定義原生屬性。在此所謂的原生即指C++,也就是說可以使用C++型別來定義屬性。當然因為畢竟UnrealScript還是認不得這些型別,所以不能在UnrealScript中去呼叫這些原生屬性的C++函式,通常是透過原生函式來操作。

原生屬性定義大致上是利用大括號指定C++型別:
var native pointer property_name{ pointee_type };
先來看最簡單的例子:
var native pointer          pv;
上面pv的C++型別其實就是void*。
也可以在屬性名稱右邊加個大括號指定C++型別。例如:
var native pointer          pfile{FILE};
上面pfile的C++型別就會是FILE*。
另外pointer也可和array一起使用:
var native array<pointer>   FilePointerArray{FILE};
上面FilePointerArray的C++型別會是TArrayNoInit<FILE*>。

另一種比較通用的語法是:
var native script_type   property_name{ native_type };
script_type必須是一個UnrealScript認得的結構型別,而native_type則是實際在C++中的型別。例如:
var native Array_Mirror     ArrayOfArray{TArray< TArray<UBOOL> >};
上面ArrayOfArray的C++型別就會是TArray< TArray<UBOOL> >。本來UnrealScript是不支援陣列的陣列,不過像這樣就可以定義出來,只是因為在UnrealScript中看到的型別是Array_Mirror,所以還是不能在UnrealScript中操作它。

Array_Mirror的定義可在object.uc中找到,它的欄位定義和TArray呼應。
struct Array_Mirror
{
 // FScriptArray
 var native const pointer Data;
 var native const int  ArrayNum;
 var native const int  ArrayMax;
};
使用此原生屬性語法時必須確保script_type的大小native_type相符,編譯器並不會檢查。

其實前面提到的pointer在object.uc中也有定義:
struct pointer
{
 var native const int Dummy;
};
另外在object.uc中還可以找到許多XXX_Mirror結構,這些都是用來定義對應到某個C++型別的原生屬性用的。例如:
var const native Map_Mirror ClothTornTriMap {TMap<QWORD,INT>};

開發者也可自行定義UnrealScript結構型別來定義原生屬性,不過要注意C++建構子不會被呼叫,而且建立物件時欄位會歸零,所以不適用於有虛擬函式的C++類別。

UnrealScript雖然並不支援map,但是提供一個特別的語法給原生map:
var native map{ key_type, value_type } property_name
所以可以把上面的map定義換成下面這行是一樣的效果:
var const native map{QWORD,INT} ClothTornTriMap;

沒有留言:

張貼留言