Skip to content

Instantly share code, notes, and snippets.

@nlupugla
Created September 25, 2023 15:52
Show Gist options
  • Save nlupugla/f78a947f0f2d409a7ab7819d5d379a28 to your computer and use it in GitHub Desktop.
Save nlupugla/f78a947f0f2d409a7ab7819d5d379a28 to your computer and use it in GitHub Desktop.
Alternative proposal for Struct creation in Godot.
//// Under the current proposal, the workflow for exposing a struct would look like the following (using PropertyInfo as an example).
/// In Object.h, where PropertyInfo is defined
// Forward declare Struct template
template <typename T>
class Struct;
/// In Object.cpp
// Use STRUCT_LAYOUT macro to define a new struct called PropertyInfoLayout which simply serves type data about PropertyInfo.
STRUCT_LAYOUT(PropertyInfoLayout, "PropertyInfo",
STRUCT_MEMBER("name", Variant::STRING),
STRUCT_MEMBER("type", Variant::INT),
STRUCT_MEMBER("hint", Variant::INT),
STRUCT_MEMBER("hint_string", Variant::STRING),
STRUCT_MEMBER("class_name", Variant::STRING_NAME));
// Specialize the Struct<T> template to Struct<PropertyInfoLayout>, which is a child of Array that can access the type data stored in PropertyInfoLayout
template class Struct<PropertyInfoLayout>;
// Object's implementation remains mostly unchanged except for...
// Adding an extra line to _bind_methods
void Object::_bind_methods() {
// all previous binds plus...
BIND_STRUCT(PropertyInfoLayout); // registers the type data stored in PropertyInfoLayout with ClassDB
}
//// Here is a potential alternative.
/// In Object.h, modify the definition of PropertyInfo
struct PropertyInfo {
Variant::Type type = Variant::NIL;
String name;
StringName class_name; // For classes
PropertyHint hint = PROPERTY_HINT_NONE;
String hint_string;
uint32_t usage = PROPERTY_USAGE_DEFAULT;
// etc...
// An alternative STRUCT_LAYOUT macro (I'll call STRUCT_LAYOUT2 for now)
STRUCT_LAYOUT2("PropertyInfo",
STRUCT_MEMBER("name", Variant::STRING),
STRUCT_MEMBER("type", Variant::INT),
STRUCT_MEMBER("hint", Variant::INT),
STRUCT_MEMBER("hint_string", Variant::STRING),
STRUCT_MEMBER("class_name", Variant::STRING_NAME));
// Rather than creating a new struct called PropertyInfoLayout, this alternative approach implements
// static methods that return PropertyInfo's type data. It also implements methods to convert PropertyInfo
// to and from an Array.
}
/// In Object.cpp, we still need to BIND_STRUCT
void Object::_bind_methods() {
// all previous binds plus...
BIND_STRUCT(PropertyInfo); // registers the type data stored in PropertyInfo with ClassDB
}
//// I see this approach having a few potential advantages:
//// 1. Fewer classes defined (the second approach does not define a PropertyInfoLayout or a Struct<PropertyInfoLayout>)
//// 2. Easier workflow (most changes happen inside the body of PropertyInfo, not spread throughout the file)
//// 3. Exposing engine functions takes much less code (methods that take/return PropertyInfo can be exposed directly, so there is no need to write private adapter functions that take/return Struct<PropertyInfoLayout>)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment