Skip to content

Instantly share code, notes, and snippets.

@simpuid
Last active March 28, 2020 16:43
Show Gist options
  • Save simpuid/4da31da0e6855311568ab313fa169101 to your computer and use it in GitHub Desktop.
Save simpuid/4da31da0e6855311568ab313fa169101 to your computer and use it in GitHub Desktop.
Mock-up usage of `Custom Profiler` API to monitor Device's magnetometer in Godot.

This mock-up shows the usage of Custom Profiler API to create custom profilers in Godot.

  • All scripts are inside res://addons/profiler/
  • plugin.gd is mentioned inside plugin.cfg file.
  • It sets the GUI scene (res://addons/profiler/gui_scene.tscn) used by the profiler.
  • It also adds a custom Node named CustomProfiler which processes and sends data from Game to Editor. This node should be added to scene tree via autoload.
  • profiler.gd is the script of CustomProfiler
  • It registers tick, add and toggle functions to EngineDebugger under id profiler
  • It registers capture function as capture for rotation (any packet with name matched to rotation:* will be relayed to the capture function)
  • Data is added via profiler_add_frame_data in _process
  • profiler_editor.gd is attached to the root node of GUI scene (res://addons/profiler/gui_scene.tscn)
  • It registers capture function to capture packets with names similar to rotation:*
  • rotation:state is used to activate/deactivate the profiler
  • rotation:data is used to send data from Game to Editor
[plugin]
name="profiler"
description=""
author=""
version=""
script="plugin.gd"
tool
extends EditorPlugin
# This scene contains the UI layout of custom profiler.
# Root node inside this packed scene have "profiler_editor.gd" attached.
var scene = preload("res://addons/profiler/gui_scene.tscn")
# EditorDebuggerNode used to register/unregister the scene
var debugger = null
func _enter_tree():
# Get EditorDebuggerNode singleton
debugger = Engine.get_singleton("EditorDebuggerNode")
# Register the scene, every instance of ScriptEditorDebugger adds an instance of it.
if editor_debugger_node != null:
editor_debugger_node.register_profiler_scene("scene_id",profiler_scene)
# Register a custom type that acts as a profiler in game.
# It should be added to game scene tree through an autoload or some other way
add_custom_type("CustomProfiler","Node",preload("res://addons/profiler/profiler.gd"),preload("res://addons/profiler/icon.png"))
func _exit_tree():
# Unregister, and remove the scene instances from instances of ScriptEditorDebugger
if editor_debugger_node != null && editor_debugger_node.has_profiler_scene("scene_id")
editor_debugger_node.unregister_profiler_scene("scene_id")
# Unregister the custom type
remove_custom_type("CustomProfiler")
extends Node
# Used to store the value sent through tick
var last_dir = Vector3.ZERO
# Stores EngineDebugger singleton
var debugger = null
func _enter_tree():
debugger = Engine.get_singleton("EngineDebugger")
var self_var = self
# Register the profiler under name "profiler"
# 3 callables are used for toggle, add and tick
if debugger != null:
if !debugger.has_profiler("profiler"):
# Called when profiler is enables/disabled
var toggle = Callable(self_var,"toggle")
# Called when data is added through EngineDebugger.profiler_add_frame_data
var add = Callable(self_var,"add")
# Called at every tick of EngineDebugger
var tick = Callable(self_var, "tick")
debugger.register_profiler("profiler",toggle,add,tick)
# Capture will capture every packet of name "rotation:*any_string*" from the Editor
if !debugger.has_capture("rotation"):
debugger.register_message_capture("rotation",Callable(self_var,"capture"))
# For simplicity, it will print the state of profiler
func toggle(state:bool, args:Array):
print(state)
# Handles the addition of data
# Add is called only when profiler is active
func add(data:Array):
if !data.empty():
last_dir = data[0]
# Data is sent at this function, for simplicity last_dir is sent
# Tick is called when profiler is active
func tick(frame_time:float, idle_time:float, physics_time:float, physics_frame_time:float):
if debugger != null:
debugger.send_message("rotation:data",[last_dir])
# Captures every packet named "rotation:*"
func capture(message:String,args:Array):
# Custom message "rotation:state: is used for activation
if message == "state" && !args.empty() && debugger != null:
var state = args.pop_front()
# profiler_enable is used to toogle the profiler.
debugger.profiler_enable("profiler",state,args)
# Clean up
func _exit_tree():
if debugger != null:
if debugger.has_profiler("profiler"):
debugger.unregister_profiler("profiler")
if debugger.has_capture("rotation"):
debugger.unregister_message_capture("rotation")
# In this example both the profiler node and the node which adds data to profiler are same.
func _process(delta):
if debugger != null:
# It adds data to profiler registered under name "profiler"
debugger.profiler_add_frame_data("profiler",[Input.get_magnetometer()])
tool
extends Control
# Stores the reference of ScriptEditorDebugger which handles this profiler.
var debugger = null
func _enter_tree():
var singleton = Engine.get_singleton("EditorDebuggerNode")
var self_var = self
# Get the attached ScriptEditorDebugger from EditorDebuggerNode singleton
if singleton != null:
debugger = singleton.get_debugger(singleton.get_debugger_id(self))
# Capture captures every message under "rotation:*any_string*" from the running Game
if debugger != null && !debugger.has_capture("rotation"):
debugger.register_message_capture("rotation",Callable(self_var,"capture"))
# Clean Up
func _exit_tree():
if debugger != null && debugger.has_capture("rotation"):
debugger.unregister_message_capture("rotation")
# Set the rotation according to the received Vector3
func capture(message:String,args:Array):
if message == "data" && !args.empty():
rect_rotation = args[0].normalized().angle_to(Vector3.AXIS_X)
# This function is called by third party button/signal which is not provided in code.
# It instructs the remote profiler to start/stop profiling.
func enable_profiler(state:bool):
if debugger != null:
debugger.send_message("rotation:state",[state])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment