Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RDPipelineColorBlendState.attachments setter #81333

Merged

Conversation

dalexeev
Copy link
Member

@dalexeev dalexeev commented Sep 5, 2023

Fixes the error

  Attempted to push_back a variable of type 'Array' into a TypedArray of type 'Object'.
  core/variant/array.cpp:269 - Condition "!_p->typed.validate(value, "push_back")" is true.
var pcbs = RDPipelineColorBlendState.new()
var attachment = RDPipelineColorBlendStateAttachment.new()
attachment.enable_blend = true
attachment.alpha_blend_op = RenderingDevice.BLEND_OP_ADD
attachment.color_blend_op = RenderingDevice.BLEND_OP_ADD
attachment.src_color_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA
attachment.dst_color_blend_factor = RenderingDevice.BLEND_FACTOR_ONE
attachment.src_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_SRC_ALPHA
attachment.dst_alpha_blend_factor = RenderingDevice.BLEND_FACTOR_ONE
var attachments : Array[RDPipelineColorBlendStateAttachment] = [ attachment ]
pcbs.attachments = attachments

CC @BastiaanOlij

@dalexeev dalexeev added this to the 4.2 milestone Sep 5, 2023
@dalexeev dalexeev requested a review from a team as a code owner September 5, 2023 10:06
Comment on lines 699 to 700
attachments.clear();
attachments.append_array(p_attachments);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
attachments.clear();
attachments.append_array(p_attachments);
attachments = p_attachments;

is_same(attachments, p_attachments) can be true, the code will not work in this case.

@dalexeev dalexeev marked this pull request as draft September 5, 2023 10:32
Copy link
Contributor

@BastiaanOlij BastiaanOlij left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder why the original code was this way, thanks for fixing, looks great!

@dalexeev
Copy link
Member Author

dalexeev commented Sep 5, 2023

I marked this as a draft because I don't think the current solution is fully correct. Must be one of the following:

Option 1

void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) {
    attachments.clear();
    attachments.append_array(p_attachments);
}

TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const {
    return attachments.duplicate();
}

Option 2

void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) {
    attachments = p_attachments;
}

TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const {
    return attachments;
}

I checked the setters and getters of other non-Object properties of pass-by-reference types (arrays and dictionaries don't have signals to track external change, unlike resources). This is inconsistent.

@dalexeev dalexeev force-pushed the fix-rd-pcbs-attachments-setter branch from 5b0b046 to f2f0375 Compare September 5, 2023 12:30
@dalexeev dalexeev marked this pull request as ready for review September 5, 2023 12:32
@BastiaanOlij
Copy link
Contributor

@dalexeev the pass by reference is only to prevent a parameter copy (and thus ending up with two copies being made), it still duplicates the content of the array.

I think option #2 is clearer, and as far as I can test works fine.

@dalexeev
Copy link
Member Author

dalexeev commented Sep 6, 2023

@BastiaanOlij Option 2 is the current option? Your comment confused me, sorry.

@BastiaanOlij
Copy link
Contributor

@dalexeev I mean in relation to this:

I checked the setters and getters of other non-Object properties of pass-by-reference types (arrays and dictionaries don't have signals to track external change, unlike resources). This is inconsistent.

We're not storing a reference, we're only passing by reference to prevent an extra copy overhead.
So if you do:

pcbs.attachments = attachments
attachments.push_back(another_attachment)

There is no expectation that that pcbs sees the new attachment. The list of attachments has already been copied. It's not like a resource where a pointer to the original array is kept and changes to the array after assign still effect things.

So:

void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) {
    attachments = p_attachments;
}

TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const {
    return attachments;
}

Does exactly what we want and keeps the code concise.

@akien-mga
Copy link
Member

So TL;DR, Bastiaan approved without hitting the "Approve" button ;)

@akien-mga akien-mga merged commit 698df41 into godotengine:master Sep 7, 2023
15 checks passed
@akien-mga
Copy link
Member

Thanks!

@dalexeev dalexeev deleted the fix-rd-pcbs-attachments-setter branch September 7, 2023 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants