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

Audio: Copy filters array in setFilters #20105

Merged
merged 2 commits into from
Oct 26, 2020

Conversation

takahirox
Copy link
Collaborator

@takahirox takahirox commented Aug 18, 2020

Problem this PR fixes

Audio.setFilters() stores a reference to passed array to Audio.filters.

setFilters( value ) {

	if ( ! value ) value = [];

	if ( this._connected === true ) {

		this.disconnect();
		this.filters = value;  // stores reference
		this.connect();

	} else {

		this.filters = value;  // stores reference

	}

	return this;

}

Then for example in the following example, an operation to filters array can have an effect to audio.filters even out of Audio. I don't think this is expected behavior for users.

const audio = new Audio(listener);
const filters = [audio.context.createGain()];
audio.setFilters(filters);
filters.pop(); // This operation has an effect to audio.filters

How this PR fixes

I'd like to suggest copying an array in Audio.setFilters() instead of storing a reference. In the above example an operation to filters won't have an effect to audio.filters. I think it would be better capsulation.

Copy link
Collaborator

@Mugen87 Mugen87 left a comment

Choose a reason for hiding this comment

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

I think this change makes senes. At other places in the engine (e.g. Box3.set()), object arguments are not assigned but copied to the respective target properties, too.

@mrdoob
Copy link
Owner

mrdoob commented Aug 18, 2020

I'd let javascript do its thing:

this.filters = value.slice(); // clone array

@mrdoob mrdoob added this to the r120 milestone Aug 18, 2020
@takahirox
Copy link
Collaborator Author

I'd let javascript do its thing:

this.filters = value.slice(); // clone array

If I'm right, mine is more memory efficient than this.filters = value.slice() because mine reuses this.filters array while this.filters = value.slice() throws away old this.filters array and creating a new copy of value array. this.filters = value.slice() would provide more pressure for Garbage Collection than mine.

But I know Audio.setFilters may not be a function called so often. So it may be ok to prioritize readability by sacrificing memory efficiency.

What do you think? If you still prefer this.filters = value.slice(), I would rewrite.

@mrdoob
Copy link
Owner

mrdoob commented Aug 18, 2020

Yeah, I suspect Audio.setFilters wouldn't be called that often so readability may be worth it in this case.

@takahirox
Copy link
Collaborator Author

takahirox commented Aug 18, 2020

Thanks for the answer. Yeah it would be reasonable.

I noticed one more difference between them.

const audio = new Audio(listener);
audio.setFilters([audio.context.createGain()]);
const filters = audio.getFilters();
audio.setFilters([]); // Whether should this line have an effect to `filters` or not?

Mine reuses Audio.filters then the second audio.setFilters() have an effect to filters in the above example because filters keeps holding Audio.filters.

The current implementation or this.filters = value.slice() throws away an old array and Audio.filters points to a new array, then the second audio.setFilters() doesn't have an effect to filters. filters holds old Audio.filters.

Which one should be right behavior do you think? I don't have strong opinion about it.

@takahirox
Copy link
Collaborator Author

Replaced with this.filters = value.slice()

@mrdoob mrdoob modified the milestones: r120, r121 Aug 25, 2020
@mrdoob mrdoob modified the milestones: r121, r122 Sep 29, 2020
@Mugen87
Copy link
Collaborator

Mugen87 commented Oct 26, 2020

@mrdoob I think this PR is good to go 👍 .

@mrdoob mrdoob merged commit 956292c into mrdoob:dev Oct 26, 2020
@mrdoob
Copy link
Owner

mrdoob commented Oct 26, 2020

Thanks!

@takahirox takahirox deleted the AudioSetFiltersCopy branch October 26, 2020 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants