Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Custom Performance Monitor #39302

Merged
merged 1 commit into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion core/debugger/remote_debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ struct RemoteDebugger::VisualProfiler {
struct RemoteDebugger::PerformanceProfiler {
Object *performance = nullptr;
int last_perf_time = 0;
uint64_t last_monitor_modification_time = 0;

void toggle(bool p_enable, const Array &p_opts) {}
void add(const Array &p_data) {}
Expand All @@ -386,12 +387,31 @@ struct RemoteDebugger::PerformanceProfiler {
return;
}
last_perf_time = pt;

Array custom_monitor_names = performance->call("get_custom_monitor_names");

uint64_t monitor_modification_time = performance->call("get_monitor_modification_time");
if (monitor_modification_time > last_monitor_modification_time) {
last_monitor_modification_time = monitor_modification_time;
EngineDebugger::get_singleton()->send_message("performance:profile_names", custom_monitor_names);
}

int max = performance->get("MONITOR_MAX");
Array arr;
arr.resize(max);
arr.resize(max + custom_monitor_names.size());
for (int i = 0; i < max; i++) {
arr[i] = performance->call("get_monitor", i);
}

for (int i = 0; i < custom_monitor_names.size(); i++) {
Variant monitor_value = performance->call("get_custom_monitor", custom_monitor_names[i]);
if (!monitor_value.is_num()) {
ERR_PRINT("Value of custom monitor '" + String(custom_monitor_names[i]) + "' is not a number");
arr[i + max] = Variant();
}
arr[i + max] = monitor_value;
}

EngineDebugger::get_singleton()->send_message("performance:profile_frame", arr);
}

Expand Down
69 changes: 69 additions & 0 deletions doc/classes/Performance.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,55 @@
</brief_description>
<description>
This class provides access to a number of different monitors related to performance, such as memory usage, draw calls, and FPS. These are the same as the values displayed in the [b]Monitor[/b] tab in the editor's [b]Debugger[/b] panel. By using the [method get_monitor] method of this class, you can access this data from your code.
You can add custom monitors using the [method add_custom_monitor] method. Custom monitors are available in [b]Monitor[/b] tab in the editor's [b]Debugger[/b] panel together with built-in monitors.
[b]Note:[/b] A few of these monitors are only available in debug mode and will always return 0 when used in a release build.
[b]Note:[/b] Many of these monitors are not updated in real-time, so there may be a short delay between changes.
[b]Note:[/b] Custom monitors do not support negative values. Negative values are clamped to 0.
</description>
<tutorials>
</tutorials>
<methods>
<method name="add_custom_monitor">
<return type="void">
</return>
<argument index="0" name="id" type="StringName">
</argument>
<argument index="1" name="callable" type="Callable">
</argument>
<argument index="2" name="arguments" type="Array" default="[ ]">
</argument>
<description>
Adds a custom monitor with name same as id. You can specify the category of monitor using '/' in id. If there are more than one '/' then default category is used. Default category is "Custom".
[codeblock]
Performance.add_custom_monitor("MyCategory/MyMonitor", some_callable) # Adds monitor with name "MyName" to category "MyCategory"
Performance.add_custom_monitor("MyMonitor", some_callable) # Adds monitor with name "MyName" to category "Custom"
# Note: "MyCategory/MyMonitor" and "MyMonitor" have same name but different ids so above code is valid
Performance.add_custom_monitor("Custom/MyMonitor", some_callable) # Adds monitor with name "MyName" to category "Custom"
# Note: "MyMonitor" and "Custom/MyMonitor" have same name and same category but different ids so above code is valid
Performance.add_custom_monitor("MyCategoryOne/MyCategoryTwo/MyMonitor", some_callable) # Adds monitor with name "MyCategoryOne/MyCategoryTwo/MyMonitor" to category "Custom"
[/codeblock]
The debugger calls the callable to get the value of custom monitor. The callable must return a number.
Callables are called with arguments supplied in argument array.
[b]Note:[/b] It throws an error if given id is already present.
</description>
</method>
<method name="get_custom_monitor">
<return type="Variant">
</return>
<argument index="0" name="id" type="StringName">
</argument>
<description>
Returns the value of custom monitor with given id. The callable is called to get the value of custom monitor.
[b]Note:[/b] It throws an error if the given id is absent.
</description>
</method>
<method name="get_custom_monitor_names">
<return type="Array">
</return>
<description>
Returns the names of active custom monitors in an array.
</description>
</method>
<method name="get_monitor" qualifiers="const">
<return type="float">
</return>
Expand All @@ -23,6 +66,32 @@
[/codeblock]
</description>
</method>
<method name="get_monitor_modification_time">
<return type="int">
</return>
<description>
Returns the last tick in which custom monitor was added/removed.
</description>
</method>
<method name="has_custom_monitor">
<return type="bool">
</return>
<argument index="0" name="id" type="StringName">
</argument>
<description>
Returns true if custom monitor with the given id is present otherwise returns false.
</description>
</method>
<method name="remove_custom_monitor">
<return type="void">
</return>
<argument index="0" name="id" type="StringName">
</argument>
<description>
Removes the custom monitor with given id.
[b]Note:[/b] It throws an error if the given id is already absent.
</description>
</method>
</methods>
<constants>
<constant name="TIME_FPS" value="0" enum="Monitor">
Expand Down
Loading