Core/ApplicationBase: Replace component indices with hashes

Fixes usage of components across DLL
This commit is contained in:
SirLynix 2024-02-23 22:40:13 +01:00
parent 1cb1750a74
commit 23ea1989ef
6 changed files with 33 additions and 73 deletions

View File

@ -38,7 +38,6 @@
#include <Nazara/Core/Application.hpp>
#include <Nazara/Core/ApplicationBase.hpp>
#include <Nazara/Core/ApplicationComponent.hpp>
#include <Nazara/Core/ApplicationComponentRegistry.hpp>
#include <Nazara/Core/ApplicationUpdater.hpp>
#include <Nazara/Core/Buffer.hpp>
#include <Nazara/Core/BufferMapper.hpp>

View File

@ -14,7 +14,7 @@
#include <Nazara/Core/CommandLineParameters.hpp>
#include <atomic>
#include <string>
#include <vector>
#include <unordered_map>
namespace Nz
{
@ -72,7 +72,7 @@ namespace Nz
};
std::atomic_bool m_running;
std::vector<std::unique_ptr<ApplicationComponent>> m_components;
std::unordered_map<UInt64 /*typehash*/, std::unique_ptr<ApplicationComponent>> m_components;
std::vector<Updater> m_updaters;
CommandLineParameters m_commandLineParams;
HighPrecisionClock m_clock;

View File

@ -2,7 +2,6 @@
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Export.hpp
#include <Nazara/Core/ApplicationComponentRegistry.hpp>
#include <stdexcept>
namespace Nz
@ -57,31 +56,37 @@ namespace Nz
template<typename T>
T& ApplicationBase::GetComponent()
{
std::size_t componentIndex = ApplicationComponentRegistry<T>::GetComponentId();
if (componentIndex >= m_components.size() || !m_components[componentIndex])
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
auto it = m_components.find(typeHash);
if (it != m_components.end())
throw std::runtime_error("component not found");
return static_cast<T&>(*m_components[componentIndex]);
return static_cast<T&>(*it->second);
}
template<typename T>
const T& ApplicationBase::GetComponent() const
{
std::size_t componentIndex = ApplicationComponentRegistry<T>::GetComponentId();
if (componentIndex >= m_components.size() || !m_components[componentIndex])
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
auto it = m_components.find(typeHash);
if (it != m_components.end())
throw std::runtime_error("component not found");
return static_cast<const T&>(*m_components[componentIndex]);
return static_cast<const T&>(*it->second);
}
template<typename T>
bool ApplicationBase::HasComponent() const
{
std::size_t componentIndex = ApplicationComponentRegistry<T>::GetComponentId();
if (componentIndex >= m_components.size())
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
auto it = m_components.find(typeHash);
if (it != m_components.end())
return false;
return m_components[componentIndex] != nullptr;
return it->second != nullptr;
}
inline void ApplicationBase::Quit()
@ -92,21 +97,25 @@ namespace Nz
template<typename T>
T* ApplicationBase::TryGetComponent()
{
std::size_t componentIndex = ApplicationComponentRegistry<T>::GetComponentId();
if (componentIndex >= m_components.size())
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
auto it = m_components.find(typeHash);
if (it != m_components.end())
return nullptr;
return static_cast<T*>(m_components[componentIndex].get());
return static_cast<T*>(it->second.get());
}
template<typename T>
const T* ApplicationBase::TryGetComponent() const
{
std::size_t componentIndex = ApplicationComponentRegistry<T>::GetComponentId();
if (componentIndex >= m_components.size())
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
auto it = m_components.find(typeHash);
if (it != m_components.end())
return nullptr;
return static_cast<const T*>(m_components[componentIndex].get());
return static_cast<const T*>(it->second.get());
}
inline ApplicationBase* ApplicationBase::Instance()
@ -117,17 +126,15 @@ namespace Nz
template<typename T, typename... Args>
T& ApplicationBase::AddComponent(Args&&... args)
{
std::size_t componentIndex = ApplicationComponentRegistry<T>::GetComponentId();
constexpr UInt64 typeHash = FNV1a64(TypeName<T>());
std::unique_ptr<T> component = std::make_unique<T>(*this, std::forward<Args>(args)...);
T& componentRef = *component;
if (componentIndex >= m_components.size())
m_components.resize(componentIndex + 1);
else if (m_components[componentIndex] != nullptr)
if (m_components.contains(typeHash))
throw std::runtime_error("component was added multiple times");
m_components[componentIndex] = std::move(component);
m_components[typeHash] = std::move(component);
return componentRef;
}

View File

@ -1,24 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Export.hpp
#pragma once
#ifndef NAZARA_CORE_APPLICATIONCOMPONENTREGISTRY_HPP
#define NAZARA_CORE_APPLICATIONCOMPONENTREGISTRY_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/Export.hpp>
namespace Nz
{
template<typename T>
struct ApplicationComponentRegistry
{
static std::size_t GetComponentId();
};
}
#include <Nazara/Core/ApplicationComponentRegistry.inl>
#endif // NAZARA_CORE_APPLICATIONCOMPONENTREGISTRY_HPP

View File

@ -1,24 +0,0 @@
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Export.hpp
namespace Nz
{
namespace Detail
{
inline std::size_t ComponentCounter()
{
static std::size_t counter = 0;
return counter++;
}
}
template<typename T>
std::size_t ApplicationComponentRegistry<T>::GetComponentId()
{
static std::size_t typeId = Detail::ComponentCounter();
return typeId;
}
}

View File

@ -90,8 +90,10 @@ namespace Nz
updaterEntry.nextUpdate = std::max(updaterEntry.nextUpdate, m_currentTime);
}
for (auto& componentPtr : m_components)
for (auto&& [typeHash, componentPtr] : m_components)
{
NazaraUnused(typeHash);
if (componentPtr)
componentPtr->Update(elapsedTime);
}