Repository: godotengine/godot
File: scene/resources/animation.h (C/C++)

Code before:
	void remove_marker(const StringName &p_name);
	bool has_marker(const StringName &p_name) const;
	StringName get_marker_at_time(double p_time) const;
	StringName get_next_marker(double p_time) const;
	StringName get_prev_marker(double p_time) const;
	double get_marker_time(const StringName &p_time) const;
	PackedStringArray get_marker_names() const;
	Color get_marker_color(const StringName &p_name) const;
	void set_marker_color(const StringName &p_name, const Color &p_color);

	void set_length(real_t p_length);
	real_t get_length() const;

	void set_loop_mode(LoopMode p_loop_mode);
	LoopMode get_loop_mode() const;

	void set_step(real_t p_step);
	real_t get_step() const;

	void clear();

	void optimize(real_t p_allowed_velocity_err = 0.01, real_t p_allowed_angular_err = 0.01, int p_precision = 3);
	void compress(uint32_t p_page_size = 8192, uint32_t p_fps = 120, float p_split_tolerance = 4.0); // 4.0 seems to be the split tolerance sweet spot from many tests.

#ifdef TOOLS_ENABLED
	HashSet<StringName> editor_get_folded_groups() const { return folded_groups; }
	void editor_clear_folded_groups() { folded_groups.clear(); }
	void editor_add_folded_group(const StringName &p_group_name) { folded_groups.insert(p_group_name); }
	void editor_remove_folded_group(const StringName &p_group_name) { folded_groups.erase(p_group_name); }
	bool editor_is_group_folded(const StringName &p_group_name) const { return folded_groups.has(p_group_name); }
	void editor_set_group_folded(const StringName &p_group_name, bool p_folded) {
		if (p_folded) {
			editor_add_folded_group(p_group_name);
		} else {
			editor_remove_folded_group(p_group_name);
		}
	}
#endif // TOOLS_ENABLED

	// Helper functions for Rotation.
	static double interpolate_via_rest(double p_from, double p_to, double p_weight, double p_rest = 0.0); // Deterministic slerp to prevent to cross the inverted rest axis.
	static Quaternion interpolate_via_rest(const Quaternion &p_from, const Quaternion &p_to, real_t p_weight, const Quaternion &p_rest = Quaternion()); // Deterministic slerp to prevent to cross the inverted rest axis.

	// Helper functions for Variant.
	static bool is_variant_interpolatable(const Variant p_value);
	static bool validate_type_match(const Variant &p_from, Variant &r_to);

	static Variant cast_to_blendwise(const Variant p_value);
	static Variant cast_from_blendwise(const Variant p_value, const Variant::Type p_type);

	static Variant string_to_array(const Variant p_value);

Review comment (suggestion):
Copy constructors for `HashSet` are now explicit[^1]; pass by reference instead:
```suggestion
	const HashSet<StringName> &editor_get_folded_groups() const { return folded_groups; }
```
[^1]: #116381

Code after:
	void remove_marker(const StringName &p_name);
	bool has_marker(const StringName &p_name) const;
	StringName get_marker_at_time(double p_time) const;
	StringName get_next_marker(double p_time) const;
	StringName get_prev_marker(double p_time) const;
	double get_marker_time(const StringName &p_time) const;
	PackedStringArray get_marker_names() const;
	Color get_marker_color(const StringName &p_name) const;
	void set_marker_color(const StringName &p_name, const Color &p_color);

	void set_length(real_t p_length);
	real_t get_length() const;

	void set_loop_mode(LoopMode p_loop_mode);
	LoopMode get_loop_mode() const;

	void set_step(real_t p_step);
	real_t get_step() const;

	void clear();

	void optimize(real_t p_allowed_velocity_err = 0.01, real_t p_allowed_angular_err = 0.01, int p_precision = 3);
	void compress(uint32_t p_page_size = 8192, uint32_t p_fps = 120, float p_split_tolerance = 4.0); // 4.0 seems to be the split tolerance sweet spot from many tests.

#ifdef TOOLS_ENABLED
	const HashSet<StringName> &editor_get_folded_groups() const { return folded_groups; }
	void editor_clear_folded_groups() { folded_groups.clear(); }
	void editor_add_folded_group(const StringName &p_group_name) { folded_groups.insert(p_group_name); }
	void editor_remove_folded_group(const StringName &p_group_name) { folded_groups.erase(p_group_name); }
	bool editor_is_group_folded(const StringName &p_group_name) const { return folded_groups.has(p_group_name); }
	void editor_set_group_folded(const StringName &p_group_name, bool p_folded) {
		if (p_folded) {
			editor_add_folded_group(p_group_name);
		} else {
			editor_remove_folded_group(p_group_name);
		}
	}
#endif // TOOLS_ENABLED

	// Helper functions for Rotation.
	static double interpolate_via_rest(double p_from, double p_to, double p_weight, double p_rest = 0.0); // Deterministic slerp to prevent to cross the inverted rest axis.
	static Quaternion interpolate_via_rest(const Quaternion &p_from, const Quaternion &p_to, real_t p_weight, const Quaternion &p_rest = Quaternion()); // Deterministic slerp to prevent to cross the inverted rest axis.

	// Helper functions for Variant.
	static bool is_variant_interpolatable(const Variant p_value);
	static bool validate_type_match(const Variant &p_from, Variant &r_to);

	static Variant cast_to_blendwise(const Variant p_value);
	static Variant cast_from_blendwise(const Variant p_value, const Variant::Type p_type);

	static Variant string_to_array(const Variant p_value);