add module
This commit is contained in:
commit
1d96f31f52
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.vs/
|
||||
.vscode/.cache/
|
||||
.vscode/compile_commands.json
|
||||
.xmake/
|
||||
build/
|
||||
vsxmake*/
|
||||
/tools
|
||||
0
engine/modules/editor/xmake.lua
Normal file
0
engine/modules/editor/xmake.lua
Normal file
0
engine/modules/engine/asset/include/asset/asset.h
Normal file
0
engine/modules/engine/asset/include/asset/asset.h
Normal file
0
engine/modules/engine/asset/src/asset.cpp
Normal file
0
engine/modules/engine/asset/src/asset.cpp
Normal file
5
engine/modules/engine/asset/xmake.lua
Normal file
5
engine/modules/engine/asset/xmake.lua
Normal file
@ -0,0 +1,5 @@
|
||||
static_component("asset","engine")
|
||||
add_includedirs("include/asset")
|
||||
add_headerfiles("include/**.h")
|
||||
add_files("src/**.cpp")
|
||||
add_deps("core", {public = true})
|
||||
25
engine/modules/engine/core/include/module/module.inl
Normal file
25
engine/modules/engine/core/include/module/module.inl
Normal file
@ -0,0 +1,25 @@
|
||||
namespace api {
|
||||
struct IDynamicModule : public IModule {
|
||||
virtual ~IDynamicModule() override
|
||||
{
|
||||
}
|
||||
SharedLibrary mSharedLib;
|
||||
};
|
||||
struct IStaticModule : public IModule {
|
||||
};
|
||||
struct IHotfixModule : public IDynamicModule {
|
||||
void* state = nullptr;
|
||||
//IHotfixModule(){ mInfo.flag |= EModuleFlag::Reload; }
|
||||
virtual void OnBeginLoad() = 0;
|
||||
virtual void OnEndLoad() = 0;
|
||||
};
|
||||
}
|
||||
#define IMPLEMENT_STATIC_MODULE(ModuleImplClass, ModuleName) \
|
||||
inline static const api::ModuleRegistrantImpl<ModuleImplClass> __RegisterModule##ModuleName((const char*)#ModuleName);
|
||||
|
||||
#define IMPLEMENT_DYNAMIC_MODULE(ModuleImplClass, ModuleName) \
|
||||
extern "C" api::IModule* __newDynamicModule##ModuleName() \
|
||||
{ \
|
||||
return new ModuleImplClass(); \
|
||||
}
|
||||
#define MODULE_DEPENDENCY(name, opt)
|
||||
31
engine/modules/engine/core/include/module/module_manager.h
Normal file
31
engine/modules/engine/core/include/module/module_manager.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "moudle.h"
|
||||
namespace api {
|
||||
template<typename T1, typename T2, typename Hasher = std::hash<T1>>
|
||||
using table = std::pmr::unordered_map<T1, T2, Hasher>;
|
||||
class ModuleManager
|
||||
{
|
||||
friend struct IModule;
|
||||
private:
|
||||
SharedLibrary mProcessLib;
|
||||
table<Name, IModule*> mModuleTable;
|
||||
public:
|
||||
ModuleManager() = default;
|
||||
IModule* GetModule(Name name);
|
||||
bool RegisterModule(Name name, IModule::CreatePFN fn);
|
||||
static ModuleManager* Ptr();
|
||||
};
|
||||
struct empty {
|
||||
|
||||
};
|
||||
static empty e;
|
||||
template <typename ModuleClass>
|
||||
struct ModuleRegistrantImpl {
|
||||
ModuleRegistrantImpl(const char* InModuleName)
|
||||
{
|
||||
ModuleManager::Ptr()->RegisterModule(InModuleName, []() {
|
||||
return new ModuleClass();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
58
engine/modules/engine/core/include/module/moudle.h
Normal file
58
engine/modules/engine/core/include/module/moudle.h
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include "pmr/name.h"
|
||||
#include "macro.h"
|
||||
#include "os/shared_library.h"
|
||||
namespace api {
|
||||
using pmr::Name;
|
||||
enum class EModuleFlag : uint32_t {
|
||||
Reload = 1,
|
||||
};
|
||||
ENABLE_BITMASK_OPERATORS(EModuleFlag);
|
||||
struct ModuleInfo {
|
||||
EModuleFlag flag;
|
||||
Name name; //!< name of the plugin
|
||||
Name prettyname; //!< formatted name of the plugin
|
||||
Name core_version; //!< version of the engine
|
||||
Name version; // !< version of the plugin
|
||||
Name linking; // !< linking of the plugin
|
||||
Name license; //!< license of the plugin
|
||||
Name url; //!< url of the plugin
|
||||
Name copyright; //!< copyright of the plugin
|
||||
public:
|
||||
bool IsReload() {
|
||||
return !!(flag & EModuleFlag::Reload);
|
||||
}
|
||||
};
|
||||
struct IModuleSubsystem
|
||||
{
|
||||
using CreatePFN = IModuleSubsystem* (*)();
|
||||
virtual ~IModuleSubsystem() = default;
|
||||
virtual void Initialize() = 0;
|
||||
virtual void Finalize() = 0;
|
||||
virtual void BeginLoad() {}
|
||||
virtual void EndLoad() {}
|
||||
};
|
||||
struct IModule {
|
||||
friend class ModuleManagerImpl;
|
||||
public:
|
||||
using CreatePFN = IModule * (*)();
|
||||
IModule() = default;
|
||||
IModule(const IModule& rhs) = delete;
|
||||
IModule& operator=(const IModule& rhs) = delete;
|
||||
virtual ~IModule() {};
|
||||
|
||||
virtual void OnLoad(int argc, char** argv) = 0;
|
||||
virtual void OnUnload() = 0;
|
||||
virtual const char* MetaData(void) = 0;
|
||||
|
||||
virtual int Main(int argc, char** argv) { return 0; }
|
||||
virtual const ModuleInfo* GetModuleInfo()
|
||||
{
|
||||
return &mInfo;
|
||||
}
|
||||
protected:
|
||||
ModuleInfo mInfo;
|
||||
std::vector<IModuleSubsystem*> mSubSystems;
|
||||
};
|
||||
}
|
||||
#include "module.inl"
|
||||
5
engine/modules/engine/core/include/os/file_system.h
Normal file
5
engine/modules/engine/core/include/os/file_system.h
Normal file
@ -0,0 +1,5 @@
|
||||
#include <string>
|
||||
namespace fs {
|
||||
std::string GetExecutablePath();
|
||||
std::string GetWorkPath();
|
||||
}
|
||||
9
engine/modules/engine/core/include/os/shared_library.h
Normal file
9
engine/modules/engine/core/include/os/shared_library.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
namespace api {
|
||||
using NativeLibHandle = void*;
|
||||
class SharedLibrary {
|
||||
NativeLibHandle mHandle;
|
||||
public:
|
||||
bool Load(const char* path = nullptr);
|
||||
};
|
||||
}
|
||||
0
engine/modules/engine/core/include/pch.h
Normal file
0
engine/modules/engine/core/include/pch.h
Normal file
0
engine/modules/engine/core/src/module/module.cpp
Normal file
0
engine/modules/engine/core/src/module/module.cpp
Normal file
25
engine/modules/engine/core/src/module/module_manager.cpp
Normal file
25
engine/modules/engine/core/src/module/module_manager.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include "module/module_manager.h"
|
||||
namespace api {
|
||||
ModuleManager* ModuleManager::Ptr()
|
||||
{
|
||||
static ModuleManager* ptr;
|
||||
if (ptr) {
|
||||
return ptr;
|
||||
}
|
||||
ptr = new ModuleManager();
|
||||
ptr->mProcessLib.Load();
|
||||
return ptr;
|
||||
}
|
||||
IModule* ModuleManager::GetModule(Name name)
|
||||
{
|
||||
auto it = mModuleTable.find(name);
|
||||
if (it == mModuleTable.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
bool ModuleManager::RegisterModule(Name name, IModule::CreatePFN fn)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
47
engine/modules/engine/core/src/os/file_system.cpp
Normal file
47
engine/modules/engine/core/src/os/file_system.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include "os/file_system.h"
|
||||
#include <filesystem>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#elif __linux__
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#elif __APPLE__
|
||||
#include <mach-o/dyld.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
namespace fs {
|
||||
|
||||
std::string _GetExecutablePath() {
|
||||
#ifdef _WIN32
|
||||
char path[MAX_PATH];
|
||||
GetModuleFileName(NULL, path, MAX_PATH);
|
||||
return std::string(path);
|
||||
#elif __linux__
|
||||
char result[PATH_MAX];
|
||||
ssize_t count = readlink("/proc/self/exe", result, PATH_MAX);
|
||||
return std::string(result, (count > 0) ? count : 0);
|
||||
#elif __APPLE__
|
||||
char path[PATH_MAX];
|
||||
uint32_t size = sizeof(path);
|
||||
if (_NSGetExecutablePath(path, &size) == 0) {
|
||||
char realPath[PATH_MAX];
|
||||
realpath(path, realPath);
|
||||
return std::string(realPath);
|
||||
}
|
||||
else {
|
||||
return std::string("");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
std::string GetExecutablePath() {
|
||||
std::string path = _GetExecutablePath();
|
||||
size_t pos = path.find_last_of("\\/");
|
||||
return (std::string::npos == pos) ? "" : path.substr(0, pos);
|
||||
}
|
||||
std::string GetWorkPath() {
|
||||
auto path = std::filesystem::current_path();
|
||||
return path.string();
|
||||
}
|
||||
|
||||
}
|
||||
21
engine/modules/engine/core/src/os/shared_library.cpp
Normal file
21
engine/modules/engine/core/src/os/shared_library.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "os/shared_library.h"
|
||||
#include <Windows.h>
|
||||
namespace api {
|
||||
bool SharedLibrary::Load(const char* path)
|
||||
{
|
||||
if (path == nullptr)
|
||||
{
|
||||
mHandle = GetModuleHandle(nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
mHandle = GetModuleHandle(path);
|
||||
if (mHandle == NULL)
|
||||
{
|
||||
mHandle = LoadLibrary(path);
|
||||
}
|
||||
}
|
||||
return mHandle;
|
||||
}
|
||||
}
|
||||
|
||||
6
engine/modules/engine/core/xmake.lua
Normal file
6
engine/modules/engine/core/xmake.lua
Normal file
@ -0,0 +1,6 @@
|
||||
static_component("core","engine")
|
||||
add_includedirs("include", {public = true})
|
||||
add_headerfiles("include/**.h","include/**.inl")
|
||||
add_files("src/**.cpp")
|
||||
add_deps("zlib", {public = true})
|
||||
--add_syslinks("Kernel32")
|
||||
9
engine/modules/engine/zlib/include/macro.h
Normal file
9
engine/modules/engine/zlib/include/macro.h
Normal file
@ -0,0 +1,9 @@
|
||||
#define ENABLE_BITMASK_OPERATORS(bitmask) \
|
||||
inline bitmask operator|(bitmask a, bitmask b) { return static_cast<bitmask>(static_cast<std::underlying_type_t<bitmask>>(a) | static_cast<std::underlying_type_t<bitmask>>(b)); } \
|
||||
inline bitmask operator&(bitmask a, bitmask b) { return static_cast<bitmask>(static_cast<std::underlying_type_t<bitmask>>(a) & static_cast<std::underlying_type_t<bitmask>>(b)); } \
|
||||
inline bitmask operator^(bitmask a, bitmask b) { return static_cast<bitmask>(static_cast<std::underlying_type_t<bitmask>>(a) ^ static_cast<std::underlying_type_t<bitmask>>(b)); } \
|
||||
inline bitmask operator~(bitmask a) { return static_cast<bitmask>(~static_cast<std::underlying_type_t<bitmask>>(a)); } \
|
||||
inline bitmask &operator|=(bitmask &a, bitmask b) { return a = a | b; } \
|
||||
inline bitmask &operator&=(bitmask &a, bitmask b) { return a = a & b; } \
|
||||
inline bitmask &operator^=(bitmask &a, bitmask b) { return a = a ^ b; } \
|
||||
inline bool operator!(bitmask a){return static_cast<std::underlying_type_t<bitmask>>(a) == 0;}
|
||||
47
engine/modules/engine/zlib/include/pmr/frame_allocator.h
Normal file
47
engine/modules/engine/zlib/include/pmr/frame_allocator.h
Normal file
@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <memory_resource>
|
||||
namespace pmr {
|
||||
class FrameAllocator : public std::pmr::memory_resource {
|
||||
private:
|
||||
char* buffer;
|
||||
size_t capacity;
|
||||
size_t offset;
|
||||
public:
|
||||
// 删除拷贝构造函数
|
||||
FrameAllocator(const FrameAllocator&) = delete;
|
||||
FrameAllocator& operator=(const FrameAllocator&) = delete;
|
||||
FrameAllocator(FrameAllocator&& o) noexcept;
|
||||
FrameAllocator& operator=(FrameAllocator&& o)noexcept;
|
||||
public:
|
||||
FrameAllocator(size_t size) noexcept;
|
||||
~FrameAllocator() noexcept;
|
||||
bool empty() const { return offset == 0; }
|
||||
void reset() { offset = 0; };
|
||||
void* try_allocate(size_t bytes, size_t alignment);
|
||||
protected:
|
||||
void move_clear() { buffer = nullptr; capacity = 0; offset = 0; };
|
||||
void* do_allocate(size_t bytes, size_t alignment) override;
|
||||
void do_deallocate(void* p, size_t bytes, size_t alignment) override {};
|
||||
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { return this == &other; };
|
||||
};
|
||||
class FrameAllocatorPool : public std::pmr::memory_resource {
|
||||
public:
|
||||
FrameAllocatorPool(size_t allocatorSize = 1024 * 1024) noexcept : allocatorSize(allocatorSize) {}
|
||||
|
||||
void* allocate(size_t bytes, size_t alignment);
|
||||
void reset();
|
||||
void* do_allocate(size_t bytes, size_t alignment) override { return allocate(bytes, alignment); }
|
||||
void do_deallocate(void* p, size_t bytes, size_t alignment) override {};
|
||||
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override { return this == &other; };
|
||||
private:
|
||||
size_t allocatorSize;
|
||||
std::vector<FrameAllocator> allocators{};
|
||||
};
|
||||
};
|
||||
// 自定义的new操作符
|
||||
inline void* operator new(size_t size, pmr::FrameAllocatorPool& pool, size_t alignment = alignof(std::max_align_t)) {
|
||||
size = (size + alignment - 1) & ~(alignment - 1);
|
||||
return pool.allocate(size, alignment);
|
||||
}
|
||||
#include "frame_allocator.inl"
|
||||
62
engine/modules/engine/zlib/include/pmr/frame_allocator.inl
Normal file
62
engine/modules/engine/zlib/include/pmr/frame_allocator.inl
Normal file
@ -0,0 +1,62 @@
|
||||
namespace pmr {
|
||||
inline FrameAllocator& FrameAllocator::operator=(FrameAllocator&& o)noexcept
|
||||
{
|
||||
std::construct_at(this, std::forward<FrameAllocator&&>(o));
|
||||
return *this;
|
||||
}
|
||||
inline FrameAllocator::FrameAllocator(FrameAllocator&& o) noexcept :buffer(o.buffer),capacity(o.capacity),offset(o.offset)
|
||||
{
|
||||
o.move_clear();
|
||||
}
|
||||
inline FrameAllocator::FrameAllocator(size_t size)noexcept
|
||||
{
|
||||
buffer = new char[size];
|
||||
capacity = size;
|
||||
offset = 0;
|
||||
}
|
||||
inline FrameAllocator::~FrameAllocator()noexcept
|
||||
{
|
||||
if(buffer)
|
||||
delete[] buffer;
|
||||
}
|
||||
inline void* FrameAllocator::try_allocate(size_t bytes, size_t alignment)
|
||||
{
|
||||
if (capacity - offset > bytes) {
|
||||
return do_allocate(bytes, alignment);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
inline void* FrameAllocator::do_allocate(size_t bytes, size_t alignment)
|
||||
{
|
||||
size_t space = capacity - offset;
|
||||
void* ptr = buffer + offset;
|
||||
if (std::align(alignment, bytes, ptr, space)) {
|
||||
offset = capacity - space + bytes;
|
||||
return ptr;
|
||||
}
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
inline void* FrameAllocatorPool::allocate(size_t bytes, size_t alignment)
|
||||
{
|
||||
for (auto& alllocator : allocators) {
|
||||
if (auto ptr = alllocator.try_allocate(bytes, alignment)) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
// 如果所有现有的分配器都没有足够的空间,则创建一个新的分配器
|
||||
auto& it = allocators.emplace_back(allocatorSize);
|
||||
return it.allocate(bytes, alignment);
|
||||
}
|
||||
inline void FrameAllocatorPool::reset()
|
||||
{
|
||||
size_t count = 0;
|
||||
for (auto& allocator : allocators) {
|
||||
if (!allocator.empty()) {
|
||||
allocator.reset();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
count = count > 0 ? count : 1;
|
||||
allocators.erase(allocators.begin() + count, allocators.end());
|
||||
}
|
||||
};
|
||||
88
engine/modules/engine/zlib/include/pmr/name.h
Normal file
88
engine/modules/engine/zlib/include/pmr/name.h
Normal file
@ -0,0 +1,88 @@
|
||||
#pragma once
|
||||
#include "frame_allocator.h"
|
||||
#include <unordered_map>
|
||||
namespace pmr
|
||||
{
|
||||
constexpr inline size_t string_hash(std::string_view str) noexcept;
|
||||
class NameID {
|
||||
public:
|
||||
static consteval size_t InvalidValue() noexcept { return static_cast<size_t>(-1); }
|
||||
|
||||
constexpr NameID() noexcept : hash{ InvalidValue() } {}
|
||||
explicit constexpr NameID(size_t value) noexcept : hash{ value } {}
|
||||
constexpr NameID(std::string_view str) noexcept : hash{ string_hash(str) } {}
|
||||
template<size_t N>
|
||||
constexpr NameID(const char(&str)[N]) noexcept : hash{ string_hash(str) } {}
|
||||
|
||||
constexpr size_t GetValue() const noexcept { return hash; }
|
||||
|
||||
constexpr bool Valid() const noexcept { return hash != InvalidValue(); }
|
||||
|
||||
constexpr bool Is(std::string_view str) const noexcept { return hash == NameID{ str }.GetValue(); }
|
||||
|
||||
explicit constexpr operator bool() const noexcept { return Valid(); }
|
||||
|
||||
constexpr std::strong_ordering operator<=>(const NameID& rhs) const noexcept = default;
|
||||
std::string ToString() const;
|
||||
const std::pmr::string& ToStringRef() const;
|
||||
operator std::string() const { return ToString(); }
|
||||
private:
|
||||
size_t hash;
|
||||
};
|
||||
struct Name {
|
||||
size_t hash;
|
||||
#ifdef Z_DEBUG
|
||||
std::string_view value;
|
||||
#endif // Z_DEBUG
|
||||
public:
|
||||
Name():hash(NameID::InvalidValue()) {};
|
||||
Name(const char* str)noexcept;
|
||||
template<size_t N>
|
||||
constexpr Name(const char(&str)[N]) noexcept;
|
||||
Name(const std::string& str)noexcept;
|
||||
Name(std::string_view str)noexcept;
|
||||
auto operator<=>(const Name& other) const noexcept { return hash <=> other.hash; };
|
||||
bool operator==(const Name& other) const {
|
||||
return hash == other.hash;
|
||||
}
|
||||
constexpr size_t GetValue() const noexcept { return hash; }
|
||||
std::string ToString() const;
|
||||
const std::string_view ToStringView() const;
|
||||
operator std::string() const { return ToString(); }
|
||||
};
|
||||
constexpr inline size_t string_hash(std::string_view str) noexcept
|
||||
{
|
||||
constexpr size_t fnv_offset_basis = 0xcbf29ce484222325;
|
||||
constexpr size_t fnv_prime = 0x100000001b3;
|
||||
|
||||
auto hash = fnv_offset_basis;
|
||||
for (auto& elem : str)
|
||||
{
|
||||
hash *= fnv_prime;
|
||||
hash ^= elem;
|
||||
}
|
||||
hash *= fnv_prime;
|
||||
hash ^= 0;
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
namespace std {
|
||||
template<>
|
||||
struct hash<::pmr::NameID>
|
||||
{
|
||||
size_t operator()(const ::pmr::NameID& ID) const noexcept
|
||||
{
|
||||
return ID.GetValue();
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct hash<::pmr::Name>
|
||||
{
|
||||
size_t operator()(const ::pmr::Name& ID) const noexcept
|
||||
{
|
||||
return ID.GetValue();
|
||||
}
|
||||
};
|
||||
}
|
||||
#include "name.inl"
|
||||
77
engine/modules/engine/zlib/include/pmr/name.inl
Normal file
77
engine/modules/engine/zlib/include/pmr/name.inl
Normal file
@ -0,0 +1,77 @@
|
||||
namespace pmr {
|
||||
using NameTable_t = std::pmr::unordered_map<size_t,const std::pmr::string>;
|
||||
struct NameTable {
|
||||
static const std::pmr::string& Find(size_t id);
|
||||
template<typename T>
|
||||
static std::string_view MakePair(size_t id, T&& str);
|
||||
static NameTable_t BuildNameTable() {
|
||||
static FrameAllocatorPool MemPool;
|
||||
return NameTable_t(&MemPool);
|
||||
}
|
||||
inline static NameTable_t Table = BuildNameTable();
|
||||
};
|
||||
template<typename T>
|
||||
inline std::string_view NameTable::MakePair(size_t id, T&& str)
|
||||
{
|
||||
auto it = Table.find(id);
|
||||
if (it == Table.end()) {
|
||||
auto it2 = Table.emplace(std::make_pair(id, std::pmr::string(str, Table.get_allocator())));
|
||||
if (it2.second) {
|
||||
return it2.first->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
inline const std::pmr::string& NameTable::Find(size_t id)
|
||||
{
|
||||
auto it = Table.find(id);
|
||||
if (it == Table.end()) {
|
||||
static std::pmr::string empty("", Table.get_allocator());
|
||||
return empty;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
inline std::string NameID::ToString() const
|
||||
{
|
||||
return std::string(NameTable::Find(hash));
|
||||
}
|
||||
inline const std::pmr::string& NameID::ToStringRef() const
|
||||
{
|
||||
return NameTable::Find(hash);
|
||||
}
|
||||
#ifdef Z_DEBUG
|
||||
#define MAKE_NAME_PAIR(hash, str) value = NameTable::MakePair(hash, str)
|
||||
#define NAME_TO_STRING value
|
||||
#else
|
||||
#define MAKE_NAME_PAIR(hash, str) NameTable::MakePair(hash, str)
|
||||
#define NAME_TO_STRING NameTable::Find(hash)
|
||||
#endif
|
||||
inline std::string Name::ToString() const
|
||||
{
|
||||
return std::string(NAME_TO_STRING);
|
||||
}
|
||||
inline const std::string_view Name::ToStringView() const
|
||||
{
|
||||
return std::string_view(NAME_TO_STRING);
|
||||
}
|
||||
inline Name::Name(const char* str) noexcept: hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
template<std::size_t N>
|
||||
inline constexpr Name::Name(const char(&str)[N]) noexcept : hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
inline Name::Name(const std::string& str) noexcept : hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
inline Name::Name(std::string_view str) noexcept : hash(string_hash(str))
|
||||
{
|
||||
MAKE_NAME_PAIR(hash, str);
|
||||
}
|
||||
#undef MAKE_NAME_PAIR
|
||||
#undef NAME_TO_STRING
|
||||
}
|
||||
42
engine/modules/engine/zlib/include/refl/detail/any.h
Normal file
42
engine/modules/engine/zlib/include/refl/detail/any.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
#include "type.h"
|
||||
namespace refl {
|
||||
class UClass;
|
||||
struct Any {
|
||||
public:
|
||||
const void* ptr;
|
||||
const UClass* cls;
|
||||
public:
|
||||
constexpr Any() : ptr(nullptr), cls(nullptr) {}
|
||||
constexpr Any(const void* ptr, const UClass* cls) : ptr(ptr), cls(cls) {}
|
||||
template<typename T>
|
||||
constexpr Any(T&& v) : ptr(&v), cls(TypeInfo<args_type_t<T>>::StaticClass) {
|
||||
if constexpr (std::is_same_v<args_type_t<T>, Any>) {
|
||||
ptr = v.ptr;
|
||||
cls = v.cls;
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
constexpr Any(T* v) : ptr(v), cls(&TypeInfo<args_type_t<T>>::StaticClass) {
|
||||
if constexpr (std::is_same_v<args_type_t<T>, Any>) {
|
||||
ptr = v->ptr;
|
||||
cls = v->cls;
|
||||
}
|
||||
}
|
||||
template<typename T>//参数 T* => T*
|
||||
constexpr inline T CastTo() const {
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
return (T)ptr;
|
||||
}
|
||||
else if constexpr (std::is_reference_v<T>) {
|
||||
using RT = std::remove_reference_t<T>;
|
||||
return *(RT*)ptr;
|
||||
}
|
||||
else {
|
||||
return *(T*)ptr;
|
||||
}
|
||||
}
|
||||
public:
|
||||
bool Check(const UClass* parent) const;
|
||||
};
|
||||
}
|
||||
14
engine/modules/engine/zlib/include/refl/detail/any.inl
Normal file
14
engine/modules/engine/zlib/include/refl/detail/any.inl
Normal file
@ -0,0 +1,14 @@
|
||||
#include "any.h"
|
||||
#include "uclass.h"
|
||||
namespace refl{
|
||||
bool Any::Check(const UClass* parent)const
|
||||
{
|
||||
if (cls == parent) {
|
||||
return true;
|
||||
}
|
||||
if (!cls || !parent) {
|
||||
return false;
|
||||
}
|
||||
return cls->IsChildOf(parent);
|
||||
}
|
||||
}
|
||||
51
engine/modules/engine/zlib/include/refl/detail/field.h
Normal file
51
engine/modules/engine/zlib/include/refl/detail/field.h
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
#include "pmr/name.h"
|
||||
#include "any.h"
|
||||
#include <span>
|
||||
namespace refl {
|
||||
using pmr::Name;
|
||||
using std::span;
|
||||
using Offset = uint32_t;
|
||||
using Method = void*;
|
||||
struct MemberData {
|
||||
Offset offset{ 0 };
|
||||
Any value;
|
||||
Any meta;
|
||||
constexpr MemberData() :value(), meta() {}
|
||||
constexpr MemberData(const Any& value, const Any& meta = {}) : value(value), meta(meta) {}
|
||||
constexpr MemberData(Offset offset, const Any& value, const Any& meta) : offset(offset), value(value), meta(meta) {}
|
||||
};
|
||||
struct MethodData {
|
||||
Method fptr{ nullptr };
|
||||
span<Any> value;
|
||||
Any meta;
|
||||
constexpr MethodData() :value(), meta() {}
|
||||
constexpr MethodData(span<Any> value, const Any& meta = {}) : value(value), meta(meta) {}
|
||||
constexpr MethodData(Method fptr, span<Any> value, const Any& meta) : fptr(fptr), value(value), meta(meta) {}
|
||||
};
|
||||
enum FieldFlag :uint32_t {
|
||||
FIELD_NONE_FLAG = 0,
|
||||
FIELD_MEMBER_FLAG = 1 << 0,
|
||||
FIELD_METHOD_FLAG = 1 << 1,
|
||||
FIELD_CTOR_FLAG = 1 << 2,
|
||||
FIELD_VALUE_FLAG = 1 << 3,
|
||||
};
|
||||
using enum FieldFlag;
|
||||
struct FieldPtr {
|
||||
union Data
|
||||
{
|
||||
MemberData member;
|
||||
MethodData method;
|
||||
constexpr Data() : member() {};
|
||||
constexpr Data(const MemberData& member) :member(member) {}
|
||||
constexpr Data(const MethodData& method) : method(method) {}
|
||||
constexpr Data(Offset offset) : member(offset, {}, {}) {}
|
||||
constexpr Data(Offset offset, const Any& value, const Any& meta) : member(offset, value, meta) {}
|
||||
constexpr Data(Method fptr, span<Any> value, const Any& meta) : method(fptr, value, meta) {}
|
||||
};
|
||||
Name name;
|
||||
const UClass* type{};
|
||||
Data data{};
|
||||
uint32_t flag{};
|
||||
};
|
||||
}
|
||||
4
engine/modules/engine/zlib/include/refl/detail/field.inl
Normal file
4
engine/modules/engine/zlib/include/refl/detail/field.inl
Normal file
@ -0,0 +1,4 @@
|
||||
#include "field.h"
|
||||
namespace refl{
|
||||
|
||||
}
|
||||
28
engine/modules/engine/zlib/include/refl/detail/name.h
Normal file
28
engine/modules/engine/zlib/include/refl/detail/name.h
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
namespace refl {
|
||||
template<size_t N>
|
||||
struct TStr {
|
||||
std::array<char, N> value;
|
||||
constexpr TStr() {};
|
||||
constexpr TStr(const char(&data)[N]) {
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
value[i] = data[i];
|
||||
}
|
||||
}
|
||||
constexpr TStr(std::string_view data) {
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
value[i] = data[i];
|
||||
}
|
||||
}
|
||||
constexpr std::string_view View()const {
|
||||
return std::string_view(value.data(), N - 1);
|
||||
}
|
||||
};
|
||||
template<size_t N>
|
||||
TStr(const char(&)[N]) -> TStr<N>;
|
||||
|
||||
template<auto v>
|
||||
constexpr auto value_name() noexcept;
|
||||
template<typename T>
|
||||
constexpr auto type_name() noexcept;
|
||||
}
|
||||
91
engine/modules/engine/zlib/include/refl/detail/name.inl
Normal file
91
engine/modules/engine/zlib/include/refl/detail/name.inl
Normal file
@ -0,0 +1,91 @@
|
||||
#include "name.h"
|
||||
namespace refl {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
constexpr auto func_signature_impl() noexcept {
|
||||
# if defined(__clang__)
|
||||
return std::string_view{ __PRETTY_FUNCTION__ };
|
||||
# elif defined(__GNUC__)
|
||||
return std::string_view{ __PRETTY_FUNCTION__ };
|
||||
# elif defined(_MSC_VER)
|
||||
return std::string_view{ __FUNCSIG__ };
|
||||
# endif
|
||||
}
|
||||
|
||||
template<size_t N, size_t M>
|
||||
constexpr auto concat(const TStr<N>& lhs, const TStr<M>& rhs) {
|
||||
constexpr size_t L = N + M - 1;
|
||||
char result[L] = {};
|
||||
for (size_t i = 0; i < L; ++i) {
|
||||
result[i] = i < N - 1 ? lhs.value[i] : rhs.value[i - N + 1];
|
||||
}
|
||||
return TStr<L>{result};
|
||||
}
|
||||
|
||||
constexpr int _num_digits(int num) {
|
||||
return num < 10 ? 1 : 1 + _num_digits(num / 10);
|
||||
}
|
||||
template <int N, int Digits = _num_digits(N)>
|
||||
constexpr auto num_name() {
|
||||
char data[Digits + 1];
|
||||
int n = N;
|
||||
for (int i = Digits - 1; i >= 0; --i) {
|
||||
data[i] = static_cast<char>('0' + n % 10);
|
||||
n /= 10;
|
||||
}
|
||||
data[Digits] = '\0'; // null-terminated string
|
||||
return TStr{ data };
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto num_prefix_name() {
|
||||
if constexpr (std::is_integral_v<T>) {
|
||||
if constexpr (std::is_signed_v<T>) {
|
||||
return TStr{ "S" };
|
||||
}
|
||||
else {
|
||||
return TStr{ "U" };
|
||||
}
|
||||
}
|
||||
else if constexpr (std::is_floating_point_v<T>) {
|
||||
return TStr{ "F" };
|
||||
}
|
||||
else {
|
||||
return TStr{ "D" };
|
||||
}
|
||||
}
|
||||
}
|
||||
template<auto v>
|
||||
constexpr auto value_name()noexcept {
|
||||
using T = decltype(v);
|
||||
if constexpr (std::is_null_pointer_v<T>)
|
||||
return TStr{ "nullptr" };
|
||||
else if constexpr (std::is_pointer_v<T>) {
|
||||
if constexpr (v == nullptr)
|
||||
return TStr{ "nullptr" };
|
||||
else
|
||||
static_assert("not support");
|
||||
}
|
||||
else if constexpr (std::is_integral_v<T>) {
|
||||
if constexpr (std::is_same_v<T, bool>) {
|
||||
if constexpr (v == true)
|
||||
return TStr{ "true" };
|
||||
else
|
||||
return TStr{ "false" };
|
||||
}
|
||||
else {
|
||||
return TStr{ "false" };
|
||||
}
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
constexpr auto type_name() noexcept {
|
||||
if constexpr (std::is_arithmetic_v<T>) {
|
||||
constexpr auto prefix = detail::num_prefix_name<T>();
|
||||
constexpr auto bit = detail::num_name<8 * sizeof(T)>();
|
||||
return detail::concat(prefix, bit);
|
||||
}
|
||||
else {
|
||||
static_assert("not support");
|
||||
}
|
||||
}
|
||||
}
|
||||
104
engine/modules/engine/zlib/include/refl/detail/type.h
Normal file
104
engine/modules/engine/zlib/include/refl/detail/type.h
Normal file
@ -0,0 +1,104 @@
|
||||
#pragma once
|
||||
#include <array>
|
||||
#include <string>
|
||||
namespace refl {
|
||||
namespace detail {
|
||||
// 定义一个模板结构体用于检测是否为 数组
|
||||
template<typename T>
|
||||
struct is_array : std::false_type {};
|
||||
|
||||
template<typename T, size_t N>
|
||||
struct is_array<T[N]> : std::true_type {
|
||||
using type = T;
|
||||
consteval static size_t size() { return N; }
|
||||
};
|
||||
// 部分特化用于匹配 std::array
|
||||
template<typename T, size_t N>
|
||||
struct is_array<std::array<T, N>> : std::true_type {
|
||||
using type = T;
|
||||
consteval static size_t size() { return N; }
|
||||
};
|
||||
|
||||
// 定义一个模板结构体用于检测是否为 std::pair
|
||||
template<typename T>
|
||||
struct is_pair : std::false_type {};
|
||||
|
||||
template<typename T1, typename T2>
|
||||
struct is_pair<std::pair<T1, T2>> : std::true_type {};
|
||||
|
||||
// 定义一个模板结构体用于检测是否为 std::pair
|
||||
template<typename T>
|
||||
struct is_tuple : std::false_type {};
|
||||
|
||||
template<typename... Types>
|
||||
struct is_tuple<std::tuple<Types...>> : std::true_type {};
|
||||
}
|
||||
template<typename T>
|
||||
concept is_array_v = detail::is_array<T>::value;
|
||||
template<typename T>
|
||||
using is_array_t = detail::is_array<T>::type;
|
||||
|
||||
template<typename T>
|
||||
concept is_pair_v = detail::is_pair<T>::value;
|
||||
|
||||
template<typename T>
|
||||
concept is_tuple_v = detail::is_tuple<T>::value;
|
||||
|
||||
template<typename T>
|
||||
concept is_string_v = requires(T t) {
|
||||
{ static_cast<std::string>(t) } -> std::convertible_to<std::string>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept is_container_v = !is_array_v<T> && !is_string_v<T> && requires(T a) {
|
||||
{ a.begin() } -> std::input_iterator;
|
||||
{ a.end() } -> std::input_iterator;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept is_map_v = is_pair_v<typename T::value_type> && is_container_v<T>;
|
||||
|
||||
template<typename T>
|
||||
concept is_sequence_v = !is_pair_v<typename T::value_type> && is_container_v<T>;
|
||||
};
|
||||
namespace refl {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct real_type {
|
||||
using type = std::remove_cv_t<T>;
|
||||
};
|
||||
template<typename T>
|
||||
struct real_type<T&> {
|
||||
using type = std::remove_cv_t<T>*;
|
||||
};
|
||||
template<typename T>
|
||||
struct real_type<T*> {
|
||||
using type = std::remove_cv_t<T>*;
|
||||
};
|
||||
//转化为指针类型
|
||||
template<typename T>
|
||||
struct args_type {
|
||||
using type = T;
|
||||
};
|
||||
template<typename T>
|
||||
struct args_type<T&> {
|
||||
using type = T;
|
||||
};
|
||||
template<typename T>
|
||||
struct args_type<T*> {
|
||||
using type = T;
|
||||
};
|
||||
}
|
||||
template<typename T>
|
||||
using real_type_t = detail::real_type<T>::type;
|
||||
template<typename T>
|
||||
using args_type_t = detail::args_type<std::remove_cv_t<T>>::type;
|
||||
};
|
||||
namespace refl {
|
||||
//类型接口
|
||||
template<typename T>
|
||||
struct TypeInfoImpl;
|
||||
|
||||
template<typename T>
|
||||
using TypeInfo = TypeInfoImpl<real_type_t<T>>;
|
||||
}
|
||||
86
engine/modules/engine/zlib/include/refl/detail/uclass.h
Normal file
86
engine/modules/engine/zlib/include/refl/detail/uclass.h
Normal file
@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
#include "field.h"
|
||||
namespace refl {
|
||||
template<typename T>
|
||||
using pmr_vector = std::pmr::vector<T>;
|
||||
enum ClassFlag :uint32_t {
|
||||
CLASS_NONE_FLAG = 0,
|
||||
CLASS_TRIVIAL_FLAG = 1 << 0,
|
||||
CLASS_POINTER_FLAG = 1 << 1,
|
||||
CLASS_ARRAY_FLAG = 1 << 2,
|
||||
CLASS_CONTAINER_FLAG = 1 << 3,
|
||||
CLASS_SEQUENCE_FLAG = 1 << 4,
|
||||
CLASS_MAP_FLAG = 1 << 5,
|
||||
CLASS_PARENT_FLAG = 1 << 6,
|
||||
};
|
||||
enum EFieldFind :uint32_t {
|
||||
FIND_ALL_FIELD = 0,
|
||||
FIND_ALL_MEMBER,
|
||||
FIND_ALL_METHOD,
|
||||
FIND_FIELD,
|
||||
FIND_CTOR,
|
||||
FIND_MEMBER,
|
||||
FIND_METHOD,
|
||||
FIND_METHODS,//函数重载 特别是构造函数
|
||||
};
|
||||
struct vtable_uclass
|
||||
{
|
||||
//class
|
||||
span<const FieldPtr>(*GetFields)(const UClass*, EFieldFind find, Name name);
|
||||
//function
|
||||
span<const UClass>(*GetParams)(const UClass*);
|
||||
//function
|
||||
void (*Call)(const FieldPtr*, span<Any> ArgsList);
|
||||
//meta
|
||||
const UClass* (*GetMeta)(Name);
|
||||
//object
|
||||
bool (*Construct)(void* ptr, const UClass* cls, span<Any> ArgsList);
|
||||
void (*Destruct)(void*);
|
||||
};
|
||||
class UClass {
|
||||
public:
|
||||
Name name;
|
||||
uint32_t size;
|
||||
uint32_t flag{0};
|
||||
const UClass* parent;
|
||||
vtable_uclass* vtable{nullptr};
|
||||
public:
|
||||
UClass(std::string_view name, uint32_t size, const UClass* parent = nullptr)
|
||||
:name(name), size(size), parent(parent) {}
|
||||
bool IsChildOf(const UClass* cls, bool bthis = false) const {
|
||||
const UClass* _parent = bthis ? this : parent;
|
||||
while (_parent != nullptr) {
|
||||
if (_parent == cls) {
|
||||
return true;
|
||||
}
|
||||
_parent = _parent->parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template<typename T>
|
||||
bool IsChildOf(bool bthis = false) const {
|
||||
return IsChildOf(TypeInfo<T>::StaticClass, bthis);
|
||||
}
|
||||
public:
|
||||
template<typename T>
|
||||
static void Destruct(void* ptr) {
|
||||
std::destroy_at((T*)ptr);
|
||||
}
|
||||
template<typename T>
|
||||
static bool Construct(void* ptr, const UClass* cls, span<Any> ArgsList = {}) {
|
||||
int argsSize = ArgsList.size();
|
||||
if (argsSize == 0) {
|
||||
if constexpr (std::is_constructible_v<T>) {
|
||||
std::construct_at((T*)ptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (argsSize == 1 && ArgsList[0].Check(cls)) {
|
||||
*(T*)ptr = *(const T*)ArgsList[0].ptr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
44
engine/modules/engine/zlib/include/refl/detail/uclass.inl
Normal file
44
engine/modules/engine/zlib/include/refl/detail/uclass.inl
Normal file
@ -0,0 +1,44 @@
|
||||
#include "uclass.h"
|
||||
#include "name.h"
|
||||
namespace refl{
|
||||
namespace detail {
|
||||
inline static pmr::FrameAllocatorPool MemPool{};
|
||||
}
|
||||
template <class T>
|
||||
concept is_metas_v = false;//requires(const Name & name) { MetaImpl<T>::MyMetas::GetMeta(name); };
|
||||
template<typename T>
|
||||
class UClass_Auto : public UClass {
|
||||
using UClass::UClass;
|
||||
using MyUClass = UClass_Auto<T>;
|
||||
public:
|
||||
static MyUClass* BuildClass() {
|
||||
MyUClass* cls = new(detail::MemPool)MyUClass(type_name<T>().View(), sizeof(T));
|
||||
if constexpr (std::is_pointer_v<T>) {
|
||||
using RT = std::remove_pointer_t<T>;
|
||||
cls->flag |= CLASS_POINTER_FLAG;
|
||||
if constexpr (!std::is_same_v<RT, void>) {
|
||||
cls->parent = TypeInfo<RT>::StaticClass;
|
||||
}
|
||||
}
|
||||
else if constexpr (is_array_v<T>) {
|
||||
using RT = is_array_t<T>;
|
||||
cls->flag = CLASS_ARRAY_FLAG;
|
||||
if constexpr (std::is_pointer_v<RT>) {
|
||||
cls->flag |= CLASS_POINTER_FLAG;
|
||||
}
|
||||
cls->parent = TypeInfo<RT>::StaticClass;
|
||||
}
|
||||
else {
|
||||
cls->vtable = new(detail::MemPool)vtable_uclass();
|
||||
cls->vtable->Construct = &UClass::Construct<T>;
|
||||
cls->vtable->Destruct = &UClass::Destruct<T>;
|
||||
}
|
||||
return cls;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct TypeInfoImpl {
|
||||
using MyUClass = UClass_Auto<T>;
|
||||
inline static MyUClass* StaticClass = MyUClass::BuildClass();
|
||||
};
|
||||
}
|
||||
4
engine/modules/engine/zlib/include/refl/pch.h
Normal file
4
engine/modules/engine/zlib/include/refl/pch.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "detail/name.inl"
|
||||
#include "detail/any.inl"
|
||||
#include "detail/uclass.inl"
|
||||
15
engine/modules/engine/zlib/include/singleton.h
Normal file
15
engine/modules/engine/zlib/include/singleton.h
Normal file
@ -0,0 +1,15 @@
|
||||
template <typename T>
|
||||
class Singleton{
|
||||
protected:
|
||||
inline static T* ms_Singleton = nullptr;
|
||||
public:
|
||||
explicit Singleton() {
|
||||
ms_Singleton = static_cast<T*>(this);
|
||||
}
|
||||
~Singleton() {
|
||||
ms_Singleton = nullptr;
|
||||
}
|
||||
static constexpr T* Ptr(void) {
|
||||
return ms_Singleton;
|
||||
}
|
||||
};
|
||||
7
engine/modules/engine/zlib/xmake.lua
Normal file
7
engine/modules/engine/zlib/xmake.lua
Normal file
@ -0,0 +1,7 @@
|
||||
header_component("zlib","engine")
|
||||
set_basename("myzlib")
|
||||
add_headerfiles("include/**.h", "include/**.inl")
|
||||
if is_mode("debug") then
|
||||
add_defines("Z_DEBUG", {public = true})
|
||||
end
|
||||
set_pcheader("include/refl/pch.h")
|
||||
11
engine/modules/render/vulkan/include/vulkan/module.h
Normal file
11
engine/modules/render/vulkan/include/vulkan/module.h
Normal file
@ -0,0 +1,11 @@
|
||||
#include "module/moudle.h"
|
||||
#include "asset/asset.h"
|
||||
class VulkanModule : public api::IDynamicModule
|
||||
{
|
||||
public:
|
||||
void OnLoad(int argc, char** argv) override;
|
||||
void OnUnload() override;
|
||||
const char* MetaData(void) override;
|
||||
};
|
||||
MODULE_DEPENDENCY(core, asset, {public = true})
|
||||
IMPLEMENT_DYNAMIC_MODULE(VulkanModule, vulkan)
|
||||
15
engine/modules/render/vulkan/src/module.cpp
Normal file
15
engine/modules/render/vulkan/src/module.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "module.h"
|
||||
|
||||
void VulkanModule::OnLoad(int argc, char** argv)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void VulkanModule::OnUnload()
|
||||
{
|
||||
}
|
||||
|
||||
const char* VulkanModule::MetaData(void)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
6
engine/modules/render/vulkan/xmake.lua
Normal file
6
engine/modules/render/vulkan/xmake.lua
Normal file
@ -0,0 +1,6 @@
|
||||
shared_component("vulkan","engine")
|
||||
add_includedirs("include/vulkan")
|
||||
add_headerfiles("include/**.h")
|
||||
add_files("src/**.cpp")
|
||||
add_rules("engine.plugin", {file = "include/vulkan/module.h"})
|
||||
--add_deps("core", "asset", {public = true})
|
||||
28
engine/modules/xmake.lua
Normal file
28
engine/modules/xmake.lua
Normal file
@ -0,0 +1,28 @@
|
||||
function header_component(name, owner, opt)
|
||||
target(owner)
|
||||
add_deps(name, { public = opt and opt.public or true })
|
||||
target_end()
|
||||
target(name)
|
||||
set_kind("headeronly")
|
||||
set_group("Engine/"..owner.."__comp")
|
||||
add_includedirs("include", {public = true})
|
||||
end
|
||||
function static_component(name, owner, opt)
|
||||
target(owner)
|
||||
add_deps(name, { public = opt and opt.public or true })
|
||||
target_end()
|
||||
target(name)
|
||||
set_kind("static")
|
||||
set_group("Engine/"..owner.."__comp")
|
||||
add_includedirs("include", {public = true})
|
||||
end
|
||||
function shared_component(name, owner, opt)
|
||||
target(owner)
|
||||
add_deps(name, { public = opt and opt.public or true })
|
||||
target_end()
|
||||
target(name)
|
||||
set_kind("shared")
|
||||
set_group("Engine/"..owner.."__comp")
|
||||
add_includedirs("include", {public = true})
|
||||
end
|
||||
includes("**/xmake.lua")
|
||||
145
engine/tools/make_plugin/src/main.cpp
Normal file
145
engine/tools/make_plugin/src/main.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <memory_resource>
|
||||
#include <stack>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
namespace pmr {
|
||||
using std::pmr::monotonic_buffer_resource;
|
||||
using std::pmr::vector;
|
||||
using std::pmr::string;
|
||||
}
|
||||
pmr::monotonic_buffer_resource pool;
|
||||
const char* MODULE_DEPENDENCY = "MODULE_DEPENDENCY";
|
||||
const char* IMPLEMENT_DYNAMIC_MODULE = "IMPLEMENT_DYNAMIC_MODULE";
|
||||
const char* IMPLEMENT_STATIC_MODULE = "IMPLEMENT_STATIC_MODULE";
|
||||
std::string_view module_macro[] = { MODULE_DEPENDENCY , IMPLEMENT_DYNAMIC_MODULE , IMPLEMENT_STATIC_MODULE };
|
||||
struct MacroData{
|
||||
const char* macro{nullptr};
|
||||
pmr::vector<pmr::string> args;
|
||||
MacroData() :args(&pool) {}
|
||||
MacroData(const pmr::vector<pmr::string>& args):args(args) {}
|
||||
};
|
||||
pmr::vector<pmr::string> parseArgs(std::string_view& str) {
|
||||
pmr::vector<pmr::string> args(&pool);
|
||||
std::stack<char> stack;
|
||||
enum EParseState {
|
||||
EEmpty,
|
||||
EBody,
|
||||
};
|
||||
EParseState state = EEmpty;
|
||||
int n = 0;
|
||||
char segment[1024];
|
||||
for (char c : str) {
|
||||
switch (state)
|
||||
{
|
||||
case EEmpty:
|
||||
{
|
||||
if (c == ' ' || c == '\t')
|
||||
break;
|
||||
state = EBody;
|
||||
if (c == '(' && stack.empty()) {
|
||||
stack.push(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
case EBody:
|
||||
{
|
||||
if (c == '(' || c == '{' || c == '[' || (c == '"' && stack.top() != '"')) {
|
||||
stack.push(c);
|
||||
}else{
|
||||
char t = stack.top();
|
||||
if ((t == '(' && c == ')') || (t == '[' && c == ']') || (t == '{' && c == '}') || (t == '"' && c == '"')) {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
if (stack.empty()) {
|
||||
std::string_view view(segment, n);
|
||||
args.push_back(pmr::string(view, &pool));
|
||||
return args;
|
||||
}
|
||||
if (c == ',' && stack.size() == 1) {
|
||||
std::string_view view(segment, n);
|
||||
args.push_back(pmr::string(view, &pool));
|
||||
n = 0;
|
||||
state = EEmpty;
|
||||
}
|
||||
else {
|
||||
segment[n++] = c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
std::optional<MacroData> parseLine(std::string_view line) {
|
||||
for (auto macro : module_macro) {
|
||||
size_t pos = line.find(macro);
|
||||
if (pos != std::string_view::npos) {
|
||||
line = line.substr(pos + macro.size());
|
||||
MacroData md{ parseArgs(line) };
|
||||
md.macro = macro.data();
|
||||
std::cout << line << std::endl;
|
||||
return md;
|
||||
}
|
||||
}
|
||||
return std::optional<MacroData>{};
|
||||
}
|
||||
// 读取文件并返回每一行内容
|
||||
pmr::vector<MacroData> readFile(const char* file_path) {
|
||||
pmr::vector<MacroData> lines(&pool);
|
||||
std::ifstream file(file_path);
|
||||
if (!file.is_open()) {
|
||||
//std::cerr << "Failed to open file: " << file_path << std::endl;
|
||||
return lines;
|
||||
}
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
std::string_view line_view(line);
|
||||
if (auto md = parseLine(line_view)) {
|
||||
lines.push_back(md.value());
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
return lines;
|
||||
}
|
||||
void writeFile(const char* file_path, std::string_view data) {
|
||||
std::ofstream file(file_path, 0);
|
||||
file.write(data.data(), data.size());
|
||||
file.close();
|
||||
}
|
||||
void genLua(const char* file_path, const pmr::vector<MacroData>& mdList) {
|
||||
std::ostringstream oss;
|
||||
oss << "{\n";
|
||||
for (auto& md : mdList) {
|
||||
if (md.macro == MODULE_DEPENDENCY) {
|
||||
oss << "\t{";
|
||||
for (auto& args : md.args) {
|
||||
if (args[0] != '{') {
|
||||
oss << '"' << args << "\", ";
|
||||
}
|
||||
else {
|
||||
oss << args;
|
||||
}
|
||||
}
|
||||
oss << "},\n";
|
||||
}
|
||||
}
|
||||
oss << '}';
|
||||
writeFile(file_path, oss.str());
|
||||
}
|
||||
void genPlugin(const char* file_path, const pmr::vector<MacroData>& mdList) {
|
||||
|
||||
}
|
||||
int main() {
|
||||
const char* file_path = R"(F:\engine\zengine\engine\modules\render\vulkan\include\vulkan\module.h)";
|
||||
auto mdList = readFile(file_path);
|
||||
genLua(R"(F:\engine\zengine\build\.gens\vulkan\windows\xmake.lua)", mdList);
|
||||
genPlugin(R"(F:\engine\zengine\build\.gens\vulkan\windows\xmake.lua)", mdList);
|
||||
return 0;
|
||||
}
|
||||
2
engine/tools/make_plugin/xmake.lua
Normal file
2
engine/tools/make_plugin/xmake.lua
Normal file
@ -0,0 +1,2 @@
|
||||
tool_target("make_plugin")
|
||||
add_files("src/main.cpp")
|
||||
6
engine/tools/xmake.lua
Normal file
6
engine/tools/xmake.lua
Normal file
@ -0,0 +1,6 @@
|
||||
function tool_target(name)
|
||||
target(name)
|
||||
set_kind("binary")
|
||||
set_group("Tools")
|
||||
end
|
||||
includes("*/xmake.lua")
|
||||
9
engine/xmake.lua
Normal file
9
engine/xmake.lua
Normal file
@ -0,0 +1,9 @@
|
||||
target("editor")
|
||||
set_kind("static")
|
||||
set_group("Engine")
|
||||
target("engine")
|
||||
set_kind("static")
|
||||
set_group("Engine")
|
||||
includes("xmake/xmake.lua")
|
||||
includes("tools/xmake.lua")
|
||||
includes("modules/xmake.lua")
|
||||
28
engine/xmake/modules/find_sdk.lua
Normal file
28
engine/xmake/modules/find_sdk.lua
Normal file
@ -0,0 +1,28 @@
|
||||
function find_my_program(name, sdkdir, use_next)
|
||||
import("lib.detect.find_file")
|
||||
import("lib.detect.find_program")
|
||||
import("lib.detect.find_tool")
|
||||
|
||||
local sdkdir = sdkdir or path.join(os.projectdir(), "tools")
|
||||
local tool = find_tool(name, {pathes = {sdkdir, "/usr/local/bin"}})
|
||||
local prog = tool and tool.program or find_program(name, {pathes = {sdkdir, "/usr/local/bin"}})
|
||||
prog = prog or find_file(name, {sdkdir})
|
||||
if (prog == nil) then
|
||||
if os.host() ~= "windows" then
|
||||
local outdata, errdata = os.iorun("which " .. name)
|
||||
if (errdata ~= nil or errdata ~= "") then
|
||||
prog = string.gsub(outdata, "%s+", "")
|
||||
end
|
||||
else
|
||||
prog = find_file(name .. ".exe", {sdkdir})
|
||||
end
|
||||
end
|
||||
if (prog == nil) then
|
||||
if not use_next then
|
||||
return find_my_program(name, path.join(sdkdir, name), true)
|
||||
end
|
||||
print(name .. "_f not found! under " .. sdkdir)
|
||||
return
|
||||
end
|
||||
return {program = prog, sdkdir = sdkdir}
|
||||
end
|
||||
28
engine/xmake/rule_plugin/make_plugin.lua
Normal file
28
engine/xmake/rule_plugin/make_plugin.lua
Normal file
@ -0,0 +1,28 @@
|
||||
import("core.project.depend")
|
||||
function cmd_compile(target, genfile, file)
|
||||
local res = [[
|
||||
{
|
||||
{"core", { public = true}},
|
||||
{"asset", { public = true}},
|
||||
}
|
||||
]]
|
||||
--io.writefile(genfile, res)
|
||||
local dependency = io.load(genfile)
|
||||
for k,v in ipairs(dependency) do
|
||||
--target:add("deps", v[1], v[2])
|
||||
end
|
||||
end
|
||||
function main(target, file)
|
||||
local sourcedir = path.join(target:autogendir({root = true}), target:plat())
|
||||
if not os.isdir(sourcedir) then
|
||||
os.mkdir(sourcedir)
|
||||
end
|
||||
local genfile = sourcedir .. "\\xmake.lua"
|
||||
local dependfile = target:dependfile(genfile)
|
||||
depend.on_changed(
|
||||
function()
|
||||
cmd_compile(target, genfile, file)
|
||||
end,
|
||||
{dependfile = dependfile, files = {file}}
|
||||
)
|
||||
end
|
||||
7
engine/xmake/rule_plugin/xmake.lua
Normal file
7
engine/xmake/rule_plugin/xmake.lua
Normal file
@ -0,0 +1,7 @@
|
||||
rule("engine.plugin")
|
||||
set_extensions(".h")
|
||||
on_load(function (target)
|
||||
import("make_plugin")
|
||||
local file = target:extraconf("rules", "engine.plugin", "file")
|
||||
make_plugin(target, file or "module.h")
|
||||
end)
|
||||
2
engine/xmake/xmake.lua
Normal file
2
engine/xmake/xmake.lua
Normal file
@ -0,0 +1,2 @@
|
||||
includes("*/xmake.lua")
|
||||
add_moduledirs(path.join(os.projectdir(), "engine/xmake/modules"))
|
||||
49
game/zworld/editor/main.cpp
Normal file
49
game/zworld/editor/main.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include <iostream>
|
||||
#include <array>
|
||||
#include <charconv>
|
||||
#include "pmr/frame_allocator.h"
|
||||
#include "pmr/name.h"
|
||||
#include "refl/pch.h"
|
||||
#include "module/module_manager.h"
|
||||
void test(std::string_view str = "") {
|
||||
std::cout << "test " << str << std::endl;
|
||||
}
|
||||
int main() {
|
||||
api::ModuleManager::Ptr();
|
||||
test("sss");
|
||||
using namespace refl;
|
||||
constexpr TStr str1{ "Hello" };
|
||||
constexpr TStr str2{ " world" };
|
||||
constexpr TStr str3 = detail::concat(str1, str2);
|
||||
constexpr auto r1 = value_name<8 * sizeof(int)>();
|
||||
constexpr int v = 12;
|
||||
auto cls = refl::TypeInfo<int>::StaticClass;
|
||||
//auto str4 = concat(r1, str2);
|
||||
auto t1 = refl::type_name<int>();
|
||||
auto v1 = refl::type_name<int>().View();
|
||||
auto v2 = t1.View();
|
||||
if (v1 == t1.View()) {
|
||||
auto t2 = refl::type_name<int16_t>();
|
||||
auto t3 = refl::type_name<int8_t>();
|
||||
}
|
||||
auto t2 = refl::type_name<int16_t>();
|
||||
auto t3 = refl::type_name<int8_t>();
|
||||
pmr::FrameAllocatorPool pool;
|
||||
pmr::Name name = "hello enginehello enginehello engine\n";
|
||||
pmr::Name name2("hello enginehello enginehello engine\n");
|
||||
pmr::Name name3("hello enginehello enginehello engine222\n");
|
||||
if (name == name2) {
|
||||
std::string s1 = name.ToString();
|
||||
std::string s2 = name2.ToString();
|
||||
if (s1.c_str() == s2.c_str()) {
|
||||
new(pool)int(1);
|
||||
}
|
||||
if (s1 == s2) {
|
||||
new(pool)int(1);
|
||||
}
|
||||
}
|
||||
int* a = new(pool)int(1);
|
||||
int* b = new(pool)int(2);
|
||||
int* c = new(pool)int(3);
|
||||
std::cout << "hello engine\n";
|
||||
}
|
||||
5
game/zworld/src/zworld.cpp
Normal file
5
game/zworld/src/zworld.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "zworld.h"
|
||||
|
||||
void hello() {
|
||||
|
||||
}
|
||||
1
game/zworld/src/zworld.h
Normal file
1
game/zworld/src/zworld.h
Normal file
@ -0,0 +1 @@
|
||||
void hello();
|
||||
11
game/zworld/xmake.lua
Normal file
11
game/zworld/xmake.lua
Normal file
@ -0,0 +1,11 @@
|
||||
target("zworld")
|
||||
set_kind("shared")
|
||||
set_group("Games")
|
||||
add_deps("engine", "editor", "vulkan", {public = true})
|
||||
add_files("src/*.cpp")
|
||||
add_headerfiles("src/*.h")
|
||||
target("zworld-editor")
|
||||
set_kind("binary")
|
||||
set_group("Games")
|
||||
add_deps("zworld")
|
||||
add_files("editor/main.cpp")
|
||||
10
xmake.lua
Normal file
10
xmake.lua
Normal file
@ -0,0 +1,10 @@
|
||||
add_rules("mode.debug", "mode.release")
|
||||
set_arch("x64")
|
||||
set_languages("cxx20")
|
||||
set_project("zengine")
|
||||
set_toolchains("clang")
|
||||
set_runtimes("MD","c++_shared")
|
||||
includes("engine")
|
||||
includes("game/*/xmake.lua")
|
||||
--xmake project -k vsxmake2022 -a x64
|
||||
--xmake project -k vsxmake2022 -m "debug;release"
|
||||
Loading…
Reference in New Issue
Block a user