Skip to content

Commit

Permalink
Added doc gen for structs.
Browse files Browse the repository at this point in the history
  • Loading branch information
nlupugla committed Sep 18, 2024
1 parent 6007b71 commit 5701057
Show file tree
Hide file tree
Showing 16 changed files with 685 additions and 281 deletions.
2 changes: 2 additions & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,8 @@ if env.msvc and not methods.using_clang(env): # MSVC
]
)

env.Append(CCFLAGS=["/permissive-"])

if env["werror"]:
env.Append(CCFLAGS=["/WX"])
env.Append(LINKFLAGS=["/WX"])
Expand Down
24 changes: 24 additions & 0 deletions core/doc_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,30 @@ void DocData::property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_propert
p_property.overridden = false;
}

void DocData::struct_doc_from_structinfo(DocData::StructDoc &p_struct, const StructInfo &p_structinfo) {
p_struct.name = p_structinfo.name;
// TODO: what about description?

p_struct.properties.resize(p_structinfo.count);
for (int i = 0; i < p_structinfo.count; i++) {
PropertyDoc property_doc;
property_doc.name = p_structinfo.names[i];
Variant::Type type = p_structinfo.types[i];
if (type == Variant::OBJECT) {
property_doc.type = p_structinfo.class_names[i];
} else if (type == Variant::NIL) {
property_doc.type = "Variant";
} else {
property_doc.type = Variant::get_type_name(type);
}
if (type != Variant::OBJECT) {
property_doc.default_value = get_default_value_string(p_structinfo.default_values[i]);
}
// TODO: what about description?
p_struct.properties.write[i] = property_doc;
}
}

void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc) {
p_method.name = p_methodinfo.name;
p_method.description = p_desc;
Expand Down
78 changes: 78 additions & 0 deletions core/doc_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -698,6 +698,67 @@ class DocData {
}
};

struct StructDoc {
String name;
String description;
Vector<PropertyDoc> properties;
bool is_deprecated = false;
bool is_experimental = false;
bool operator<(const StructDoc &p_struct) const {
return name < p_struct.name;
}
static StructDoc from_dict(const Dictionary &p_dict) {
StructDoc doc;

if (p_dict.has("name")) {
doc.name = p_dict["name"];
}

if (p_dict.has("description")) {
doc.description = p_dict["description"];
}

Array properties;
if (p_dict.has("properties")) {
properties = p_dict["properties"];
}
for (int i = 0; i < properties.size(); i++) {
doc.properties.push_back(PropertyDoc::from_dict(properties[i]));
}

if (p_dict.has("is_experimental")) {
doc.is_experimental = p_dict["is_experimental"];
}

return doc;
}
static Dictionary to_dict(const StructDoc &p_doc) {
Dictionary dict;

if (!p_doc.name.is_empty()) {
dict["name"] = p_doc.name;
}

if (!p_doc.description.is_empty()) {
dict["description"] = p_doc.description;
}

if (!p_doc.properties.is_empty()) {
Array properties;
for (int i = 0; i < p_doc.properties.size(); i++) {
properties.push_back(PropertyDoc::to_dict(p_doc.properties[i]));
}
dict["properties"] = properties;
}

dict["is_deprecated"] = p_doc.is_deprecated;

dict["is_experimental"] = p_doc.is_experimental;

return dict;
}
};

struct ClassDoc {
String name;
String inherits;
Expand All @@ -713,6 +774,7 @@ class DocData {
HashMap<String, EnumDoc> enums;
Vector<PropertyDoc> properties;
Vector<MethodDoc> annotations;
Vector<StructDoc> structs;
Vector<ThemeItemDoc> theme_properties;
bool is_deprecated = false;
String deprecated_message;
Expand Down Expand Up @@ -818,6 +880,14 @@ class DocData {
doc.annotations.push_back(MethodDoc::from_dict(annotations[i]));
}

Array structs;
if (p_dict.has("structs")) {
structs = p_dict["structs"];
}
for (int i = 0; i < structs.size(); i++) {
doc.structs.push_back(StructDoc::from_dict(structs[i]));
}

Array theme_properties;
if (p_dict.has("theme_properties")) {
theme_properties = p_dict["theme_properties"];
Expand Down Expand Up @@ -947,6 +1017,13 @@ class DocData {
dict["annotations"] = annotations;
}

if (!p_doc.structs.is_empty()) {
Array structs;
for (int i = 0; i < p_doc.structs.size(); i++) {
structs.push_back(StructDoc::to_dict(p_doc.structs[i]));
}
}

if (!p_doc.theme_properties.is_empty()) {
Array theme_properties;
for (int i = 0; i < p_doc.theme_properties.size(); i++) {
Expand Down Expand Up @@ -982,6 +1059,7 @@ class DocData {
static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo);
static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo);
static void property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo);
static void struct_doc_from_structinfo(DocData::StructDoc &p_struct, const StructInfo &p_structinfo);
static void method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc);
static void constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc);
static void signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc);
Expand Down
8 changes: 4 additions & 4 deletions core/object/method_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,16 @@ MethodInfo MethodInfo::from_dict(const Dictionary &p_dict) {
args = p_dict["args"];
}

for (int i = 0; i < args.size(); i++) {
Dictionary d = args[i];
for (const Variant &arg : args) {
Dictionary d = arg;
mi.arguments.push_back(PropertyInfo::from_dict(d));
}
Array defargs;
if (p_dict.has("default_args")) {
defargs = p_dict["default_args"];
}
for (int i = 0; i < defargs.size(); i++) {
mi.default_arguments.push_back(defargs[i]);
for (const Variant &defarg : defargs) {
mi.default_arguments.push_back(defarg);
}

if (p_dict.has("return")) {
Expand Down
2 changes: 1 addition & 1 deletion core/object/object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1597,7 +1597,7 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_meta_list"), &Object::_get_meta_list_bind);

ClassDB::bind_method(D_METHOD("add_user_signal", "signal", "arguments"), &Object::_add_user_signal, DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("add_user_signal_as_struct", "signal"), &Object::_add_user_signal_as_struct, DEFVAL(Struct<MethodInfo>()));
ClassDB::bind_method(D_METHOD("add_user_signal_as_struct", "signal"), &Object::_add_user_signal_as_struct);
ClassDB::bind_method(D_METHOD("has_user_signal", "signal"), &Object::_has_user_signal);
ClassDB::bind_method(D_METHOD("remove_user_signal", "signal"), &Object::_remove_user_signal);

Expand Down
6 changes: 0 additions & 6 deletions core/variant/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1045,12 +1045,6 @@ Array::Array(const StructInfo &p_struct_info, bool is_array_of_structs) {
}
}

Array::Array(const Vector<Variant> &p_vec) {
_p = memnew(ArrayPrivate);
_p->refcount.init();
_p->array = p_vec; // TODO: is this right? Do I need to copy?
}

Array::Array() {
_p = memnew(ArrayPrivate);
_p->refcount.init();
Expand Down
1 change: 0 additions & 1 deletion core/variant/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,6 @@ class Array {
Array(const Array &p_from, const StructInfo &p_struct_info);
Array(const Dictionary &p_from, const StructInfo &p_struct_info);
Array(const StructInfo &p_struct_info, bool p_is_array_of_structs = false);
Array(const Vector<Variant> &p_vec);
Array();
~Array();
};
Expand Down
14 changes: 7 additions & 7 deletions core/variant/struct_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,27 @@ class Struct;
#define STRUCT_DECLARE(m_struct_name) using StructType = m_struct_name

#define STRUCT_MEMBER_TYPEDEF_ALIAS(m_type, m_member_name, m_member_name_alias, m_default) \
using Type = m_type; \
_FORCE_INLINE_ static const StringName get_name() { return SNAME(m_member_name_alias); } \
_FORCE_INLINE_ static Variant get_variant(const StructType &p_struct) { return to_variant(p_struct.m_member_name); } \
_FORCE_INLINE_ static const Variant get_default_value_variant() { return to_variant(m_default); } \
_FORCE_INLINE_ static m_type get(const StructType &p_struct) { return p_struct.m_member_name; } \
_FORCE_INLINE_ static m_type get_default_value() { return m_default; } \
_FORCE_INLINE_ static Type get(const StructType &p_struct) { return p_struct.m_member_name; } \
_FORCE_INLINE_ static Type get_default_value() { return m_default; } \
_FORCE_INLINE_ static void set_variant(StructType &p_struct, const Variant &p_variant) { p_struct.m_member_name = from_variant(p_variant); } \
_FORCE_INLINE_ static void set(StructType &p_struct, const m_type &p_value) { p_struct.m_member_name = p_value; } \
using Type = m_type
_FORCE_INLINE_ static void set(StructType &p_struct, const m_type &p_value) { p_struct.m_member_name = p_value; }

#define STRUCT_MEMBER_TYPEDEF(m_type, m_member_name, m_default) \
STRUCT_MEMBER_TYPEDEF_ALIAS(m_type, m_member_name, #m_member_name, m_default)

#define STRUCT_MEMBER_TYPEDEF_POINTER(m_type, m_member_name, m_default) \
using Type = m_type *; \
_FORCE_INLINE_ static const StringName get_name() { return SNAME(#m_member_name); } \
_FORCE_INLINE_ static Variant get_variant(const StructType &p_struct) { return to_variant(p_struct.m_member_name); } \
_FORCE_INLINE_ static const Variant get_default_value_variant() { return to_variant(m_default); } \
_FORCE_INLINE_ static m_type *get(const StructType &p_struct) { return p_struct.m_member_name; } \
_FORCE_INLINE_ static Type get(const StructType &p_struct) { return p_struct.m_member_name; } \
_FORCE_INLINE_ static const m_type *get_default_value() { return m_default; } \
_FORCE_INLINE_ static void set_variant(StructType &p_struct, const Variant &p_variant) { p_struct.m_member_name = from_variant(p_variant); } \
_FORCE_INLINE_ static void set(StructType &p_struct, m_type *p_value) { p_struct.m_member_name = p_value; } \
using Type = m_type *
_FORCE_INLINE_ static void set(StructType &p_struct, Type p_value) { p_struct.m_member_name = p_value; }

#define STRUCT_MEMBER_PRIMITIVE_ALIAS(m_type, m_member_name, m_member_name_alias, m_default) \
m_type m_member_name = m_default; \
Expand Down
2 changes: 1 addition & 1 deletion core/variant/typed_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class TypedArray<Struct<T>> : public Array {
}
_FORCE_INLINE_ TypedArray(const List<T> *p_list) {
initialize_struct_type(T::get_struct_info(), true);
for (const List<T>::Element *E = p_list->front(); E; E = E->next()) {
for (const typename List<T>::Element *E = p_list->front(); E; E = E->next()) {
push_back(Struct<T>(E->get()));
}
}
Expand Down
1 change: 1 addition & 0 deletions core/variant/variant_setget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
}
break;
}
[[fallthrough]];
}
default: {
List<StringName> members;
Expand Down
31 changes: 31 additions & 0 deletions doc/class.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,37 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="structs" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="struct" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="member" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute type="xs:string" name="name" use="required"/>
<xs:attribute type="xs:string" name="type" use="required"/>
<xs:attribute type="xs:string" name="default" use="required"/>
<xs:attribute type="xs:string" name="enum" use="optional" />
<xs:attribute type="xs:boolean" name="is_bitfield" use="optional" />
<xs:attribute type="xs:boolean" name="is_deprecated" use="optional" />
<xs:attribute type="xs:boolean" name="is_experimental" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element type="xs:string" name="description" minOccurs="0"/>
</xs:sequence>
<xs:attribute type="xs:string" name="name" use="required"/>
<xs:attribute type="xs:boolean" name="is_deprecated" use="optional" />
<xs:attribute type="xs:boolean" name="is_experimental" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="annotations" minOccurs="0">
<xs:complexType>
<xs:sequence>
Expand Down
25 changes: 25 additions & 0 deletions doc/classes/Object.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1138,4 +1138,29 @@
Reference-counted connections can be assigned to the same [Callable] multiple times. Each disconnection decreases the internal counter. The signal fully disconnects only when the counter reaches 0.
</constant>
</constants>
<structs>
<struct name="Object.PropertyInfo">
<member name="name" type="String" default="&quot;&quot;"/>
<member name="class_name" type="StringName" default="&amp;&quot;&quot;"/>
<member name="type" type="int" default="0"/>
<member name="hint" type="int" default="0"/>
<member name="hint_string" type="String" default="&quot;&quot;"/>
<member name="usage" type="int" default="6"/>
</struct>
<struct name="Object.MethodInfo">
<member name="name" type="String" default="&quot;&quot;"/>
<member name="args" type="Array" default="[]"/>
<member name="default_args" type="Array" default="[]"/>
<member name="flags" type="int" default="1"/>
<member name="id" type="int" default="0"/>
<member name="return" type="Array" default="[&quot;&quot;, &amp;&quot;&quot;, 0, 0, &quot;&quot;, 6]"/>
<member name="return_val_metadata" type="int" default="0"/>
<member name="arguments_metadata" type="PackedInt32Array" default="PackedInt32Array()"/>
</struct>
<struct name="Object.Connection">
<member name="signal" type="Signal" default="Signal()"/>
<member name="callable" type="Callable" default="Callable()"/>
<member name="flags" type="int" default="0"/>
</struct>
</structs>
</class>
9 changes: 6 additions & 3 deletions doc/tools/doc_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"description",
"methods",
"constants",
"structs",
"members",
"theme_items",
"signals",
Expand All @@ -78,6 +79,7 @@
"Desc.",
"Methods",
"Constants",
"Structs",
"Members",
"Theme Items",
"Signals",
Expand Down Expand Up @@ -191,6 +193,7 @@ def __init__(self, name: str = ""):
self.progresses: Dict[str, ClassStatusProgress] = {
"methods": ClassStatusProgress(),
"constants": ClassStatusProgress(),
"structs": ClassStatusProgress(),
"members": ClassStatusProgress(),
"theme_items": ClassStatusProgress(),
"signals": ClassStatusProgress(),
Expand Down Expand Up @@ -239,7 +242,7 @@ def make_output(self) -> Dict[str, str]:
)
items_progress = ClassStatusProgress()

for k in ["methods", "constants", "members", "theme_items", "signals", "constructors", "operators"]:
for k in ["methods", "constants", "structs", "members", "theme_items", "signals", "constructors", "operators"]:
items_progress += self.progresses[k]
output[k] = self.progresses[k].to_configured_colored_string()

Expand Down Expand Up @@ -284,7 +287,7 @@ def generate_for_class(c: ET.Element):
descr = sub_tag.find("description")
has_descr = (descr is not None) and (descr.text is not None) and len(descr.text.strip()) > 0
status.progresses[tag.tag].increment(is_deprecated or is_experimental or has_descr)
elif tag.tag in ["constants", "members", "theme_items"]:
elif tag.tag in ["constants", "structs", "members", "theme_items"]:
for sub_tag in list(tag):
if sub_tag.text is not None:
is_deprecated = "deprecated" in sub_tag.attrib
Expand Down Expand Up @@ -327,7 +330,7 @@ def generate_for_class(c: ET.Element):
sys.exit(1)

if flags["i"]:
for r in ["methods", "constants", "members", "signals", "theme_items"]:
for r in ["methods", "constants", "structs", "members", "signals", "theme_items"]:
index = table_columns.index(r)
del table_column_names[index]
del table_columns[index]
Expand Down
Loading

0 comments on commit 5701057

Please sign in to comment.