Skip to content

Commit fd4e2e1

Browse files
committed
CraterCrashGH-384 Support script documentation
1 parent 11202e5 commit fd4e2e1

File tree

13 files changed

+314
-8
lines changed

13 files changed

+314
-8
lines changed

src/editor/plugins/orchestrator_editor_plugin.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ void OrchestratorPlugin::_notification(int p_what)
6161

6262
// Register the plugin's icon for CreateScript Dialog
6363
Ref<Theme> theme = ThemeDB::get_singleton()->get_default_theme();
64-
if (theme.is_valid() && !theme->has_icon(_get_plugin_name(), "EditorIcons"))
65-
theme->set_icon(_get_plugin_name(), "EditorIcons", _get_plugin_icon());
64+
if (theme.is_valid() && !theme->has_icon(OScript::get_class_static(), "EditorIcons"))
65+
theme->set_icon(OScript::get_class_static(), "EditorIcons", _get_plugin_icon());
6666

6767
_window_wrapper = memnew(OrchestratorWindowWrapper);
6868
_window_wrapper->set_window_title(vformat("Orchestrator - Godot Engine"));

src/orchestration/orchestration.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,24 @@ void Orchestration::validate_and_build(BuildLog& p_log)
276276
}
277277
}
278278

279+
void Orchestration::set_brief_description(const String& p_description)
280+
{
281+
if (!_brief_description.match(p_description))
282+
{
283+
_brief_description = p_description;
284+
_self->emit_changed();
285+
}
286+
}
287+
288+
void Orchestration::set_description(const String& p_description)
289+
{
290+
if (!_description.match(p_description))
291+
{
292+
_description = p_description;
293+
_self->emit_changed();
294+
}
295+
}
296+
279297
void Orchestration::add_node(const Ref<OScriptGraph>& p_graph, const Ref<OScriptNode>& p_node)
280298
{
281299
ERR_FAIL_COND_MSG(_has_instances(), "Cannot add node, instances exist.");

src/orchestration/orchestration.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class Orchestration
6363
HashMap<StringName, Ref<OScriptSignal>> _signals; //! Map of all user-defined signals
6464
HashMap<StringName, Ref<OScriptGraph>> _graphs; //! Map of all defined graphs
6565
Resource* _self; //! Reference to the outer resource type
66+
String _brief_description; //! The brief description
67+
String _description; //! The description
6668

6769
//~ Begin Serialization Interface
6870
TypedArray<OScriptNode> _get_nodes_internal() const;
@@ -158,6 +160,22 @@ class Orchestration
158160
/// @param p_log the build log
159161
virtual void validate_and_build(BuildLog& p_log);
160162

163+
/// Get the brief description for the orchestration
164+
/// @return the brief description
165+
virtual String get_brief_description() const { return _brief_description; }
166+
167+
/// Set the brief description
168+
/// @param p_description the brief description
169+
virtual void set_brief_description(const String& p_description);
170+
171+
/// Get the description for the orchestration
172+
/// @return the description
173+
virtual String get_description() const { return _description; }
174+
175+
/// Set the description for the orchestration
176+
/// @param p_description the description
177+
virtual void set_description(const String& p_description);
178+
161179
//~ Begin Node Interface
162180
void add_node(const Ref<OScriptGraph>& p_graph, const Ref<OScriptNode>& p_node);
163181
void remove_node(int p_node_id);

src/script/function.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ void OScriptFunction::_get_property_list(List<PropertyInfo> *r_list) const
2727
r_list->push_back(PropertyInfo(Variant::DICTIONARY, "method"));
2828
r_list->push_back(PropertyInfo(Variant::BOOL, "user_defined"));
2929
r_list->push_back(PropertyInfo(Variant::INT, "id"));
30+
r_list->push_back(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT));
3031
}
3132

3233
bool OScriptFunction::_get(const StringName &p_name, Variant &r_value)
@@ -51,6 +52,11 @@ bool OScriptFunction::_get(const StringName &p_name, Variant &r_value)
5152
r_value = _user_defined;
5253
return true;
5354
}
55+
else if (p_name.match("description"))
56+
{
57+
r_value = _description;
58+
return true;
59+
}
5460
return false;
5561
}
5662

@@ -78,6 +84,15 @@ bool OScriptFunction::_set(const StringName &p_name, const Variant &p_value)
7884
_user_defined = p_value;
7985
result = true;
8086
}
87+
else if (p_name.match("description"))
88+
{
89+
_description = p_value;
90+
91+
if (_orchestration)
92+
_orchestration->get_self()->emit_changed();
93+
94+
result = true;
95+
}
8196

8297
if (result)
8398
emit_changed();
@@ -261,3 +276,12 @@ void OScriptFunction::set_has_return_value(bool p_has_return_value)
261276
emit_changed();
262277
}
263278
}
279+
280+
void OScriptFunction::set_description(const String& p_description)
281+
{
282+
if (_description != p_description)
283+
{
284+
_description = p_description;
285+
emit_changed();
286+
}
287+
}

src/script/function.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class OScriptFunction : public Resource
5353
bool _user_defined{ false }; //! Whether function is user-defined
5454
int _owning_node_id{ -1 }; //! Owning node id
5555
bool _returns_value{ false }; //! Whether the function returns a value
56+
String _description; //! Function description
5657

5758
protected:
5859
//~ Begin Wrapped Interface
@@ -170,6 +171,14 @@ class OScriptFunction : public Resource
170171
/// Sets whether the function has a return value
171172
/// @param p_has_return_value value true if the function has a return value, false otherwise
172173
void set_has_return_value(bool p_has_return_value);
174+
175+
/// Get the description
176+
/// @return the description
177+
String get_description() const { return _description; }
178+
179+
/// Sets the description
180+
/// @param p_description the description
181+
void set_description(const String& p_description);
173182
};
174183

175184
#endif // ORCHESTRATOR_SCRIPT_FUNCTION_H

src/script/language.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ String OScriptLanguage::_get_name() const
7979

8080
String OScriptLanguage::_get_type() const
8181
{
82-
return TYPE;
82+
return OScript::get_class_static();
8383
}
8484

8585
String OScriptLanguage::_get_extension() const
@@ -104,7 +104,7 @@ bool OScriptLanguage::_supports_builtin_mode() const
104104

105105
bool OScriptLanguage::_supports_documentation() const
106106
{
107-
return false;
107+
return true;
108108
}
109109

110110
bool OScriptLanguage::_is_using_templates()

src/script/nodes/functions/function_terminator.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ void OScriptNodeFunctionTerminator::_get_property_list(List<PropertyInfo>* r_lis
3333
r_list->push_back(PropertyInfo(Variant::STRING, "function_id", PROPERTY_HINT_NONE, "", read_only_serialize));
3434
r_list->push_back(PropertyInfo(Variant::STRING, "function_name", PROPERTY_HINT_NONE, "", read_only_editor));
3535

36+
r_list->push_back(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT));
37+
3638
if (function.is_valid())
3739
{
3840
if (_supports_return_values())
@@ -113,6 +115,15 @@ bool OScriptNodeFunctionTerminator::_get(const StringName& p_name, Variant& r_va
113115
return true;
114116
}
115117
}
118+
else if (p_name.match("description"))
119+
{
120+
Ref<OScriptFunction> function = get_function();
121+
if (function.is_valid())
122+
{
123+
r_value = function->get_description();
124+
return true;
125+
}
126+
}
116127
return false;
117128
}
118129

@@ -176,6 +187,15 @@ bool OScriptNodeFunctionTerminator::_set(const StringName& p_name, const Variant
176187
return true;
177188
}
178189
}
190+
else if (p_name.match("description"))
191+
{
192+
Ref<OScriptFunction> function = get_function();
193+
if (function.is_valid())
194+
{
195+
function->set_description(p_value);
196+
return true;
197+
}
198+
}
179199
return false;
180200
}
181201

src/script/script.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "script/instances/script_instance.h"
2121
#include "script/instances/script_instance_placeholder.h"
2222
#include "script/nodes/script_nodes.h"
23+
#include "script_docdata.h"
2324

2425
#include <godot_cpp/classes/engine.hpp>
2526
#include <godot_cpp/core/mutex_lock.hpp>
@@ -74,6 +75,14 @@ void OScript::_bind_methods()
7475
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "graphs", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_graphs",
7576
"_get_graphs");
7677

78+
ClassDB::bind_method(D_METHOD("_set_brief_description", "description"), &OScript::_set_brief_description);
79+
ClassDB::bind_method(D_METHOD("_get_brief_description"), &OScript::_get_brief_description);
80+
ADD_PROPERTY(PropertyInfo(Variant::STRING, "brief_description", PROPERTY_HINT_MULTILINE_TEXT), "_set_brief_description", "_get_brief_description");
81+
82+
ClassDB::bind_method(D_METHOD("_set_description", "description"), &OScript::_set_description);
83+
ClassDB::bind_method(D_METHOD("_get_description"), &OScript::_get_description);
84+
ADD_PROPERTY(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT), "_set_description", "_get_description");
85+
7786
ADD_SIGNAL(MethodInfo("connections_changed", PropertyInfo(Variant::STRING, "caller")));
7887
ADD_SIGNAL(MethodInfo("functions_changed"));
7988
ADD_SIGNAL(MethodInfo("variables_changed"));
@@ -209,9 +218,7 @@ Error OScript::_reload(bool p_keep_state)
209218

210219
TypedArray<Dictionary> OScript::_get_documentation() const
211220
{
212-
// todo: see how to generate it from the script/node contents
213-
// see doc_data & script_language_extension
214-
return {};
221+
return OScriptDocData::create_documentation(Ref<OScript>(this));
215222
}
216223

217224
bool OScript::_has_static_method(const StringName& p_method) const

src/script/script.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ class OScript : public ScriptExtension, public Orchestration
7171
void _set_variables(const TypedArray<OScriptVariable>& p_variables) { _set_variables_internal(p_variables); }
7272
TypedArray<OScriptSignal> _get_signals() const { return _get_signals_internal(); }
7373
void _set_signals(const TypedArray<OScriptSignal>& p_signals) { _set_signals_internal(p_signals); }
74+
void _set_brief_description(const String& p_description) { set_brief_description(p_description); }
75+
String _get_brief_description() const { return get_brief_description(); }
76+
void _set_description(const String& p_description) { set_description(p_description); }
77+
String _get_description() const { return get_description(); }
7478
//~ End Serialization API
7579

7680
/// Update export placeholders

src/script/script_docdata.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// This file is part of the Godot Orchestrator project.
2+
//
3+
// Copyright (c) 2023-present Vahera Studios LLC and its contributors.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
//
17+
#include "script/script_docdata.h"
18+
19+
Dictionary OScriptDocData::_create_property_documentation(const PropertyInfo& p_property)
20+
{
21+
Dictionary property;
22+
property["name"] = p_property.name;
23+
property["type"] = p_property.type == Variant::NIL ? "Variant" : Variant::get_type_name(p_property.type);
24+
return property;
25+
}
26+
27+
TypedArray<Dictionary> OScriptDocData::_get_method_arguments_documentation(const std::vector<PropertyInfo>& p_properties)
28+
{
29+
TypedArray<Dictionary> data;
30+
for (const PropertyInfo& property : p_properties)
31+
data.push_back(_create_property_documentation(property));
32+
33+
return data;
34+
}
35+
36+
String OScriptDocData::_get_method_return_type(const MethodInfo& p_method)
37+
{
38+
if (p_method.return_val.type == Variant::NIL)
39+
return p_method.return_val.usage & PROPERTY_USAGE_NIL_IS_VARIANT ? "Variant" : "void";
40+
41+
return Variant::get_type_name(p_method.return_val.type);
42+
}
43+
44+
Dictionary OScriptDocData::_method_info_documentation(const MethodInfo& p_method, const String& p_description)
45+
{
46+
Dictionary data;
47+
data["name"] = p_method.name;
48+
data["description"] = p_description;
49+
data["return_type"] = _get_method_return_type(p_method);
50+
data["arguments"] = _get_method_arguments_documentation(p_method.arguments);
51+
return data;
52+
}
53+
54+
TypedArray<Dictionary> OScriptDocData::_create_properties_documentation(const Ref<OScript>& p_script)
55+
{
56+
TypedArray<Dictionary> data;
57+
for (const Ref<OScriptVariable>& variable : p_script->get_variables())
58+
{
59+
Dictionary property_data = _create_property_documentation(variable->get_info());
60+
property_data["description"] = variable->get_description();
61+
62+
data.push_back(property_data);
63+
}
64+
return data;
65+
}
66+
67+
TypedArray<Dictionary> OScriptDocData::_create_signals_documentation(const Ref<OScript>& p_script)
68+
{
69+
TypedArray<Dictionary> data;
70+
for (const Ref<OScriptSignal>& signal : p_script->get_custom_signals())
71+
{
72+
const MethodInfo& mi = signal->get_method_info();
73+
data.push_back(_method_info_documentation(mi, signal->get("description")));
74+
}
75+
return data;
76+
}
77+
78+
TypedArray<Dictionary> OScriptDocData::_create_functions_documentation(const Ref<OScript>& p_script)
79+
{
80+
TypedArray<Dictionary> data;
81+
for (const Ref<OScriptFunction>& function : p_script->get_functions())
82+
{
83+
const MethodInfo& mi = function->get_method_info();
84+
data.push_back(_method_info_documentation(mi, function->get("description")));
85+
}
86+
return data;
87+
}
88+
89+
TypedArray<Dictionary> OScriptDocData::create_documentation(const Ref<OScript>& p_script)
90+
{
91+
Dictionary data;
92+
data["name"] = vformat("\"%s\"", p_script->get_path().replace("res://", ""));
93+
data["inherits"] = p_script->get_base_type();
94+
data["brief_description"] = p_script->get_brief_description();
95+
data["description"] = p_script->get_description();
96+
data["methods"] = _create_functions_documentation(p_script);
97+
data["signals"] = _create_signals_documentation(p_script);
98+
data["properties"] = _create_properties_documentation(p_script);
99+
data["is_deprecated"] = false;
100+
data["is_experimental"] = false;
101+
data["is_script_doc"] = true;
102+
data["script_path"] = p_script->get_path();
103+
104+
// We currently only support 1 class per Orchestration
105+
return Array::make(data);
106+
}

0 commit comments

Comments
 (0)