// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com) // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include namespace Nz { inline ApplicationBase::ApplicationBase() : ApplicationBase(0, static_cast(nullptr)) { } inline ApplicationBase::ApplicationBase(int argc, char** argv) : ApplicationBase(argc, const_cast*>(argv)) { } inline void ApplicationBase::AddUpdater(std::unique_ptr&& functor) { auto& updaterEntry = m_updaters.emplace_back(); updaterEntry.lastUpdate = -Time::Nanosecond(); updaterEntry.nextUpdate = Time::Zero(); updaterEntry.updater = std::move(functor); } template void ApplicationBase::AddUpdaterFunc(F&& functor) { static_assert(std::is_invocable_v || std::is_invocable_v, "functor must be callable with either a Time parameter or no parameter"); return AddUpdater(std::make_unique>>(std::forward(functor))); } template void ApplicationBase::AddUpdaterFunc(FixedInterval fixedInterval, F&& functor) { return AddUpdaterFunc(fixedInterval.interval, std::forward(functor)); } template void ApplicationBase::AddUpdaterFunc(Interval interval, F&& functor) { return AddUpdaterFunc(interval.interval, std::forward(functor)); } inline void ApplicationBase::ClearComponents() { m_components.clear(); } template T& ApplicationBase::GetComponent() { std::size_t componentIndex = ApplicationComponentRegistry::GetComponentId(); if (componentIndex >= m_components.size() || !m_components[componentIndex]) throw std::runtime_error("component not found"); return static_cast(*m_components[componentIndex]); } template const T& ApplicationBase::GetComponent() const { std::size_t componentIndex = ApplicationComponentRegistry::GetComponentId(); if (componentIndex >= m_components.size() || !m_components[componentIndex]) throw std::runtime_error("component not found"); return static_cast(*m_components[componentIndex]); } inline void ApplicationBase::Quit() { m_running = false; } template T& ApplicationBase::AddComponent(Args&&... args) { std::size_t componentIndex = ApplicationComponentRegistry::GetComponentId(); std::unique_ptr component = std::make_unique(*this, std::forward(args)...); T& componentRef = *component; if (componentIndex >= m_components.size()) m_components.resize(componentIndex + 1); else if (m_components[componentIndex] != nullptr) throw std::runtime_error("component was added multiple times"); m_components[componentIndex] = std::move(component); return componentRef; } template void ApplicationBase::AddUpdaterFunc(Time interval, F&& functor) { if constexpr (std::is_invocable_r_v || std::is_invocable_r_v) return AddUpdater(std::make_unique, Fixed>>(std::forward(functor), interval)); else if constexpr (std::is_invocable_r_v || std::is_invocable_r_v) return AddUpdater(std::make_unique>>(std::forward(functor))); else static_assert(AlwaysFalse(), "functor must be callable with either elapsed time or nothing and return void or next update time"); } } #include