Types and Extensions¶
In this section we learn more about the relationship between types in KL and corresponding types in extensions.
The header file generated by kl2edk as well as the FabricEDK.h
header file it includes provide definitions for the built-in KL types, any types defined by the extension, and any types defined by other extensions required by the extension. All of these types are defined in the Fabric::EDK::KL
namespace.
注釈
For brevity, all types in this section will be referred to without the Fabirc::EDK::
namespace prefix as if the using namespace Fabric::EDK;
directive had been issued.
Simple Types¶
The simple types are all simply aliases for existing C++ types.
When a simple type is passed as an in
parameter from KL, the corresponding parameter in C++ should be a “pass-by-value”, ie. without the &
pass-by-reference symbol. Similarly, an extension function that returns a value that is a simple type should just return the value directly rather than use a “hidden return parameter”. See Calling Convention for Simple Types for more information about the calling convention for simple types.
KL::Boolean
The KLBoolean
type. You can assign the C++ constantstrue
andfalse
to expressions of this type.
KL::UInt8
, KL::SInt8
, KL::UInt16
, KL::SInt16
, KL::UInt32
, KL::SInt32
, KL::UInt64
, KL::SInt64
The KL integer types; equivalent to the KL types of the same name.
KL::Float32
, KL::Float64
The KL floating-point types; equivalent to the KL types of the same name.
KL::Byte
, KL::Integer
, KL::Index
, KL::Size
, KL::Scalar
KL built-in type aliases; they alias the same type as in the KL language.
KL::Data
The KLData
type. This is simply a type alias forvoid *
; however, there is aKL::DataWrapper
template provided byFabricEDK.h
that makes it much easier to work with these pointers; see The KL::DataWrapper<Ty> and KL::ConstDataWrapper<Ty> Templates for more information.
Equivalences for Simple Types¶
Since simple types are just aliases for preexisting C++ types, you can use corresponding C++ types in place of them wherever convenient. The following table shows equivalent C++ types for each KL simple type:
KL Type Equivalent C++ type(s) KL::Boolean
bool
KL::UInt8
uint8_t
,unsigned char
KL::UInt16
uint16_t
,unsigned short
KL::UInt32
uint32_t
,unsigned int
KL::UInt64
uint64_t
,unsigned long long
KL::SInt8
int8_t
,char
KL::SInt16
int16_t
,short
KL::SInt32
int32_t
,int
KL::SInt64
int64_t
,long long
KL::Float32
float
KL::Float64
double
The KL::DataWrapper<Ty>
and KL::ConstDataWrapper<Ty>
Templates¶
In order to simplify use of the KL::Data
type, FabricEDK.h
provides the templates KL::DataWrapper<Ty>
KL::ConstDataWrapper<Ty>
that allows you to treat a value of type KL::Data
as if it were a pointer to a more complex type. KL::DataWrapper<Ty>
allows modification of the resulting complex type whereas KL::ConstDataWrapper<Ty>
allows it only to be read. The best explanation is through an example:
struct SomeMoreComplexStruct {
InternalValue value;
// ....
};
FABRIC_EDK_EXPORT void MyFunc( Fabric::EDK::KL::Data::IOParam data )
{
Fabric::EDK::KL::DataWrapper<SomeMoreComplexStruct> complexStruct( data );
if ( !complexStruct ) {
// Note that this assignment actually changes the referenced
complexStruct = new SomeMoreComplexStruct;
complexStruct->value = // ... whatever
}
}
Complex Types¶
The complex types do not correspond directly to an existing C++ type, but instead have a complex representation as a C++ class or template in header file generated by kl2edk or the FabricEDK.h
header file.
Complex types must always be passed by reference in C++ functions corresponding to KL functions, even when they are in
parameters in KL; similarly, they must always be returned through a “hidden return parameter”. This is usually done using the ::INParam
and ::Result
typedefs. For more information, see Calling Convention for Complex Types.
警告
Unlike KL (in guarded mode), there are generally no checks for array indices or other lookups when using complex types. It is the responsibility of the programmer to ensure that these operations are within bounds.
KL::String
¶
Provides the functionality of the KL String
type. It supports the usual empty constructor, copy constructor, and assignment operator, as well as following methods:
-
const char *
KL::String::
c_str
() const¶ Returns the string contents as a C-style null-terminated string.
-
const char *
KL::String::
data
() const¶ Returns the string contents as a raw pointer to character data.
-
uint32_t
KL::String::
length
() const¶ Returns the string contents as a raw pointer to character data.
-
void
KL::String::
append
(char ch)¶ Appends a character to the string.
-
void
KL::String::
operator+=
(char ch)¶ Alias for
void KL::String::append(char ch)
.
-
void
KL::String::
append
(char const *data, uint32_t length)¶ Appends another string given as a raw character pointer and a length.
-
void
KL::String::
append
(char const *cStr)¶ Appends another string given as a C-style null-terminate string.
-
void
KL::String::
operator+=
(char const *cStr)¶ Alias for
void KL::String::append(char const *cStr)
.
-
void
KL::String::
append
(KL::String const &that)¶ Appends another
KL::String
.
-
void
KL::String::
operator+=
(KL::String const &that)¶ Alias for
void KL::String::append(KL::String const &that)
.
KL::VariableArray<Ty>
¶
Provides the functionality of a variable array of the type Ty
, which must itself be a KL type. It supports an empty constructor that constructs an empty array, a copy constructor and assignment operator that take a reference to the contents of the other array, as well as the following methods:
-
template<>
uint32_tKL::VariableArray<Ty>::
size
() const¶ Returns the size (length) of the array.
-
template<>
voidKL::VariableArray<Ty>::
resize
(uint32_t newSize)¶ Resize the array. The new elements (if any) will be initialized using the constructor for the given type.
-
template<>
voidKL::VariableArray<Ty>::
push_back
(Ty const &t)¶ Append an element to the end of the array
-
template<>
Ty const &KL::VariableArray<Ty>::
operator[]
(uint32_t index) const¶ The read-only array indexing operator.
-
template<>
Ty &KL::VariableArray<Ty>::
operator[]
(uint32_t index)¶ The read-write array indexing operator. It returns a modifiable reference to the given element of the array.
注釈
Unlike KL, there is no checks for array indices when indexing into an array. It is the responsibility of the programmer to ensure that the array index is within bounds.
注釈
References returned from the array indexing operators should be considered temporary and should not be stored in other variables. Calling the resize
method on a variable array may cause references to become invalid.
KL::FixedArray<Ty, size>
¶
Provides the functionality of a KL fixed array of the type Ty
, which must itself be a KL type, of size :samp:{size} which must be an unsigned integer. It proves the usual empty and copy constructors and assignment operators. It provides the following specialized constructors and methods:
-
template<>
Ty const &KL::ExternalArray<Ty>::
operator[]
(uint32_t index) const¶ The read-only array indexing operator.
-
template<>
Ty &KL::ExternalArray<Ty>::
operator[]
(uint32_t index)¶ The read-write array indexing operator. It returns a modifiable reference to the given element of the array.
KL::ExternalArray<Ty>
¶
Provides the functionality of a external array of the type Ty
, which must itself be a KL built-in or user-defined type. It allows you to construct a new array from a raw pointer and element count, along with the usual empty and copy constructors and assignment operators. It provides the following specialized constructors and methods:
-
KL::ExternalArray<Ty>
ExternalArray
(Ty *members, uint32_t size)¶ Constructs a new external array from a raw pointer and a size (element count). The external array does not take ownership of the data; it is the responsibility of the extension author to manage the lifecycle of the underlying data and to ensure that it outlives any use of the data anywhere in Fabric Engine.
-
template<>
uint32_tKL::ExternalArray<Ty>::
size
() const¶ Returns the size (length) of the array.
-
template<>
Ty const &KL::ExternalArray<Ty>::
operator[]
(uint32_t index) const The read-only array indexing operator.
-
template<>
Ty &KL::ExternalArray<Ty>::
operator[]
(uint32_t index) The read-write array indexing operator. It returns a modifiable reference to the given element of the array.
警告
Unlike KL, there is no checks for array indices when indexing into an array. It is the responsibility of the programmer to ensure that the array index is within bounds.
KL::Dict<KeyTy, ValueTy>`
¶
Provides the functionality of a dictionary that maps keys of type KeyTy
to values of type ValueTy
. KeyTy
must be either a simple type or KL::String
; ValueTy
can be any KL type. It supports an empty constructor that constructs an empty dictionary, a copy constructor and assignment operator that take a reference to the contents of the other dictionary, as well as the following methods:
-
template<>
uint32_tKL::Dict<KeyTy, ValueTy>::
size
() const¶ Returns the size (length) of the array.
-
template<>
boolKL::Dict<KeyTy, ValueTy>::
has
(KeyTy const &key)¶ Returns
true
if and only if there is a value for the given key in the dictionary.
-
template<>
ValueTy const &KL::Dict<KeyTy, ValueTy>::
operator[]
(KeyTy const &key) const¶ The read-only dictionary indexing operator. If there is no value for the given key in the dictionary an exception is thrown.
-
template<>
ValueTy const *KL::Dict<KeyTy, ValueTy>::
maybeGet
(KeyTy const &key)¶ Get a pointer to the value corresponding to the given key. If there is no value for the given key, this method returns
0
.
-
template<>
ValueTy &KL::Dict<KeyTy, ValueTy>::
operator[]
(KeyTy const &key)¶ The read-write array indexing operator. It returns a mutable (read-write) reference to the value for the key in the dictionary. If there is no value for the key, a new value is created for the key. The initial value of the new value is the default value for
ValueTy
.
-
template<>
ValueTy &KL::Dict<KeyTy, ValueTy>::
get
(KeyTy const &key, ValueTy const &defaultValue)¶ Get the value for the given key from the dictionary, returning an mutable (read-write) reference to the value. If there is no value for the key, a new value is created whose value is
defaultValue
.
注釈
References returned from the array indexing operators should be considered temporary and should not be stored in other variables. Methods that potential modify the dictionary can cause the references to become invalid, leading to programming errors.
-
template<>
KL::Dict<KeyTy, ValueTy>::iteratorKL::Dict<KeyTy, ValueTy>::
begin
()¶ -
template<>
KL::Dict<KeyTy, ValueTy>::iteratorKL::Dict<KeyTy, ValueTy>::
end
()¶ -
template<>
KL::Dict<KeyTy, ValueTy>::const_iteratorKL::Dict<KeyTy, ValueTy>::
begin
() const¶ -
template<>
KL::Dict<KeyTy, ValueTy>::const_iteratorKL::Dict<KeyTy, ValueTy>::
end
() const¶ The iteration interface for dictionaries. Please refer to the
EDKDicts.cpp
example in the$FABRIC_DIR/Samples/EDK/EDKDicts
folder for an example of dictionary iteration in the EDK.
KL::Object
¶
The KL::Object
type is the equivalent of the KL Object
type that refers to an arbitrary object. It supports an empty constructor (which constructs a null object reference), a copy constructor and an assignment operator (taking a reference to the other object) as well as the ==
and !=
comparison operators.
User-Defined Types¶
The KL struct
, interface
and object
types are user-defined types. They may be defined by the KL source files of the extension or one of the other extensions that the extension requires.
User-defined types have C++ equivalents defined for them in the header generated by the kl2edk tool. The following section detail usage of these C++ equivalent types.
Structures¶
KL structures (defined using the KL struct
keyword) are be directly represented by C++ structures. Each member of the KL structure is provided as a structure member in C++ with exactly the corresponding C++ type. You can therefore reference the members of an instance of the structure using the usual .
operation, as well as performing all the other usual C++ structure operations.
Mapping KL Structures to Third-Party API Structures¶
Since the generated C++ KL structure maps directly to a plain C++ structure with the KL types for its members, it is possible to pointer-cast the KL structure to another structure using the reinterpret_cast
operator in C++. However, you must ensure the following about the target structure:
- The structure must only contain simple KL types or other structures containing simple KL types. For a list of C++ types equivalent to the simple KL types, see Equivalences for Simple Types.
- The order of the members in the structure must be exactly the same in KL and in C++
- The structure must use the default C++ alignment for the structure and its members.
Interfaces¶
For each interface defined in the KL code there will be a C++ equivalent with the same name defined in the generated header.
In the C++ class generated for the interface the methods of the interface are provided through the interface.methodName(arg, arg, ...)
call.
Additionally, the C++ class provides:
- An empty constructor that constructs a null interface reference
- A copy constructor and an assignment operator that copy a reference to the other interface
- The
==
and!=
comparison operators that compare for interfaces to point to the same object - A conversion to the C++ type
bool
as well as theoperator !
that can be used for checks for the interface reference being non-null or null
For example:
// KL code
interface MyInt {
Float32 foo();
};
function callIntMethod(MyInt myInt) = "CallIntMethod";
then the corresponding C++ definition for CallIntMethod
should be:
// C++ code
FABRIC_EXT_EXPORT void CallIntMethod(
Fabric::EDK::KL::myInt::INParam myInt
)
{
Fabric::EDK::KL::Float32 result = myInt.foo();
Fabric::EDK::report("myInt.foo() returned %f", result);
}
Objects¶
For each object defined in the KL code there will be a C++ equivalent with the same name defined in the generated header.
The members of the object are accessed through the object->memberName
operation. All of the members of the KL structure are provided through this operation.
The methods of the object that belong to an interface that the object implements are provided through the object.methodName(arg, arg, ...)
call.
注釈
There is currently no way to call methods on the object that are not part of an implemented interface.
- An empty constructor that constructs a null object reference
- A static method
objectType::Create()
constructs a new Object of typeobjectType
and returns a reference to it - A copy constructor and an assignment operator that copy a reference to the other object
- The
==
and!=
comparison operators that compare for objects to point to the same object - A conversion to the C++ type
bool
as well as theoperator !
that can be used for checks for the object reference being non-null or null
For example:
// KL code
interface MyInt {
Float32 foo();
};
object MyObj : MyInt {
Byte b;
String s;
};
function displayObjectMembers(MyObj myObj) = "DisplayObjectMembers";
then the corresponding C++ definition for DisplayObjectMembers
should be:
// C++ code
FABRIC_EXT_EXPORT void DisplayObjectMembers(
Fabric::EDK::KL::MyObj::INParam myObj
)
{
Fabric::EDK::report(
"myObj.b=%u myObj.s=%s",
unsigned(myObj->b),
myObj->s.c_str()
);
Fabric::EDK::KL::Float32 result = myObj.foo();
Fabric::EDK::report("myObj.foo() returned %f", result);
}
Refer to the EDKObjects sample located in $FABRIC_DIR/Samples/EDK/EDKObjects
for a detailed example of exposing object functionality using the EDK.