Rework modules

This commit is contained in:
Jérôme Leclercq
2020-09-10 20:12:09 +02:00
parent 385927b05a
commit a7fac3beb8
31 changed files with 568 additions and 787 deletions

View File

@@ -8,24 +8,26 @@
#define NAZARA_CORE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Module.hpp>
#include <Nazara/Core/TypeList.hpp>
namespace Nz
{
class NAZARA_CORE_API Core
class NAZARA_CORE_API Core : public Module<Core>
{
friend Module;
public:
Core() = delete;
~Core() = delete;
using Dependencies = TypeList<>;
static bool Initialize();
static bool IsInitialized();
static void Uninitialize();
Core();
~Core();
private:
static unsigned int s_moduleReferenceCounter;
static Core* s_instance;
};
}
#include <Nazara/Core/Core.inl>
#endif // NAZARA_CORE_HPP

View File

@@ -0,0 +1,12 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Core.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,40 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_MODULE_HPP
#define NAZARA_MODULE_HPP
#include <Nazara/Prerequisites.hpp>
#include <string>
namespace Nz
{
template<typename T>
class Module
{
friend class Core;
public:
static T* Instance();
protected:
Module(std::string moduleName, T* pointer);
~Module();
private:
struct NoLog {};
Module(std::string moduleName, T* pointer, NoLog);
void LogInit();
std::string m_moduleName;
};
}
#include <Nazara/Core/Module.inl>
#endif // NAZARA_MODULE_HPP

View File

@@ -0,0 +1,46 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Module.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
template<typename T>
Module<T>::Module(std::string moduleName, T* pointer) :
Module(std::move(moduleName), pointer, NoLog{})
{
LogInit();
}
template<typename T>
Module<T>::Module(std::string moduleName, T* pointer, NoLog) :
m_moduleName(std::move(moduleName))
{
NazaraAssert(T::s_instance == nullptr, "only one instance of " + m_moduleName + " must exist at a given time");
T::s_instance = pointer;
}
template<typename T>
Module<T>::~Module()
{
NazaraNotice("Uninitializing " + m_moduleName + "...");
T::s_instance = nullptr;
}
template<typename T>
T* Module<T>::Instance()
{
return T::s_instance;
}
template<typename T>
void Module<T>::LogInit()
{
NazaraNotice("Initializing " + m_moduleName + "...");
}
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,48 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_MODULES_HPP
#define NAZARA_MODULES_HPP
#include <Nazara/Core/TypeList.hpp>
namespace Nz
{
namespace Detail
{
template<typename>
struct BuildDepList;
template<typename Module, typename... Modules>
struct ModuleTuple : ModuleTuple<Module>, ModuleTuple<Modules...>
{
};
template<typename Module>
struct ModuleTuple<Module>
{
Module m;
};
}
template<typename... ModuleList>
class Modules
{
public:
Modules() = default;
~Modules() = default;
private:
using OrderedModuleList = TypeListUnique<typename Detail::BuildDepList<TypeList<ModuleList...>>::Result>;
using Tuple = TypeListInstantiate<OrderedModuleList, Detail::ModuleTuple>;
Tuple m_modules;
};
}
#include <Nazara/Core/Modules.inl>
#endif

View File

@@ -0,0 +1,26 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Modules.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz::Detail
{
template<>
struct BuildDepList<TypeList<>>
{
using Result = TypeList<>;
};
template<typename Module, typename... ModuleList>
struct BuildDepList<TypeList<Module, ModuleList...>>
{
using ModuleDependencies = typename BuildDepList<typename Module::Dependencies>::Result;
using ModuleDependenciesIncModule = TypeListAppend<ModuleDependencies, Module>;
using RestDependencies = typename BuildDepList<TypeList<ModuleList...>>::Result;
using Result = TypeListConcat<ModuleDependenciesIncModule, RestDependencies>;
};
}
#include <Nazara/Core/DebugOff.hpp>

View File

@@ -0,0 +1,64 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_TYPELIST_HPP
#define NAZARA_TYPELIST_HPP
#include <cstddef>
namespace Nz
{
template<typename...> struct TypeList {};
namespace Detail
{
template<typename, typename>
struct ListAppend;
template<typename, std::size_t>
struct ListAt;
template<typename, typename>
struct ListConcat;
template<typename, typename>
struct ListFind;
template<typename, template<typename...> typename>
struct ListInstantiate;
template<typename, typename>
struct ListPrepend;
template<typename, typename>
struct ListUnique;
}
template<typename List, typename NewType>
using TypeListAppend = typename Detail::ListAppend<List, NewType>::Result;
template<typename List, std::size_t Index>
using TypeListAt = typename Detail::ListAt<List, Index>::Type;
template<typename FirstList, typename SecondList>
using TypeListConcat = typename Detail::ListConcat<FirstList, SecondList>::Result;
template<typename List, typename Type>
constexpr bool TypeListFind = Detail::ListFind<List, Type>::Find();
template<typename List, template<typename...> typename Class>
using TypeListInstantiate = typename Detail::ListInstantiate<List, Class>::Result;
template<typename List, typename NewType>
using TypeListPrepend = typename Detail::ListPrepend<List, NewType>::Result;
template<typename List>
using TypeListUnique = typename Detail::ListUnique<TypeList<>, List>::Result;
}
#include <Nazara/Core/TypeList.inl>
#endif // NAZARA_TYPELIST_HPP

View File

@@ -0,0 +1,112 @@
// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/TypeList.hpp>
#include <type_traits>
#include <Nazara/Core/Debug.hpp>
namespace Nz::Detail
{
template<typename NewType, typename... ListTypes>
struct ListAppend<TypeList<ListTypes...>, NewType>
{
using Result = TypeList<ListTypes..., NewType>;
};
template<typename T, typename... ListTypes>
struct ListAt<TypeList<T, ListTypes...>, 0>
{
using Type = T;
};
template<std::size_t Index, typename T, typename... ListTypes>
struct ListAt<TypeList<T, ListTypes...>, Index>
{
static_assert(Index <= sizeof...(ListTypes), "Index out of range");
using Type = typename ListAt<TypeList<ListTypes...>, Index - 1>::Type;
};
template<typename... First>
struct ListConcat<TypeList<First...>, TypeList<>>
{
using Result = TypeList<First...>;
};
template<typename... Second>
struct ListConcat<TypeList<>, TypeList<Second...>>
{
using Result = TypeList<Second...>;
};
template<typename... First, typename T>
struct ListConcat<TypeList<First...>, TypeList<T>>
{
using Result = TypeList<First..., T>;
};
template<typename... First, typename T1, typename T2, typename... Second>
struct ListConcat<TypeList<First...>, TypeList<T1, T2, Second...>>
{
using Result = typename ListConcat<TypeList<First..., T1>, TypeList<T2, Second...>>::Result;
};
struct ListFindHelper
{
template<typename ToFind, typename Type, typename... Rest> static constexpr bool Find()
{
if constexpr (std::is_same_v<ToFind, Type>)
return true;
else
return Find<ToFind, Rest...>();
}
template<typename ToFind> static constexpr bool Find()
{
return false;
}
};
template<typename TypeToFind, typename... ListTypes>
struct ListFind<TypeList<ListTypes...>, TypeToFind>
{
static constexpr bool Find()
{
return ListFindHelper::Find<TypeToFind, ListTypes...>();
}
};
template<template<typename...> typename Class, typename... ListTypes>
struct ListInstantiate<TypeList<ListTypes...>, Class>
{
using Result = Class<ListTypes...>;
};
template<typename NewType, typename... ListTypes>
struct ListPrepend<TypeList<ListTypes...>, NewType>
{
using Result = TypeList<NewType, ListTypes...>;
};
template<typename... Types, typename T1>
struct ListUnique<TypeList<Types...>, TypeList<T1>>
{
static constexpr bool IsTypePresent = ListFind<TypeList<Types...>, T1>::Find();
using Result = std::conditional_t<!IsTypePresent, TypeList<Types..., T1>, TypeList<Types...>>;
};
template<typename... Types, typename T1, typename T2, typename... Rest>
struct ListUnique<TypeList<Types...>, TypeList<T1, T2, Rest...>>
{
using Result = typename ListUnique<typename ListUnique<TypeList<Types...>, TypeList<T1>>::Result, TypeList<T2, Rest...>>::Result;
};
}
#include <Nazara/Core/DebugOff.hpp>