Inspector ⚠️ when C# props might be out of date
This commit is contained in:
parent
2d0ee20ff3
commit
0818d015db
5 changed files with 136 additions and 3 deletions
|
@ -788,9 +788,7 @@ static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_curr
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_for_script) {
|
void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_for_script) {
|
||||||
if (!bool(EDITOR_GET("text_editor/external/use_external_editor"))) {
|
bool use_external_editor = bool(EDITOR_GET("text_editor/external/use_external_editor"));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_NULL(get_tree());
|
ERR_FAIL_NULL(get_tree());
|
||||||
|
|
||||||
|
@ -804,6 +802,10 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo
|
||||||
for (const Ref<Script> &E : scripts) {
|
for (const Ref<Script> &E : scripts) {
|
||||||
Ref<Script> scr = E;
|
Ref<Script> scr = E;
|
||||||
|
|
||||||
|
if (!use_external_editor && !scr->get_language()->overrides_external_editor()) {
|
||||||
|
continue; // We're not using an external editor for this script.
|
||||||
|
}
|
||||||
|
|
||||||
if (p_for_script.is_valid() && p_for_script != scr) {
|
if (p_for_script.is_valid() && p_for_script != scr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2246,6 +2246,17 @@ bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_upda
|
||||||
} else {
|
} else {
|
||||||
p_instance_to_update->update(propnames, values);
|
p_instance_to_update->update(propnames, values);
|
||||||
}
|
}
|
||||||
|
} else if (placeholders.size()) {
|
||||||
|
uint64_t script_modified_time = FileAccess::get_modified_time(get_path());
|
||||||
|
uint64_t last_valid_build_time = GDMono::get_singleton()->get_project_assembly_modified_time();
|
||||||
|
if (script_modified_time > last_valid_build_time) {
|
||||||
|
for (PlaceHolderScriptInstance *instance : placeholders) {
|
||||||
|
Object *owner = instance->get_owner();
|
||||||
|
if (owner->get_script_instance() == instance) {
|
||||||
|
owner->notify_property_list_changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||||
using GodotTools.Build;
|
using GodotTools.Build;
|
||||||
using GodotTools.Ides;
|
using GodotTools.Ides;
|
||||||
using GodotTools.Ides.Rider;
|
using GodotTools.Ides.Rider;
|
||||||
|
using GodotTools.Inspector;
|
||||||
using GodotTools.Internals;
|
using GodotTools.Internals;
|
||||||
using GodotTools.ProjectEditor;
|
using GodotTools.ProjectEditor;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
@ -45,6 +46,7 @@ namespace GodotTools
|
||||||
|
|
||||||
// TODO Use WeakReference once we have proper serialization.
|
// TODO Use WeakReference once we have proper serialization.
|
||||||
private WeakRef _exportPluginWeak;
|
private WeakRef _exportPluginWeak;
|
||||||
|
private WeakRef _inspectorPluginWeak;
|
||||||
|
|
||||||
public GodotIdeManager GodotIdeManager { get; private set; }
|
public GodotIdeManager GodotIdeManager { get; private set; }
|
||||||
|
|
||||||
|
@ -52,6 +54,8 @@ namespace GodotTools
|
||||||
|
|
||||||
public bool SkipBuildBeforePlaying { get; set; } = false;
|
public bool SkipBuildBeforePlaying { get; set; } = false;
|
||||||
|
|
||||||
|
public DateTime LastValidBuildDateTime { get; private set; }
|
||||||
|
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
private bool CreateProjectSolutionIfNeeded()
|
private bool CreateProjectSolutionIfNeeded()
|
||||||
{
|
{
|
||||||
|
@ -437,6 +441,21 @@ namespace GodotTools
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateLastValidBuildDateTime()
|
||||||
|
{
|
||||||
|
var dllName = $"{GodotSharpDirs.ProjectAssemblyName}.dll";
|
||||||
|
var path = Path.Combine(GodotSharpDirs.ProjectBaseOutputPath, "Debug", dllName);
|
||||||
|
LastValidBuildDateTime = File.GetLastWriteTime(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildFinished(BuildResult buildResult)
|
||||||
|
{
|
||||||
|
if (buildResult == BuildResult.Success)
|
||||||
|
{
|
||||||
|
UpdateLastValidBuildDateTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void BuildStateChanged()
|
private void BuildStateChanged()
|
||||||
{
|
{
|
||||||
if (_bottomPanelBtn != null)
|
if (_bottomPanelBtn != null)
|
||||||
|
@ -447,6 +466,8 @@ namespace GodotTools
|
||||||
{
|
{
|
||||||
base._EnablePlugin();
|
base._EnablePlugin();
|
||||||
|
|
||||||
|
UpdateLastValidBuildDateTime();
|
||||||
|
|
||||||
ProjectSettings.SettingsChanged += GodotSharpDirs.DetermineProjectLocation;
|
ProjectSettings.SettingsChanged += GodotSharpDirs.DetermineProjectLocation;
|
||||||
|
|
||||||
if (Instance != null)
|
if (Instance != null)
|
||||||
|
@ -615,6 +636,12 @@ namespace GodotTools
|
||||||
AddExportPlugin(exportPlugin);
|
AddExportPlugin(exportPlugin);
|
||||||
_exportPluginWeak = WeakRef(exportPlugin);
|
_exportPluginWeak = WeakRef(exportPlugin);
|
||||||
|
|
||||||
|
// Inspector plugin
|
||||||
|
var inspectorPlugin = new InspectorPlugin();
|
||||||
|
AddInspectorPlugin(inspectorPlugin);
|
||||||
|
_inspectorPluginWeak = WeakRef(inspectorPlugin);
|
||||||
|
BuildManager.BuildFinished += BuildFinished;
|
||||||
|
|
||||||
BuildManager.Initialize();
|
BuildManager.Initialize();
|
||||||
RiderPathManager.Initialize();
|
RiderPathManager.Initialize();
|
||||||
|
|
||||||
|
@ -627,6 +654,10 @@ namespace GodotTools
|
||||||
base._DisablePlugin();
|
base._DisablePlugin();
|
||||||
|
|
||||||
_editorSettings.SettingsChanged -= OnSettingsChanged;
|
_editorSettings.SettingsChanged -= OnSettingsChanged;
|
||||||
|
|
||||||
|
// Custom signals aren't automatically disconnected currently.
|
||||||
|
MSBuildPanel.BuildStateChanged -= BuildStateChanged;
|
||||||
|
BuildManager.BuildFinished -= BuildFinished;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _ExitTree()
|
public override void _ExitTree()
|
||||||
|
@ -661,6 +692,13 @@ namespace GodotTools
|
||||||
_exportPluginWeak.Dispose();
|
_exportPluginWeak.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsInstanceValid(_inspectorPluginWeak))
|
||||||
|
{
|
||||||
|
(_inspectorPluginWeak.GetRef().AsGodotObject() as InspectorPlugin)?.Dispose();
|
||||||
|
|
||||||
|
_inspectorPluginWeak.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
GodotIdeManager?.Dispose();
|
GodotIdeManager?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
using Godot;
|
||||||
|
using GodotTools.Internals;
|
||||||
|
|
||||||
|
namespace GodotTools.Inspector
|
||||||
|
{
|
||||||
|
public partial class InspectorOutOfSyncWarning : HBoxContainer
|
||||||
|
{
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
SetAnchorsPreset(LayoutPreset.TopWide);
|
||||||
|
|
||||||
|
var iconTexture = GetThemeIcon("StatusWarning", "EditorIcons");
|
||||||
|
|
||||||
|
var icon = new TextureRect()
|
||||||
|
{
|
||||||
|
Texture = iconTexture,
|
||||||
|
ExpandMode = TextureRect.ExpandModeEnum.FitWidthProportional,
|
||||||
|
CustomMinimumSize = iconTexture.GetSize(),
|
||||||
|
};
|
||||||
|
|
||||||
|
icon.SizeFlagsVertical = SizeFlags.ShrinkCenter;
|
||||||
|
|
||||||
|
var label = new Label()
|
||||||
|
{
|
||||||
|
Text = "This inspector might be out of date. Please build the C# project.".TTR(),
|
||||||
|
AutowrapMode = TextServer.AutowrapMode.WordSmart,
|
||||||
|
CustomMinimumSize = new Vector2(100f, 0f),
|
||||||
|
};
|
||||||
|
|
||||||
|
label.AddThemeColorOverride("font_color", GetThemeColor("warning_color", "Editor"));
|
||||||
|
label.SizeFlagsHorizontal = SizeFlags.Fill | SizeFlags.Expand;
|
||||||
|
|
||||||
|
AddChild(icon);
|
||||||
|
AddChild(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Godot;
|
||||||
|
using GodotTools.Utils;
|
||||||
|
|
||||||
|
namespace GodotTools.Inspector
|
||||||
|
{
|
||||||
|
public partial class InspectorPlugin : EditorInspectorPlugin
|
||||||
|
{
|
||||||
|
public override bool _CanHandle(GodotObject godotObject)
|
||||||
|
{
|
||||||
|
foreach (var script in EnumerateScripts(godotObject))
|
||||||
|
{
|
||||||
|
if (script is CSharpScript)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ParseBegin(GodotObject godotObject)
|
||||||
|
{
|
||||||
|
foreach (var script in EnumerateScripts(godotObject))
|
||||||
|
{
|
||||||
|
if (script is not CSharpScript) continue;
|
||||||
|
|
||||||
|
if (File.GetLastWriteTime(script.ResourcePath) > GodotSharpEditor.Instance.LastValidBuildDateTime)
|
||||||
|
{
|
||||||
|
AddCustomControl(new InspectorOutOfSyncWarning());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<Script> EnumerateScripts(GodotObject godotObject)
|
||||||
|
{
|
||||||
|
var script = godotObject.GetScript().As<Script>();
|
||||||
|
while (script != null)
|
||||||
|
{
|
||||||
|
yield return script;
|
||||||
|
script = script.GetBaseScript();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue