Optimize out a lot of std::string construction and allocations (#415)

Update CommandLineParameters.hpp

Update CommandLineParametersTests.cpp

Update WebContext.hpp

xmake check-files -f

Fix MaterialPassRegistry
This commit is contained in:
Jérôme Leclercq
2023-12-30 14:50:57 +01:00
committed by GitHub
parent f7c9060364
commit 79ec135af7
57 changed files with 219 additions and 210 deletions

View File

@@ -55,7 +55,7 @@ namespace Nz
Integer: 0 is interpreted as false, any other value is interpreted as true
std::string: Conversion obeys the rule as described by std::string::ToBool
*/
auto ParameterList::GetBooleanParameter(const std::string& name, bool strict) const -> Result<bool, Error>
auto ParameterList::GetBooleanParameter(std::string_view name, bool strict) const -> Result<bool, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -105,7 +105,7 @@ namespace Nz
*
* \remark If the parameter is not a color, the function fails
*/
auto ParameterList::GetColorParameter(const std::string& name, bool /*strict*/) const -> Result<Color, Error>
auto ParameterList::GetColorParameter(std::string_view name, bool /*strict*/) const -> Result<Color, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -140,7 +140,7 @@ namespace Nz
Integer: The integer value is converted to its double representation
std::string: Conversion obeys the rule as described by std::string::ToDouble
*/
auto ParameterList::GetDoubleParameter(const std::string& name, bool strict) const -> Result<double, Error>
auto ParameterList::GetDoubleParameter(std::string_view name, bool strict) const -> Result<double, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -199,7 +199,7 @@ namespace Nz
Double: The floating-point value is truncated and converted to a integer
std::string: Conversion obeys the rule as described by std::string::ToInteger
*/
auto ParameterList::GetIntegerParameter(const std::string& name, bool strict) const -> Result<long long, Error>
auto ParameterList::GetIntegerParameter(std::string_view name, bool strict) const -> Result<long long, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -259,7 +259,7 @@ namespace Nz
*
* \remark type must be a valid pointer to a ParameterType variable
*/
auto ParameterList::GetParameterType(const std::string& name) const -> Result<ParameterType, Error>
auto ParameterList::GetParameterType(std::string_view name) const -> Result<ParameterType, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -278,7 +278,7 @@ namespace Nz
* \remark If the parameter is not a pointer, a conversion may be performed if strict parameter is set to false, compatibles types are:
Userdata: The pointer part of the userdata is returned
*/
auto ParameterList::GetPointerParameter(const std::string& name, bool strict) const -> Result<void*, Error>
auto ParameterList::GetPointerParameter(std::string_view name, bool strict) const -> Result<void*, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -323,7 +323,7 @@ namespace Nz
Pointer: Conversion obeys the rules of PointerToString
Userdata: Conversion obeys the rules of PointerToString
*/
auto ParameterList::GetStringParameter(const std::string& name, bool strict) const -> Result<std::string, Error>
auto ParameterList::GetStringParameter(std::string_view name, bool strict) const -> Result<std::string, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -391,7 +391,7 @@ namespace Nz
Boolean: A string view containing true or false
None: An empty string view is returned
*/
auto ParameterList::GetStringViewParameter(const std::string& name, bool strict) const -> Result<std::string_view, Error>
auto ParameterList::GetStringViewParameter(std::string_view name, bool strict) const -> Result<std::string_view, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -436,7 +436,7 @@ namespace Nz
*
* \see GetPointerParameter
*/
auto ParameterList::GetUserdataParameter(const std::string& name, bool /*strict*/) const -> Result<void*, Error>
auto ParameterList::GetUserdataParameter(std::string_view name, bool /*strict*/) const -> Result<void*, Error>
{
auto it = m_parameters.find(name);
if (it == m_parameters.end())
@@ -456,7 +456,7 @@ namespace Nz
*
* \param name Name of the parameter
*/
bool ParameterList::HasParameter(const std::string& name) const
bool ParameterList::HasParameter(std::string_view name) const
{
return m_parameters.find(name) != m_parameters.end();
}
@@ -469,7 +469,7 @@ namespace Nz
*
* \param name Name of the parameter
*/
void ParameterList::RemoveParameter(const std::string& name)
void ParameterList::RemoveParameter(std::string_view name)
{
auto it = m_parameters.find(name);
if (it != m_parameters.end())

View File

@@ -5,6 +5,7 @@
#include <Nazara/Graphics/Formats/PipelinePassListLoader.hpp>
#include <Nazara/Core/ParameterFile.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <NazaraUtils/StringHash.hpp>
#include <optional>
#include <Nazara/Graphics/Debug.hpp>
@@ -183,7 +184,7 @@ namespace Nz::Loaders
throw ResourceLoadingError::DecodingError;
}
std::size_t passId = m_current->passList->AddPass(passName, implIndex, std::move(implConfig));
std::size_t passId = m_current->passList->AddPass(std::move(passName), implIndex, std::move(implConfig));
for (auto&& [inputName, attachmentName] : inputs)
{
@@ -262,7 +263,7 @@ namespace Nz::Loaders
struct CurrentPassList
{
std::shared_ptr<PipelinePassList> passList;
std::unordered_map<std::string /*attachmentName*/, std::size_t /*attachmentId*/> attachmentsByName;
std::unordered_map<std::string /*attachmentName*/, std::size_t /*attachmentId*/, StringHash<>, std::equal_to<>> attachmentsByName;
};
std::optional<CurrentPassList> m_current;

View File

@@ -35,7 +35,7 @@ namespace Nz
ExternalBlockData* externalBlock = nullptr;
if (!node.tag.empty())
{
if (m_externalBlocks.find(node.tag) != m_externalBlocks.end())
if (m_externalBlocks.contains(node.tag))
throw std::runtime_error("duplicate tag " + node.tag);
externalBlock = &m_externalBlocks[node.tag];
@@ -90,7 +90,7 @@ namespace Nz
{
case ShaderBindingType::Sampler:
{
if (externalBlock->samplers.find(externalVar.tag) != externalBlock->samplers.end())
if (externalBlock->samplers.contains(externalVar.tag))
throw std::runtime_error("duplicate sampler tag " + externalVar.tag + " in external block " + node.tag);
const auto& samplerType = std::get<nzsl::Ast::SamplerType>(*varType);
@@ -105,7 +105,7 @@ namespace Nz
case ShaderBindingType::StorageBuffer:
{
if (externalBlock->storageBlocks.find(externalVar.tag) != externalBlock->storageBlocks.end())
if (externalBlock->storageBlocks.contains(externalVar.tag))
throw std::runtime_error("duplicate storage buffer tag " + externalVar.tag + " in external block " + node.tag);
ExternalStorageBlock& storageBuffer = externalBlock->storageBlocks[externalVar.tag];
@@ -117,7 +117,7 @@ namespace Nz
case ShaderBindingType::Texture:
{
if (externalBlock->textures.find(externalVar.tag) != externalBlock->textures.end())
if (externalBlock->textures.contains(externalVar.tag))
throw std::runtime_error("duplicate textures tag " + externalVar.tag + " in external block " + node.tag);
const auto& textureType = std::get<nzsl::Ast::TextureType>(*varType);
@@ -134,7 +134,7 @@ namespace Nz
case ShaderBindingType::UniformBuffer:
{
if (externalBlock->uniformBlocks.find(externalVar.tag) != externalBlock->uniformBlocks.end())
if (externalBlock->uniformBlocks.contains(externalVar.tag))
throw std::runtime_error("duplicate storage buffer tag " + externalVar.tag + " in external block " + node.tag);
ExternalUniformBlock& uniformBuffer = externalBlock->uniformBlocks[externalVar.tag];

View File

@@ -38,7 +38,7 @@ namespace Nz
m_onShaderModuleUpdated.Connect(moduleResolver.OnModuleUpdated, [this, name = std::move(moduleName)](nzsl::ModuleResolver* resolver, const std::string& updatedModuleName)
{
if (m_usedModules.find(updatedModuleName) == m_usedModules.end())
if (!m_usedModules.contains(updatedModuleName))
return;
nzsl::Ast::ModulePtr newShaderModule = resolver->Resolve(name);
@@ -108,7 +108,7 @@ namespace Nz
return it->second;
}
nzsl::Ast::ModulePtr UberShader::Validate(const nzsl::Ast::Module& module, std::unordered_map<std::string, Option>* options)
nzsl::Ast::ModulePtr UberShader::Validate(const nzsl::Ast::Module& module, std::unordered_map<std::string, Option, StringHash<>, std::equal_to<>>* options)
{
NazaraAssert(m_shaderStages != 0, "there must be at least one shader stage");
assert(options);
@@ -132,7 +132,7 @@ namespace Nz
supportedStageType |= stageType;
};
std::unordered_map<std::string, Option> optionByName;
std::unordered_map<std::string, Option, StringHash<>, std::equal_to<>> optionByName;
callbacks.onOptionDeclaration = [&](const nzsl::Ast::DeclareOptionStatement& option)
{
//TODO: Check optionType

View File

@@ -17,7 +17,7 @@ namespace Nz
{
struct AnimationImpl
{
std::unordered_map<std::string, std::size_t> sequenceMap;
std::unordered_map<std::string, std::size_t, StringHash<>, std::equal_to<>> sequenceMap;
std::vector<Sequence> sequences;
std::vector<SequenceJoint> sequenceJoints; // Uniquement pour les animations squelettiques
AnimationType type;
@@ -47,7 +47,7 @@ namespace Nz
Animation::Animation(Animation&&) noexcept = default;
Animation::~Animation() = default;
bool Animation::AddSequence(const Sequence& sequence)
bool Animation::AddSequence(Sequence sequence)
{
NazaraAssert(m_impl, "Animation not created");
NazaraAssert(sequence.frameCount > 0, "Sequence frame count must be over zero");
@@ -76,7 +76,7 @@ namespace Nz
m_impl->sequenceMap[sequence.name] = static_cast<std::size_t>(m_impl->sequences.size());
}
m_impl->sequences.push_back(sequence);
m_impl->sequences.emplace_back(std::move(sequence));
return true;
}
@@ -145,7 +145,7 @@ namespace Nz
return m_impl->jointCount;
}
Sequence* Animation::GetSequence(const std::string& sequenceName)
Sequence* Animation::GetSequence(std::string_view sequenceName)
{
NazaraAssert(m_impl, "Animation not created");
@@ -167,7 +167,7 @@ namespace Nz
return &m_impl->sequences[index];
}
const Sequence* Animation::GetSequence(const std::string& sequenceName) const
const Sequence* Animation::GetSequence(std::string_view sequenceName) const
{
NazaraAssert(m_impl, "Animation not created");
@@ -196,7 +196,7 @@ namespace Nz
return static_cast<std::size_t>(m_impl->sequences.size());
}
std::size_t Animation::GetSequenceIndex(const std::string& sequenceName) const
std::size_t Animation::GetSequenceIndex(std::string_view sequenceName) const
{
NazaraAssert(m_impl, "Animation not created");
@@ -233,7 +233,7 @@ namespace Nz
return m_impl->type;
}
bool Animation::HasSequence(const std::string& sequenceName) const
bool Animation::HasSequence(std::string_view sequenceName) const
{
NazaraAssert(m_impl, "Animation not created");
@@ -259,7 +259,7 @@ namespace Nz
return m_impl != nullptr;
}
void Animation::RemoveSequence(const std::string& identifier)
void Animation::RemoveSequence(std::string_view identifier)
{
NazaraAssert(m_impl, "Animation not created");

View File

@@ -262,7 +262,7 @@ namespace Nz
return true;
}
void MD5AnimParser::Error(const std::string& message)
void MD5AnimParser::Error(std::string_view message)
{
NazaraErrorFmt("{0} at line #{1}", message, m_lineCount);
}
@@ -504,14 +504,14 @@ namespace Nz
return true;
}
void MD5AnimParser::Warning(const std::string& message)
void MD5AnimParser::Warning(std::string_view message)
{
NazaraWarning(message + " at line #" + NumberToString(m_lineCount));
NazaraWarningFmt("{0} at line #{1}", message, m_lineCount);
}
void MD5AnimParser::UnrecognizedLine(bool error)
{
std::string message = "Unrecognized \"" + m_currentLine + '"';
std::string message = "unrecognized \"" + m_currentLine + '"';
if (error)
Error(message);

View File

@@ -209,7 +209,7 @@ namespace Nz
return true;
}
void MD5MeshParser::Error(const std::string& message)
void MD5MeshParser::Error(std::string_view message)
{
NazaraErrorFmt("{0} on line #{1}", message, m_lineCount);
}
@@ -444,14 +444,14 @@ namespace Nz
return true;
}
void MD5MeshParser::Warning(const std::string& message)
void MD5MeshParser::Warning(std::string_view message)
{
NazaraWarningFmt("{0} on line #{1}", message, m_lineCount);
}
void MD5MeshParser::UnrecognizedLine(bool error)
{
std::string message = "Unrecognized \"" + m_currentLine + '"';
std::string message = "unrecognized \"" + m_currentLine + '"';
if (error)
Error(message);

View File

@@ -14,7 +14,7 @@ namespace Nz
namespace
{
template<std::size_t N>
bool TestKeyword(const std::string& currentLine, const char(&keyword)[N], std::size_t& offset)
bool TestKeyword(std::string_view currentLine, const char(&keyword)[N], std::size_t& offset)
{
if (currentLine.size() > N && StartsWith(currentLine, keyword, CaseIndependent{}) && std::isspace(currentLine[N - 1]))
{

View File

@@ -57,7 +57,7 @@ namespace Nz
return (extension == ".obj");
}
bool SaveOBJToStream(const Mesh& mesh, const std::string& format, Stream& stream, const MeshParams& parameters)
bool SaveOBJToStream(const Mesh& mesh, std::string_view format, Stream& stream, const MeshParams& parameters)
{
NAZARA_USE_ANONYMOUS_NAMESPACE

View File

@@ -235,7 +235,7 @@ namespace Nz
return s_formatHandlers.find(extension) != s_formatHandlers.end();
}
bool SaveToStream(const Image& image, const std::string& format, Stream& stream, const ImageParams& parameters)
bool SaveToStream(const Image& image, std::string_view format, Stream& stream, const ImageParams& parameters)
{
NazaraUnused(parameters);
@@ -252,7 +252,7 @@ namespace Nz
return false;
}
auto it = s_formatHandlers.find(std::string_view(format));
auto it = s_formatHandlers.find(format);
NazaraAssert(it != s_formatHandlers.end(), "Invalid handler");
const FormatHandler& handler = it->second;

View File

@@ -1146,7 +1146,7 @@ namespace Nz
return utility->GetImageSaver().SaveToFile(*this, filePath, params);
}
bool Image::SaveToStream(Stream& stream, const std::string& format, const ImageParams& params)
bool Image::SaveToStream(Stream& stream, std::string_view format, const ImageParams& params)
{
Utility* utility = Utility::Instance();
NazaraAssert(utility, "Utility module has not been initialized");

View File

@@ -55,19 +55,18 @@ namespace Nz
InvalidateAABB();
}
void Mesh::AddSubMesh(const std::string& identifier, std::shared_ptr<SubMesh> subMesh)
void Mesh::AddSubMesh(std::string identifier, std::shared_ptr<SubMesh> subMesh)
{
NazaraAssert(m_isValid, "Mesh should be created first");
NazaraAssert(!identifier.empty(), "Identifier is empty");
NazaraAssert(m_subMeshMap.find(identifier) == m_subMeshMap.end(), "SubMesh identifier \"" + identifier + "\" is already in use");
NazaraAssert(subMesh, "Invalid submesh");
NazaraAssert(!identifier.empty(), "empty identifier");
NazaraAssertFmt(!m_subMeshMap.contains(identifier), "SubMesh identifier \"{0}\" is already in use", identifier);
NazaraAssert(subMesh, "invalid submesh");
NazaraAssert(subMesh->GetAnimationType() == m_animationType, "Submesh animation type doesn't match mesh animation type");
std::size_t index = m_subMeshes.size();
AddSubMesh(std::move(subMesh));
m_subMeshMap[identifier] = static_cast<std::size_t>(index);
m_subMeshMap.emplace(std::move(identifier), index);
}
std::shared_ptr<SubMesh> Mesh::BuildSubMesh(const Primitive& primitive, const MeshParams& params)
@@ -404,12 +403,12 @@ namespace Nz
return &m_skeleton;
}
const std::shared_ptr<SubMesh>& Mesh::GetSubMesh(const std::string& identifier) const
const std::shared_ptr<SubMesh>& Mesh::GetSubMesh(std::string_view identifier) const
{
NazaraAssert(m_isValid, "Mesh should be created first");
auto it = m_subMeshMap.find(identifier);
NazaraAssert(it != m_subMeshMap.end(), "SubMesh " + identifier + " not found");
NazaraAssertFmt(it != m_subMeshMap.end(), "SubMesh {0} not found", identifier);
return m_subMeshes[it->second].subMesh;
}
@@ -429,12 +428,12 @@ namespace Nz
return static_cast<std::size_t>(m_subMeshes.size());
}
std::size_t Mesh::GetSubMeshIndex(const std::string& identifier) const
std::size_t Mesh::GetSubMeshIndex(std::string_view identifier) const
{
NazaraAssert(m_isValid, "Mesh should be created first");
auto it = m_subMeshMap.find(identifier);
NazaraAssert(it != m_subMeshMap.end(), "SubMesh " + identifier + " not found");
NazaraAssertFmt(it != m_subMeshMap.end(), "SubMesh {0} not found", identifier);
return it->second;
}
@@ -470,17 +469,15 @@ namespace Nz
OnMeshInvalidateAABB(this);
}
bool Mesh::HasSubMesh(const std::string& identifier) const
bool Mesh::HasSubMesh(std::string_view identifier) const
{
NazaraAssert(m_isValid, "Mesh should be created first");
return m_subMeshMap.find(identifier) != m_subMeshMap.end();
return m_subMeshMap.contains(identifier);
}
bool Mesh::HasSubMesh(std::size_t index) const
{
NazaraAssert(m_isValid, "Mesh should be created first");
return index < m_subMeshes.size();
}
@@ -523,7 +520,7 @@ namespace Nz
}
}
void Mesh::RemoveSubMesh(const std::string& identifier)
void Mesh::RemoveSubMesh(std::string_view identifier)
{
std::size_t index = GetSubMeshIndex(identifier);
RemoveSubMesh(index);
@@ -554,7 +551,7 @@ namespace Nz
return utility->GetMeshSaver().SaveToFile(*this, filePath, params);
}
bool Mesh::SaveToStream(Stream& stream, const std::string& format, const MeshParams& params)
bool Mesh::SaveToStream(Stream& stream, std::string_view format, const MeshParams& params)
{
Utility* utility = Utility::Instance();
NazaraAssert(utility, "Utility module has not been initialized");
@@ -584,7 +581,7 @@ namespace Nz
m_materialData.resize(matCount);
#ifdef NAZARA_DEBUG
#ifdef NAZARA_DEBUG
for (SubMeshData& data : m_subMeshes)
{
std::size_t matIndex = data.subMesh->GetMaterialIndex();
@@ -594,7 +591,7 @@ namespace Nz
NazaraWarning("SubMesh " + PointerToString(data.subMesh.get()) + " material index is over mesh new material count (" + NumberToString(matIndex) + " >= " + NumberToString(matCount) + "), setting it to first material");
}
}
#endif
#endif
}
void Mesh::Transform(const Matrix4f& matrix)

View File

@@ -4,6 +4,7 @@
#include <Nazara/Utility/Skeleton.hpp>
#include <Nazara/Utility/Joint.hpp>
#include <NazaraUtils/StringHash.hpp>
#include <unordered_map>
#include <Nazara/Utility/Debug.hpp>
@@ -11,7 +12,7 @@ namespace Nz
{
struct SkeletonImpl
{
std::unordered_map<std::string, std::size_t> jointMap;
std::unordered_map<std::string, std::size_t, StringHash<>, std::equal_to<>> jointMap;
std::vector<Joint> joints;
Boxf aabb;
bool aabbUpdated = false;
@@ -68,7 +69,7 @@ namespace Nz
return m_impl->aabb;
}
Joint* Skeleton::GetJoint(const std::string& jointName)
Joint* Skeleton::GetJoint(std::string_view jointName)
{
NazaraAssert(m_impl, "skeleton must have been created");
@@ -91,7 +92,7 @@ namespace Nz
return &m_impl->joints[index];
}
const Joint* Skeleton::GetJoint(const std::string& jointName) const
const Joint* Skeleton::GetJoint(std::string_view jointName) const
{
NazaraAssert(m_impl, "skeleton must have been created");
@@ -132,7 +133,7 @@ namespace Nz
return static_cast<std::size_t>(m_impl->joints.size());
}
std::size_t Skeleton::GetJointIndex(const std::string& jointName) const
std::size_t Skeleton::GetJointIndex(std::string_view jointName) const
{
NazaraAssert(m_impl, "skeleton must have been created");
@@ -259,9 +260,8 @@ namespace Nz
const std::string& name = m_impl->joints[i].GetName();
if (!name.empty())
{
NazaraAssert(m_impl->jointMap.find(name) == m_impl->jointMap.end(), "Joint name \"" + name + "\" is already present in joint map");
m_impl->jointMap[name] = static_cast<std::size_t>(i);
NazaraAssertFmt(!m_impl->jointMap.contains(name), "Joint name \{0}\" is already present in joint map", name);
m_impl->jointMap.emplace(name, i);
}
}

View File

@@ -11,6 +11,7 @@
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
#include <NazaraUtils/Algorithm.hpp>
#include <NazaraUtils/CallOnExit.hpp>
#include <NazaraUtils/StringHash.hpp>
#include <array>
#include <unordered_set>
#include <Nazara/VulkanRenderer/Debug.hpp>
@@ -22,11 +23,11 @@ namespace Nz
struct AvailableVulkanLayer
{
VkLayerProperties layerProperties;
std::unordered_map<std::string, std::size_t> extensionByName;
std::unordered_map<std::string, std::size_t, StringHash<>, std::equal_to<>> extensionByName;
std::vector<VkExtensionProperties> extensionList;
};
void EnumerateVulkanLayers(std::vector<AvailableVulkanLayer>& availableLayers, std::unordered_map<std::string, std::size_t>& layerByName)
void EnumerateVulkanLayers(std::vector<AvailableVulkanLayer>& availableLayers, std::unordered_map<std::string, std::size_t, StringHash<>, std::equal_to<>>& layerByName)
{
std::vector<VkLayerProperties> layerList;
if (Vk::Loader::EnumerateInstanceLayerProperties(&layerList))
@@ -175,7 +176,7 @@ namespace Nz
std::vector<const char*> enabledLayers;
std::vector<AvailableVulkanLayer> availableLayers;
std::unordered_map<std::string, std::size_t> availableLayerByName;
std::unordered_map<std::string, std::size_t, StringHash<>, std::equal_to<>> availableLayerByName;
EnumerateVulkanLayers(availableLayers, availableLayerByName);
if (auto result = parameters.GetBooleanParameter("VkInstanceInfo_OverrideEnabledLayers"); !result.GetValueOr(false))
@@ -211,12 +212,12 @@ namespace Nz
}
// Get supported extension list
std::unordered_set<std::string> availableExtensions;
std::unordered_set<std::string, StringHash<>, std::equal_to<>> availableExtensions;
std::vector<VkExtensionProperties> extensionList;
if (Vk::Loader::EnumerateInstanceExtensionProperties(&extensionList))
{
for (VkExtensionProperties& extProperty : extensionList)
availableExtensions.insert(extProperty.extensionName);
availableExtensions.emplace(extProperty.extensionName);
}
if (auto result = parameters.GetBooleanParameter("VkInstanceInfo_OverrideEnabledExtensions"); !result.GetValueOr(false))