Inspector ⚠️ when C# props might be out of date

This commit is contained in:
Paul Joannon 2023-12-22 23:27:13 +01:00
parent 2d0ee20ff3
commit 0818d015db
No known key found for this signature in database
GPG key ID: C12F69B0AD0390DD
5 changed files with 136 additions and 3 deletions

View file

@ -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;
} }

View file

@ -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

View file

@ -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();
} }

View file

@ -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);
}
}
}

View file

@ -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();
}
}
}
}