Repository: godotengine/godot
File: scene/animation/animation_tree.cpp (C++)

Code before:
	if (r_max) {
		*r_max = 0;
		for (int i = 0; i < blend_count; i++) {
			*r_max = MAX(*r_max, blendw[i]);
		}
	}

	String new_path;
	AnimationNode *new_parent;

	// This is the slowest part of processing, but as strings process in powers of 2, and the paths always exist, it will not result in that many allocations.
	if (p_new_parent) {
		new_parent = p_new_parent;
		new_path = String(base_path) + String(p_subpath) + "/";
	} else {
		ERR_FAIL_COND_V(!parent, 0);
		new_parent = parent;
		new_path = String(parent->base_path) + String(p_subpath) + "/";
	}

	// If tracks for blending don't exist for one of the animations, Rest or RESET animation is blended as init animation instead.
	// Then, blend weight is 0 means that the init animation blend weight is 1.
	// Therefore, the blending process must be executed even if the blend weight is 0.
	if (!p_seek && p_optimize && !any_valid) {
		return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_seek_root, p_connections);
	}
	return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_seek_root, p_connections);
}

int AnimationNode::get_input_count() const {
	return inputs.size();
}

String AnimationNode::get_input_name(int p_input) {
	ERR_FAIL_INDEX_V(p_input, inputs.size(), String());
	return inputs[p_input].name;
}

String AnimationNode::get_caption() const {
	String ret;
	if (GDVIRTUAL_CALL(_get_caption, ret)) {
		return ret;
	}

	return "Node";
}

void AnimationNode::add_input(const String &p_name) {
	//root nodes can't add inputs
	ERR_FAIL_COND(Object::cast_to<AnimationRootNode>(this) != nullptr);
	Input input;

Review comment (performance):
After blending algorithm was changed by #57675, `p_optimize` actually functioned only as `!sync`. `p_optimize` is replaced by `p_sync` and logical negation (`false` -> `true`) of the function arguments at each part.

Code after:
	if (r_max) {
		*r_max = 0;
		for (int i = 0; i < blend_count; i++) {
			*r_max = MAX(*r_max, blendw[i]);
		}
	}

	String new_path;
	AnimationNode *new_parent;

	// This is the slowest part of processing, but as strings process in powers of 2, and the paths always exist, it will not result in that many allocations.
	if (p_new_parent) {
		new_parent = p_new_parent;
		new_path = String(base_path) + String(p_subpath) + "/";
	} else {
		ERR_FAIL_COND_V(!parent, 0);
		new_parent = parent;
		new_path = String(parent->base_path) + String(p_subpath) + "/";
	}

	// If tracks for blending don't exist for one of the animations, Rest or RESET animation is blended as init animation instead.
	// Then blend weight is 0 means that the init animation blend weight is 1.
	// In that case, processing only the animation with the lacking track will not process the lacking track, and will not properly apply the Reset value.
	// This means that all tracks which the animations in the branch that may be blended have must be processed.
	// Therefore, the blending process must be executed even if the blend weight is 0.
	if (!p_seek && !p_sync && !any_valid) {
		return p_node->_pre_process(new_path, new_parent, state, 0, p_seek, p_seek_root, p_connections);
	}
	return p_node->_pre_process(new_path, new_parent, state, p_time, p_seek, p_seek_root, p_connections);
}

int AnimationNode::get_input_count() const {
	return inputs.size();
}

String AnimationNode::get_input_name(int p_input) {
	ERR_FAIL_INDEX_V(p_input, inputs.size(), String());
	return inputs[p_input].name;
}

String AnimationNode::get_caption() const {
	String ret;
	if (GDVIRTUAL_CALL(_get_caption, ret)) {
		return ret;
	}

	return "Node";
}

void AnimationNode::add_input(const String &p_name) {
	//root nodes can't add inputs