Skip to content

Commit

Permalink
Merge pull request #81 from jss2a98aj/cherry-pick-4.4-mono
Browse files Browse the repository at this point in the history
[4.4 backport] Assorted C#/mono fixes
  • Loading branch information
Bioblaze authored Oct 19, 2024
2 parents 8816632 + 81495fe commit 9fb2d78
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 18 deletions.
8 changes: 4 additions & 4 deletions core/math/basis.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ struct [[nodiscard]] Basis {
Vector3(0, 0, 1)
};

_FORCE_INLINE_ const Vector3 &operator[](int p_axis) const {
return rows[p_axis];
_FORCE_INLINE_ const Vector3 &operator[](int p_row) const {
return rows[p_row];
}
_FORCE_INLINE_ Vector3 &operator[](int p_axis) {
return rows[p_axis];
_FORCE_INLINE_ Vector3 &operator[](int p_row) {
return rows[p_row];
}

void invert();
Expand Down
55 changes: 46 additions & 9 deletions modules/mono/csharp_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,18 @@ void CSharpLanguage::finalize() {

finalizing = true;

// Make sure all script binding gchandles are released before finalizing GDMono
// Make sure all script binding gchandles are released before finalizing GDMono.
for (KeyValue<Object *, CSharpScriptBinding> &E : script_bindings) {
CSharpScriptBinding &script_binding = E.value;

if (!script_binding.gchandle.is_released()) {
script_binding.gchandle.release();
script_binding.inited = false;
}

// Make sure we clear all the instance binding callbacks so they don't get called
// after finalizing the C# language.
script_binding.owner->free_instance_binding(this);
}

if (gdmono) {
Expand Down Expand Up @@ -1227,6 +1231,11 @@ void CSharpLanguage::_instance_binding_free_callback(void *, void *, void *p_bin
}

GDExtensionBool CSharpLanguage::_instance_binding_reference_callback(void *p_token, void *p_binding, GDExtensionBool p_reference) {
// Instance bindings callbacks can only be called if the C# language is available.
// Failing this assert usually means that we didn't clear the instance binding in some Object
// and the C# language has already been finalized.
DEV_ASSERT(CSharpLanguage::get_singleton() != nullptr);

CRASH_COND(!p_binding);

CSharpScriptBinding &script_binding = ((RBMap<Object *, CSharpScriptBinding>::Element *)p_binding)->get();
Expand Down Expand Up @@ -1488,11 +1497,23 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const {

void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
List<PropertyInfo> props;
script->get_script_property_list(&props);
ERR_FAIL_COND(!script.is_valid());
#ifdef TOOLS_ENABLED
for (const PropertyInfo &prop : script->exported_members_cache) {
props.push_back(prop);
}
#else
for (const KeyValue<StringName, PropertyInfo> &E : script->member_info) {
props.push_front(E.value);
}
#endif

// Call _get_property_list
for (PropertyInfo &prop : props) {
validate_property(prop);
p_properties->push_back(prop);
}

ERR_FAIL_COND(!script.is_valid());
// Call _get_property_list

StringName method = SNAME("_get_property_list");

Expand All @@ -1515,9 +1536,25 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
}
}

for (PropertyInfo &prop : props) {
validate_property(prop);
p_properties->push_back(prop);
CSharpScript *top = script.ptr()->base_script.ptr();
while (top != nullptr) {
props.clear();
#ifdef TOOLS_ENABLED
for (const PropertyInfo &prop : top->exported_members_cache) {
props.push_back(prop);
}
#else
for (const KeyValue<StringName, PropertyInfo> &E : top->member_info) {
props.push_front(E.value);
}
#endif

for (PropertyInfo &prop : props) {
validate_property(prop);
p_properties->push_back(prop);
}

top = top->base_script.ptr();
}
}

Expand Down Expand Up @@ -1662,7 +1699,7 @@ bool CSharpInstance::_reference_owner_unsafe() {
// but the managed instance is alive, the refcount will be 1 instead of 0.
// See: _unreference_owner_unsafe()

// May not me referenced yet, so we must use init_ref() instead of reference()
// May not be referenced yet, so we must use init_ref() instead of reference()
if (static_cast<RefCounted *>(owner)->init_ref()) {
CSharpLanguage::get_singleton()->post_unsafe_reference(owner);
unsafe_referenced = true;
Expand Down Expand Up @@ -2351,8 +2388,8 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
if (!ok) {
// Important to clear this before destroying the script instance here
instance->script = Ref<CSharpScript>();
instance->owner = nullptr;
p_owner->set_script_instance(nullptr);
instance->owner = nullptr;

return nullptr;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,11 @@ public void MethodWithAttributeRidArray()
public void MethodWithWrongAttribute()
{
}

[NestedGenericTypeAttributeContainer.NestedGenericTypeAttribute<bool>()]
public void MethodWithNestedAttribute()
{
}
}

[GenericTypeAttribute<bool>()]
Expand Down Expand Up @@ -657,3 +662,11 @@ public class ClassNonVariantAnnotated
public class GenericTypeAttribute<[MustBeVariant] T> : Attribute
{
}

public class NestedGenericTypeAttributeContainer
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class NestedGenericTypeAttribute<[MustBeVariant] T> : Attribute
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ private bool ShouldCheckTypeArgument(
{
ITypeParameterSymbol? typeParamSymbol = parentSymbol switch
{
IMethodSymbol methodSymbol when parentSyntax.Parent is AttributeSyntax &&
IMethodSymbol methodSymbol when parentSyntax.Ancestors().Any(s => s is AttributeSyntax) &&
methodSymbol.ContainingType.TypeParameters.Length > 0
=> methodSymbol.ContainingType.TypeParameters[typeArgumentIndex],

Expand Down
2 changes: 1 addition & 1 deletion modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ public ICollection<Variant> Values
var keys = Array.CreateTakingOwnershipOfDisposableValue(keysArray);

godot_array valuesArray;
NativeFuncs.godotsharp_dictionary_keys(ref self, out valuesArray);
NativeFuncs.godotsharp_dictionary_values(ref self, out valuesArray);
var values = Array.CreateTakingOwnershipOfDisposableValue(valuesArray);

int count = NativeFuncs.godotsharp_dictionary_count(ref self);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Godot.NativeInterop;

#nullable enable
Expand Down Expand Up @@ -51,7 +52,7 @@ public static bool IsInstanceIdValid(ulong id)
/// </summary>
/// <param name="instance">The instance to check.</param>
/// <returns>If the instance is a valid object.</returns>
public static bool IsInstanceValid(GodotObject? instance)
public static bool IsInstanceValid([NotNullWhen(true)] GodotObject? instance)
{
return instance != null && instance.NativeInstance != IntPtr.Zero;
}
Expand Down
4 changes: 2 additions & 2 deletions modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ public Transform3D(Projection projection)
{
for (int j = 0; j < 3; j++)
{
real_t e = transform.Basis[i][j] * min[j];
real_t f = transform.Basis[i][j] * max[j];
real_t e = transform.Basis[j][i] * min[j];
real_t f = transform.Basis[j][i] * max[j];
if (e < f)
{
tmin[i] += e;
Expand Down

0 comments on commit 9fb2d78

Please sign in to comment.