bool kitchen::make_dependency_ready()

in src/native/diffs/core/kitchen.cpp [134:241]


bool kitchen::make_dependency_ready(
	const item_definition &item,
	bool select_recipes_only,
	std::set<item_definition> &mocked_items,
	std::set<item_definition> &already_using)
{
	if (mocked_items.contains(item))
	{
		return true;
	}

	if (m_selected_recipes.contains(item))
	{
		return true;
	}

	if (m_ready_items.contains(item))
	{
		return true;
	}

	if (m_unreachable_items.contains(item))
	{
		ADU_LOG("Item already determined unreachable: {}", item.to_string());
		return false;
	}

	for (auto &pantry : m_all_pantries)
	{
		std::shared_ptr<prepared_item> from_pantry;
		if (pantry->find(item, &from_pantry))
		{
			m_ready_items.insert(std::pair{item, from_pantry});
			return true;
		}
	}

	// Only check this after we've looked in the pantry to allow us to
	// use the pantry multiple times when only selecting recipes.
	if (already_using.contains(item))
	{
		return false;
	}
	else
	{
		already_using.insert(item);
	}

	for (auto &cookbook : m_all_cookbooks)
	{
		const recipe_set *recipes_for_item;
		if (!cookbook->find_recipes_for_item(item, &recipes_for_item))
		{
			continue;
		}

		for (auto &recipe : *recipes_for_item)
		{
			bool found_impossible_ingredient{false};
			item_definition impossible_item;

			std::vector<std::shared_ptr<prepared_item>> prepared_ingredients;

			auto &ingredients = recipe->get_item_ingredients();

			for (auto &ingredient : ingredients)
			{
				if (!make_dependency_ready(ingredient, select_recipes_only, mocked_items, already_using))
				{
					impossible_item = ingredient;

					ADU_LOG("Found impossible item {}, for: {}", ingredient.to_string(), item.to_string());

					found_impossible_ingredient = true;
					break;
				}
				prepared_ingredients.push_back(m_ready_items[ingredient]);
			}

			if (found_impossible_ingredient)
			{
				for (auto &ingredient : ingredients)
				{
					if (ingredient == impossible_item)
					{
						break;
					}
					already_using.erase(ingredient);
				}
				continue;
			}

			m_selected_recipes[item] = recipe;

			if (!select_recipes_only)
			{
				auto from_recipe = recipe->prepare(this, prepared_ingredients);
				m_ready_items.insert(std::pair{item, from_recipe});
			}

			return true;
		}
	}

	ADU_LOG("Couldn't make dependency: {}", item.to_string());

	return false;
}