mirror of
https://github.com/godotengine/godot.git
synced 2024-10-22 21:21:53 +00:00
Compare commits
4 Commits
2b17da9763
...
509312a63a
Author | SHA1 | Date | |
---|---|---|---|
|
509312a63a | ||
|
533c616cb8 | ||
|
b023f30655 | ||
|
d5d509bbd6 |
|
@ -66,4 +66,13 @@ public class ScriptPropertiesGeneratorTests
|
|||
"AbstractGenericNode(Of T)_ScriptProperties.generated.cs"
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Inheritance()
|
||||
{
|
||||
await CSharpSourceGeneratorVerifier<ScriptPropertiesGenerator>.Verify(
|
||||
new string[] { "Inheritance.cs" },
|
||||
new string[] { "InheritanceBase_ScriptProperties.generated.cs", "InheritanceChild_ScriptProperties.generated.cs" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,4 +30,13 @@ public class ScriptPropertyDefValGeneratorTests
|
|||
"ExportedComplexStrings_ScriptPropertyDefVal.generated.cs"
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Inheritance()
|
||||
{
|
||||
await CSharpSourceGeneratorVerifier<ScriptPropertyDefValGenerator>.Verify(
|
||||
new string[] { "Inheritance.cs" },
|
||||
new string[] { "InheritanceBase_ScriptPropertyDefVal.generated.cs", "InheritanceChild_ScriptPropertyDefVal.generated.cs" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,4 +12,13 @@ public class ScriptSerializationGeneratorTests
|
|||
"ScriptBoilerplate_ScriptSerialization.generated.cs", "OuterClass.NestedClass_ScriptSerialization.generated.cs"
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Inheritance()
|
||||
{
|
||||
await CSharpSourceGeneratorVerifier<ScriptSerializationGenerator>.VerifyNoCompilerDiagnostics(
|
||||
new string[] { "Inheritance.cs" },
|
||||
new string[] { "InheritanceBase_ScriptSerialization.generated.cs", "InheritanceChild_ScriptSerialization.generated.cs" }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
using Godot;
|
||||
using Godot.NativeInterop;
|
||||
|
||||
partial class InheritanceBase
|
||||
{
|
||||
#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
|
||||
/// <summary>
|
||||
/// Cached StringNames for the properties and fields contained in this class, for fast lookup.
|
||||
/// </summary>
|
||||
public new class PropertyName : global::Godot.Node.PropertyName {
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyString' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyString = "MyString";
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyInteger' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyInteger = "MyInteger";
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyString) {
|
||||
this.@MyString = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@MyInteger) {
|
||||
this.@MyInteger = global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(value);
|
||||
return true;
|
||||
}
|
||||
return base.SetGodotClassPropertyValue(name, value);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyString) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@MyString);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@MyInteger) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int>(this.@MyInteger);
|
||||
return true;
|
||||
}
|
||||
return base.GetGodotClassPropertyValue(name, out value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the property information for all the properties declared in this class.
|
||||
/// This method is used by Godot to register the available properties in the editor.
|
||||
/// Do not call this method.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList()
|
||||
{
|
||||
var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>();
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@MyString, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.@MyInteger, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false));
|
||||
return properties;
|
||||
}
|
||||
#pragma warning restore CS0109
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
partial class InheritanceBase
|
||||
{
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Godot;
|
||||
using Godot.NativeInterop;
|
||||
|
||||
partial class InheritanceBase
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override void SaveGodotObjectData(global::Godot.Bridge.GodotSerializationInfo info)
|
||||
{
|
||||
base.SaveGodotObjectData(info);
|
||||
info.AddProperty(PropertyName.@MyString, global::Godot.Variant.From<string>(this.@MyString));
|
||||
info.AddProperty(PropertyName.@MyInteger, global::Godot.Variant.From<int>(this.@MyInteger));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override void RestoreGodotObjectData(global::Godot.Bridge.GodotSerializationInfo info)
|
||||
{
|
||||
base.RestoreGodotObjectData(info);
|
||||
if (info.TryGetProperty(PropertyName.@MyString, out var _value_MyString))
|
||||
this.@MyString = _value_MyString.As<string>();
|
||||
if (info.TryGetProperty(PropertyName.@MyInteger, out var _value_MyInteger))
|
||||
this.@MyInteger = _value_MyInteger.As<int>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
using Godot;
|
||||
using Godot.NativeInterop;
|
||||
|
||||
partial class InheritanceChild
|
||||
{
|
||||
#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
|
||||
/// <summary>
|
||||
/// Cached StringNames for the properties and fields contained in this class, for fast lookup.
|
||||
/// </summary>
|
||||
public new class PropertyName : global::InheritanceBase.PropertyName {
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyString' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyString = "MyString";
|
||||
/// <summary>
|
||||
/// Cached name for the 'MyInteger' property.
|
||||
/// </summary>
|
||||
public new static readonly global::Godot.StringName @MyInteger = "MyInteger";
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyString) {
|
||||
this.@MyString = global::Godot.NativeInterop.VariantUtils.ConvertTo<string>(value);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@MyInteger) {
|
||||
this.@MyInteger = global::Godot.NativeInterop.VariantUtils.ConvertTo<int>(value);
|
||||
return true;
|
||||
}
|
||||
return base.SetGodotClassPropertyValue(name, value);
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
|
||||
{
|
||||
if (name == PropertyName.@MyString) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<string>(this.@MyString);
|
||||
return true;
|
||||
}
|
||||
if (name == PropertyName.@MyInteger) {
|
||||
value = global::Godot.NativeInterop.VariantUtils.CreateFrom<int>(this.@MyInteger);
|
||||
return true;
|
||||
}
|
||||
return base.GetGodotClassPropertyValue(name, out value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the property information for all the properties declared in this class.
|
||||
/// This method is used by Godot to register the available properties in the editor.
|
||||
/// Do not call this method.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal new static global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo> GetGodotPropertyList()
|
||||
{
|
||||
var properties = new global::System.Collections.Generic.List<global::Godot.Bridge.PropertyInfo>();
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)4, name: PropertyName.@MyString, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4096, exported: false));
|
||||
properties.Add(new(type: (global::Godot.Variant.Type)2, name: PropertyName.@MyInteger, hint: (global::Godot.PropertyHint)0, hintString: "", usage: (global::Godot.PropertyUsageFlags)4102, exported: true));
|
||||
return properties;
|
||||
}
|
||||
#pragma warning restore CS0109
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
partial class InheritanceChild
|
||||
{
|
||||
#pragma warning disable CS0109 // Disable warning about redundant 'new' keyword
|
||||
#if TOOLS
|
||||
/// <summary>
|
||||
/// Get the default values for all properties declared in this class.
|
||||
/// This method is used by Godot to determine the value that will be
|
||||
/// used by the inspector when resetting properties.
|
||||
/// Do not call this method.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
internal new static global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant> GetGodotPropertyDefaultValues()
|
||||
{
|
||||
var values = new global::System.Collections.Generic.Dictionary<global::Godot.StringName, global::Godot.Variant>(1);
|
||||
int __MyInteger_default_value = default;
|
||||
values.Add(PropertyName.@MyInteger, global::Godot.Variant.From<int>(__MyInteger_default_value));
|
||||
return values;
|
||||
}
|
||||
#endif // TOOLS
|
||||
#pragma warning restore CS0109
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Godot;
|
||||
using Godot.NativeInterop;
|
||||
|
||||
partial class InheritanceChild
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override void SaveGodotObjectData(global::Godot.Bridge.GodotSerializationInfo info)
|
||||
{
|
||||
base.SaveGodotObjectData(info);
|
||||
info.AddProperty(PropertyName.@MyString, global::Godot.Variant.From<string>(this.@MyString));
|
||||
info.AddProperty(PropertyName.@MyInteger, global::Godot.Variant.From<int>(this.@MyInteger));
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
|
||||
protected override void RestoreGodotObjectData(global::Godot.Bridge.GodotSerializationInfo info)
|
||||
{
|
||||
base.RestoreGodotObjectData(info);
|
||||
if (info.TryGetProperty(PropertyName.@MyString, out var _value_MyString))
|
||||
this.@MyString = _value_MyString.As<string>();
|
||||
if (info.TryGetProperty(PropertyName.@MyInteger, out var _value_MyInteger))
|
||||
this.@MyInteger = _value_MyInteger.As<int>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using Godot;
|
||||
|
||||
public partial class InheritanceBase : Node
|
||||
{
|
||||
public virtual string MyString { get; set; }
|
||||
public virtual int MyInteger { get; set; }
|
||||
}
|
||||
|
||||
public partial class InheritanceChild : InheritanceBase
|
||||
{
|
||||
public override string MyString { get; set; }
|
||||
[Export]
|
||||
public override int MyInteger => 0;
|
||||
}
|
|
@ -384,5 +384,15 @@ namespace Godot.SourceGenerators
|
|||
public static int StartLine(this Location location)
|
||||
=> location.SourceTree?.GetLineSpan(location.SourceSpan).StartLinePosition.Line
|
||||
?? location.GetLineSpan().StartLinePosition.Line;
|
||||
|
||||
public static IMethodSymbol? GetMethodOrBaseGetMethod(this IPropertySymbol symbol)
|
||||
{
|
||||
return symbol.GetMethod ?? symbol.OverriddenProperty?.GetMethodOrBaseGetMethod();
|
||||
}
|
||||
|
||||
public static IMethodSymbol? SetMethodOrBaseSetMethod(this IPropertySymbol symbol)
|
||||
{
|
||||
return symbol.SetMethod ?? symbol.OverriddenProperty?.SetMethodOrBaseSetMethod();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ namespace Godot.SourceGenerators
|
|||
|
||||
public IPropertySymbol PropertySymbol { get; }
|
||||
public MarshalType Type { get; }
|
||||
|
||||
public bool IsReadOnly => PropertySymbol.IsReadOnly ||
|
||||
PropertySymbol.SetMethodOrBaseSetMethod() is { IsInitOnly: true };
|
||||
public bool IsWriteOnly => PropertySymbol.IsWriteOnly;
|
||||
}
|
||||
|
||||
public readonly struct GodotFieldData
|
||||
|
@ -56,6 +60,8 @@ namespace Godot.SourceGenerators
|
|||
|
||||
public IFieldSymbol FieldSymbol { get; }
|
||||
public MarshalType Type { get; }
|
||||
|
||||
public bool IsReadOnly => FieldSymbol.IsReadOnly;
|
||||
}
|
||||
|
||||
public struct GodotPropertyOrFieldData
|
||||
|
|
|
@ -176,8 +176,7 @@ namespace Godot.SourceGenerators
|
|||
|
||||
// Generate SetGodotClassPropertyValue
|
||||
|
||||
bool allPropertiesAreReadOnly = godotClassFields.All(fi => fi.FieldSymbol.IsReadOnly) &&
|
||||
godotClassProperties.All(pi => pi.PropertySymbol.IsReadOnly || pi.PropertySymbol.SetMethod!.IsInitOnly);
|
||||
bool allPropertiesAreReadOnly = godotClassFields.All(fi => fi.IsReadOnly) && godotClassProperties.All(pi => pi.IsReadOnly);
|
||||
|
||||
if (!allPropertiesAreReadOnly)
|
||||
{
|
||||
|
@ -188,7 +187,7 @@ namespace Godot.SourceGenerators
|
|||
|
||||
foreach (var property in godotClassProperties)
|
||||
{
|
||||
if (property.PropertySymbol.IsReadOnly || property.PropertySymbol.SetMethod!.IsInitOnly)
|
||||
if (property.IsReadOnly)
|
||||
continue;
|
||||
|
||||
GeneratePropertySetter(property.PropertySymbol.Name,
|
||||
|
@ -197,7 +196,7 @@ namespace Godot.SourceGenerators
|
|||
|
||||
foreach (var field in godotClassFields)
|
||||
{
|
||||
if (field.FieldSymbol.IsReadOnly)
|
||||
if (field.IsReadOnly)
|
||||
continue;
|
||||
|
||||
GeneratePropertySetter(field.FieldSymbol.Name,
|
||||
|
@ -210,7 +209,7 @@ namespace Godot.SourceGenerators
|
|||
}
|
||||
|
||||
// Generate GetGodotClassPropertyValue
|
||||
bool allPropertiesAreWriteOnly = godotClassFields.Length == 0 && godotClassProperties.All(pi => pi.PropertySymbol.IsWriteOnly);
|
||||
bool allPropertiesAreWriteOnly = godotClassFields.Length == 0 && godotClassProperties.All(pi => pi.IsWriteOnly);
|
||||
|
||||
if (!allPropertiesAreWriteOnly)
|
||||
{
|
||||
|
@ -423,7 +422,7 @@ namespace Godot.SourceGenerators
|
|||
|
||||
if (exportAttr != null && propertySymbol != null)
|
||||
{
|
||||
if (propertySymbol.GetMethod == null)
|
||||
if (propertySymbol.GetMethodOrBaseGetMethod() is null)
|
||||
{
|
||||
// This should never happen, as we filtered WriteOnly properties, but just in case.
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
|
@ -434,7 +433,7 @@ namespace Godot.SourceGenerators
|
|||
return null;
|
||||
}
|
||||
|
||||
if (propertySymbol.SetMethod == null || propertySymbol.SetMethod.IsInitOnly)
|
||||
if (propertySymbol.SetMethodOrBaseSetMethod() is not { IsInitOnly: false })
|
||||
{
|
||||
// This should never happen, as we filtered ReadOnly properties, but just in case.
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
|
|
|
@ -163,7 +163,7 @@ namespace Godot.SourceGenerators
|
|||
continue;
|
||||
}
|
||||
|
||||
if (property.IsReadOnly || property.SetMethod!.IsInitOnly)
|
||||
if (property.IsReadOnly || property.SetMethodOrBaseSetMethod() is not { IsInitOnly: false })
|
||||
{
|
||||
context.ReportDiagnostic(Diagnostic.Create(
|
||||
Common.ExportedMemberIsReadOnlyRule,
|
||||
|
|
|
@ -123,10 +123,12 @@ namespace Godot.SourceGenerators
|
|||
|
||||
// TODO: We should still restore read-only properties after reloading assembly. Two possible ways: reflection or turn RestoreGodotObjectData into a constructor overload.
|
||||
// Ignore properties without a getter, without a setter or with an init-only setter. Godot properties must be both readable and writable.
|
||||
var godotClassProperties = propertySymbols.Where(property => !(property.IsReadOnly || property.IsWriteOnly || property.SetMethod!.IsInitOnly))
|
||||
var godotClassProperties = propertySymbols
|
||||
.Where(property => !(property.IsReadOnly || property.IsWriteOnly) && property.SetMethodOrBaseSetMethod() is { IsInitOnly: false })
|
||||
.WhereIsGodotCompatibleType(typeCache)
|
||||
.ToArray();
|
||||
var godotClassFields = fieldSymbols.Where(property => !property.IsReadOnly)
|
||||
var godotClassFields = fieldSymbols
|
||||
.Where(property => !property.IsReadOnly)
|
||||
.WhereIsGodotCompatibleType(typeCache)
|
||||
.ToArray();
|
||||
|
||||
|
|
|
@ -7260,6 +7260,10 @@ void RenderingDevice::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(DEBUG_PASS);
|
||||
}
|
||||
|
||||
void RenderingDevice::make_current() {
|
||||
render_thread_id = Thread::get_caller_id();
|
||||
}
|
||||
|
||||
RenderingDevice::~RenderingDevice() {
|
||||
finalize();
|
||||
|
||||
|
|
|
@ -1496,6 +1496,8 @@ public:
|
|||
|
||||
static RenderingDevice *get_singleton();
|
||||
|
||||
void make_current();
|
||||
|
||||
RenderingDevice();
|
||||
~RenderingDevice();
|
||||
|
||||
|
|
|
@ -370,6 +370,8 @@ Size2i RenderingServerDefault::get_maximum_viewport_size() const {
|
|||
void RenderingServerDefault::_assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id) {
|
||||
server_thread = Thread::get_caller_id();
|
||||
server_task_id = p_pump_task_id;
|
||||
// This is needed because the main RD is created on the main thread.
|
||||
RenderingDevice::get_singleton()->make_current();
|
||||
}
|
||||
|
||||
void RenderingServerDefault::_thread_exit() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user