commit 1d96f31f524bb822cb001b3888e417413e1ce163 Author: ouczbs Date: Sat Jul 20 18:04:19 2024 +0800 add module diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f8c16b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.vs/ +.vscode/.cache/ +.vscode/compile_commands.json +.xmake/ +build/ +vsxmake*/ +/tools \ No newline at end of file diff --git a/engine/modules/editor/xmake.lua b/engine/modules/editor/xmake.lua new file mode 100644 index 0000000..e69de29 diff --git a/engine/modules/engine/asset/include/asset/asset.h b/engine/modules/engine/asset/include/asset/asset.h new file mode 100644 index 0000000..e69de29 diff --git a/engine/modules/engine/asset/src/asset.cpp b/engine/modules/engine/asset/src/asset.cpp new file mode 100644 index 0000000..e69de29 diff --git a/engine/modules/engine/asset/xmake.lua b/engine/modules/engine/asset/xmake.lua new file mode 100644 index 0000000..4c36c84 --- /dev/null +++ b/engine/modules/engine/asset/xmake.lua @@ -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}) \ No newline at end of file diff --git a/engine/modules/engine/core/include/module/module.inl b/engine/modules/engine/core/include/module/module.inl new file mode 100644 index 0000000..ed675fc --- /dev/null +++ b/engine/modules/engine/core/include/module/module.inl @@ -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 __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) \ No newline at end of file diff --git a/engine/modules/engine/core/include/module/module_manager.h b/engine/modules/engine/core/include/module/module_manager.h new file mode 100644 index 0000000..3a0c291 --- /dev/null +++ b/engine/modules/engine/core/include/module/module_manager.h @@ -0,0 +1,31 @@ +#pragma once +#include "moudle.h" +namespace api { + template> + using table = std::pmr::unordered_map; + class ModuleManager + { + friend struct IModule; + private: + SharedLibrary mProcessLib; + table mModuleTable; + public: + ModuleManager() = default; + IModule* GetModule(Name name); + bool RegisterModule(Name name, IModule::CreatePFN fn); + static ModuleManager* Ptr(); + }; + struct empty { + + }; + static empty e; + template + struct ModuleRegistrantImpl { + ModuleRegistrantImpl(const char* InModuleName) + { + ModuleManager::Ptr()->RegisterModule(InModuleName, []() { + return new ModuleClass(); + }); + } + }; +} \ No newline at end of file diff --git a/engine/modules/engine/core/include/module/moudle.h b/engine/modules/engine/core/include/module/moudle.h new file mode 100644 index 0000000..df056bc --- /dev/null +++ b/engine/modules/engine/core/include/module/moudle.h @@ -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 mSubSystems; + }; +} +#include "module.inl" \ No newline at end of file diff --git a/engine/modules/engine/core/include/os/file_system.h b/engine/modules/engine/core/include/os/file_system.h new file mode 100644 index 0000000..a25dac0 --- /dev/null +++ b/engine/modules/engine/core/include/os/file_system.h @@ -0,0 +1,5 @@ +#include +namespace fs { + std::string GetExecutablePath(); + std::string GetWorkPath(); +} \ No newline at end of file diff --git a/engine/modules/engine/core/include/os/shared_library.h b/engine/modules/engine/core/include/os/shared_library.h new file mode 100644 index 0000000..e2f1106 --- /dev/null +++ b/engine/modules/engine/core/include/os/shared_library.h @@ -0,0 +1,9 @@ +#pragma once +namespace api { + using NativeLibHandle = void*; + class SharedLibrary { + NativeLibHandle mHandle; + public: + bool Load(const char* path = nullptr); + }; +} \ No newline at end of file diff --git a/engine/modules/engine/core/include/pch.h b/engine/modules/engine/core/include/pch.h new file mode 100644 index 0000000..e69de29 diff --git a/engine/modules/engine/core/src/module/module.cpp b/engine/modules/engine/core/src/module/module.cpp new file mode 100644 index 0000000..e69de29 diff --git a/engine/modules/engine/core/src/module/module_manager.cpp b/engine/modules/engine/core/src/module/module_manager.cpp new file mode 100644 index 0000000..60550cd --- /dev/null +++ b/engine/modules/engine/core/src/module/module_manager.cpp @@ -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; + } +} \ No newline at end of file diff --git a/engine/modules/engine/core/src/os/file_system.cpp b/engine/modules/engine/core/src/os/file_system.cpp new file mode 100644 index 0000000..6b811be --- /dev/null +++ b/engine/modules/engine/core/src/os/file_system.cpp @@ -0,0 +1,47 @@ +#include "os/file_system.h" +#include + +#ifdef _WIN32 +#include +#elif __linux__ +#include +#include +#elif __APPLE__ +#include +#include +#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(); + } + +} \ No newline at end of file diff --git a/engine/modules/engine/core/src/os/shared_library.cpp b/engine/modules/engine/core/src/os/shared_library.cpp new file mode 100644 index 0000000..730919f --- /dev/null +++ b/engine/modules/engine/core/src/os/shared_library.cpp @@ -0,0 +1,21 @@ +#include "os/shared_library.h" +#include +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; + } +} + diff --git a/engine/modules/engine/core/xmake.lua b/engine/modules/engine/core/xmake.lua new file mode 100644 index 0000000..678b15f --- /dev/null +++ b/engine/modules/engine/core/xmake.lua @@ -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") \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/macro.h b/engine/modules/engine/zlib/include/macro.h new file mode 100644 index 0000000..0792846 --- /dev/null +++ b/engine/modules/engine/zlib/include/macro.h @@ -0,0 +1,9 @@ +#define ENABLE_BITMASK_OPERATORS(bitmask) \ +inline bitmask operator|(bitmask a, bitmask b) { return static_cast(static_cast>(a) | static_cast>(b)); } \ +inline bitmask operator&(bitmask a, bitmask b) { return static_cast(static_cast>(a) & static_cast>(b)); } \ +inline bitmask operator^(bitmask a, bitmask b) { return static_cast(static_cast>(a) ^ static_cast>(b)); } \ +inline bitmask operator~(bitmask a) { return static_cast(~static_cast>(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>(a) == 0;} diff --git a/engine/modules/engine/zlib/include/pmr/frame_allocator.h b/engine/modules/engine/zlib/include/pmr/frame_allocator.h new file mode 100644 index 0000000..c03e005 --- /dev/null +++ b/engine/modules/engine/zlib/include/pmr/frame_allocator.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +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 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" \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/pmr/frame_allocator.inl b/engine/modules/engine/zlib/include/pmr/frame_allocator.inl new file mode 100644 index 0000000..876650a --- /dev/null +++ b/engine/modules/engine/zlib/include/pmr/frame_allocator.inl @@ -0,0 +1,62 @@ +namespace pmr { + inline FrameAllocator& FrameAllocator::operator=(FrameAllocator&& o)noexcept + { + std::construct_at(this, std::forward(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()); + } +}; \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/pmr/name.h b/engine/modules/engine/zlib/include/pmr/name.h new file mode 100644 index 0000000..0a5b4b9 --- /dev/null +++ b/engine/modules/engine/zlib/include/pmr/name.h @@ -0,0 +1,88 @@ +#pragma once +#include "frame_allocator.h" +#include +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(-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 + 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 + 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" \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/pmr/name.inl b/engine/modules/engine/zlib/include/pmr/name.inl new file mode 100644 index 0000000..200debc --- /dev/null +++ b/engine/modules/engine/zlib/include/pmr/name.inl @@ -0,0 +1,77 @@ +namespace pmr { + using NameTable_t = std::pmr::unordered_map; + struct NameTable { + static const std::pmr::string& Find(size_t id); + template + 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 + 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 + 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 +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/any.h b/engine/modules/engine/zlib/include/refl/detail/any.h new file mode 100644 index 0000000..19bcf1d --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/any.h @@ -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 + constexpr Any(T&& v) : ptr(&v), cls(TypeInfo>::StaticClass) { + if constexpr (std::is_same_v, Any>) { + ptr = v.ptr; + cls = v.cls; + } + } + template + constexpr Any(T* v) : ptr(v), cls(&TypeInfo>::StaticClass) { + if constexpr (std::is_same_v, Any>) { + ptr = v->ptr; + cls = v->cls; + } + } + template//参数 T* => T* + constexpr inline T CastTo() const { + if constexpr (std::is_pointer_v) { + return (T)ptr; + } + else if constexpr (std::is_reference_v) { + using RT = std::remove_reference_t; + return *(RT*)ptr; + } + else { + return *(T*)ptr; + } + } + public: + bool Check(const UClass* parent) const; + }; +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/any.inl b/engine/modules/engine/zlib/include/refl/detail/any.inl new file mode 100644 index 0000000..6977bd4 --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/any.inl @@ -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); + } +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/field.h b/engine/modules/engine/zlib/include/refl/detail/field.h new file mode 100644 index 0000000..0c26189 --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/field.h @@ -0,0 +1,51 @@ +#pragma once +#include "pmr/name.h" +#include "any.h" +#include +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 value; + Any meta; + constexpr MethodData() :value(), meta() {} + constexpr MethodData(span value, const Any& meta = {}) : value(value), meta(meta) {} + constexpr MethodData(Method fptr, span 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 value, const Any& meta) : method(fptr, value, meta) {} + }; + Name name; + const UClass* type{}; + Data data{}; + uint32_t flag{}; + }; +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/field.inl b/engine/modules/engine/zlib/include/refl/detail/field.inl new file mode 100644 index 0000000..cf5586f --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/field.inl @@ -0,0 +1,4 @@ +#include "field.h" +namespace refl{ + +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/name.h b/engine/modules/engine/zlib/include/refl/detail/name.h new file mode 100644 index 0000000..6c1c778 --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/name.h @@ -0,0 +1,28 @@ +#pragma once +namespace refl { + template + struct TStr { + std::array 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 + TStr(const char(&)[N]) -> TStr; + + template + constexpr auto value_name() noexcept; + template + constexpr auto type_name() noexcept; +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/name.inl b/engine/modules/engine/zlib/include/refl/detail/name.inl new file mode 100644 index 0000000..fafd2ee --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/name.inl @@ -0,0 +1,91 @@ +#include "name.h" +namespace refl { + namespace detail { + template + 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 + constexpr auto concat(const TStr& lhs, const TStr& 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{result}; + } + + constexpr int _num_digits(int num) { + return num < 10 ? 1 : 1 + _num_digits(num / 10); + } + template + constexpr auto num_name() { + char data[Digits + 1]; + int n = N; + for (int i = Digits - 1; i >= 0; --i) { + data[i] = static_cast('0' + n % 10); + n /= 10; + } + data[Digits] = '\0'; // null-terminated string + return TStr{ data }; + } + template + constexpr auto num_prefix_name() { + if constexpr (std::is_integral_v) { + if constexpr (std::is_signed_v) { + return TStr{ "S" }; + } + else { + return TStr{ "U" }; + } + } + else if constexpr (std::is_floating_point_v) { + return TStr{ "F" }; + } + else { + return TStr{ "D" }; + } + } + } + template + constexpr auto value_name()noexcept { + using T = decltype(v); + if constexpr (std::is_null_pointer_v) + return TStr{ "nullptr" }; + else if constexpr (std::is_pointer_v) { + if constexpr (v == nullptr) + return TStr{ "nullptr" }; + else + static_assert("not support"); + } + else if constexpr (std::is_integral_v) { + if constexpr (std::is_same_v) { + if constexpr (v == true) + return TStr{ "true" }; + else + return TStr{ "false" }; + } + else { + return TStr{ "false" }; + } + } + } + template + constexpr auto type_name() noexcept { + if constexpr (std::is_arithmetic_v) { + constexpr auto prefix = detail::num_prefix_name(); + constexpr auto bit = detail::num_name<8 * sizeof(T)>(); + return detail::concat(prefix, bit); + } + else { + static_assert("not support"); + } + } +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/type.h b/engine/modules/engine/zlib/include/refl/detail/type.h new file mode 100644 index 0000000..3dd95bc --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/type.h @@ -0,0 +1,104 @@ +#pragma once +#include +#include +namespace refl { + namespace detail { + // 定义一个模板结构体用于检测是否为 数组 + template + struct is_array : std::false_type {}; + + template + struct is_array : std::true_type { + using type = T; + consteval static size_t size() { return N; } + }; + // 部分特化用于匹配 std::array + template + struct is_array> : std::true_type { + using type = T; + consteval static size_t size() { return N; } + }; + + // 定义一个模板结构体用于检测是否为 std::pair + template + struct is_pair : std::false_type {}; + + template + struct is_pair> : std::true_type {}; + + // 定义一个模板结构体用于检测是否为 std::pair + template + struct is_tuple : std::false_type {}; + + template + struct is_tuple> : std::true_type {}; + } + template + concept is_array_v = detail::is_array::value; + template + using is_array_t = detail::is_array::type; + + template + concept is_pair_v = detail::is_pair::value; + + template + concept is_tuple_v = detail::is_tuple::value; + + template + concept is_string_v = requires(T t) { + { static_cast(t) } -> std::convertible_to; + }; + + template + concept is_container_v = !is_array_v && !is_string_v && requires(T a) { + { a.begin() } -> std::input_iterator; + { a.end() } -> std::input_iterator; + }; + + template + concept is_map_v = is_pair_v && is_container_v; + + template + concept is_sequence_v = !is_pair_v && is_container_v; +}; +namespace refl { + namespace detail { + template + struct real_type { + using type = std::remove_cv_t; + }; + template + struct real_type { + using type = std::remove_cv_t*; + }; + template + struct real_type { + using type = std::remove_cv_t*; + }; + //转化为指针类型 + template + struct args_type { + using type = T; + }; + template + struct args_type { + using type = T; + }; + template + struct args_type { + using type = T; + }; + } + template + using real_type_t = detail::real_type::type; + template + using args_type_t = detail::args_type>::type; +}; +namespace refl { + //类型接口 + template + struct TypeInfoImpl; + + template + using TypeInfo = TypeInfoImpl>; +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/uclass.h b/engine/modules/engine/zlib/include/refl/detail/uclass.h new file mode 100644 index 0000000..d7e897b --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/uclass.h @@ -0,0 +1,86 @@ +#pragma once +#include "field.h" +namespace refl { + template + using pmr_vector = std::pmr::vector; + 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(*GetFields)(const UClass*, EFieldFind find, Name name); + //function + span(*GetParams)(const UClass*); + //function + void (*Call)(const FieldPtr*, span ArgsList); + //meta + const UClass* (*GetMeta)(Name); + //object + bool (*Construct)(void* ptr, const UClass* cls, span 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 + bool IsChildOf(bool bthis = false) const { + return IsChildOf(TypeInfo::StaticClass, bthis); + } + public: + template + static void Destruct(void* ptr) { + std::destroy_at((T*)ptr); + } + template + static bool Construct(void* ptr, const UClass* cls, span ArgsList = {}) { + int argsSize = ArgsList.size(); + if (argsSize == 0) { + if constexpr (std::is_constructible_v) { + 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; + } + }; +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/detail/uclass.inl b/engine/modules/engine/zlib/include/refl/detail/uclass.inl new file mode 100644 index 0000000..53bd87c --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/detail/uclass.inl @@ -0,0 +1,44 @@ +#include "uclass.h" +#include "name.h" +namespace refl{ + namespace detail { + inline static pmr::FrameAllocatorPool MemPool{}; + } + template + concept is_metas_v = false;//requires(const Name & name) { MetaImpl::MyMetas::GetMeta(name); }; + template + class UClass_Auto : public UClass { + using UClass::UClass; + using MyUClass = UClass_Auto; + public: + static MyUClass* BuildClass() { + MyUClass* cls = new(detail::MemPool)MyUClass(type_name().View(), sizeof(T)); + if constexpr (std::is_pointer_v) { + using RT = std::remove_pointer_t; + cls->flag |= CLASS_POINTER_FLAG; + if constexpr (!std::is_same_v) { + cls->parent = TypeInfo::StaticClass; + } + } + else if constexpr (is_array_v) { + using RT = is_array_t; + cls->flag = CLASS_ARRAY_FLAG; + if constexpr (std::is_pointer_v) { + cls->flag |= CLASS_POINTER_FLAG; + } + cls->parent = TypeInfo::StaticClass; + } + else { + cls->vtable = new(detail::MemPool)vtable_uclass(); + cls->vtable->Construct = &UClass::Construct; + cls->vtable->Destruct = &UClass::Destruct; + } + return cls; + } + }; + template + struct TypeInfoImpl { + using MyUClass = UClass_Auto; + inline static MyUClass* StaticClass = MyUClass::BuildClass(); + }; +} \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/refl/pch.h b/engine/modules/engine/zlib/include/refl/pch.h new file mode 100644 index 0000000..f2d3617 --- /dev/null +++ b/engine/modules/engine/zlib/include/refl/pch.h @@ -0,0 +1,4 @@ +#pragma once +#include "detail/name.inl" +#include "detail/any.inl" +#include "detail/uclass.inl" \ No newline at end of file diff --git a/engine/modules/engine/zlib/include/singleton.h b/engine/modules/engine/zlib/include/singleton.h new file mode 100644 index 0000000..9fd0069 --- /dev/null +++ b/engine/modules/engine/zlib/include/singleton.h @@ -0,0 +1,15 @@ +template +class Singleton{ +protected: + inline static T* ms_Singleton = nullptr; +public: + explicit Singleton() { + ms_Singleton = static_cast(this); + } + ~Singleton() { + ms_Singleton = nullptr; + } + static constexpr T* Ptr(void) { + return ms_Singleton; + } +}; \ No newline at end of file diff --git a/engine/modules/engine/zlib/xmake.lua b/engine/modules/engine/zlib/xmake.lua new file mode 100644 index 0000000..8306ddd --- /dev/null +++ b/engine/modules/engine/zlib/xmake.lua @@ -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") \ No newline at end of file diff --git a/engine/modules/render/vulkan/include/vulkan/module.h b/engine/modules/render/vulkan/include/vulkan/module.h new file mode 100644 index 0000000..3f97789 --- /dev/null +++ b/engine/modules/render/vulkan/include/vulkan/module.h @@ -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) \ No newline at end of file diff --git a/engine/modules/render/vulkan/src/module.cpp b/engine/modules/render/vulkan/src/module.cpp new file mode 100644 index 0000000..28833ef --- /dev/null +++ b/engine/modules/render/vulkan/src/module.cpp @@ -0,0 +1,15 @@ +#include "module.h" + +void VulkanModule::OnLoad(int argc, char** argv) +{ + +} + +void VulkanModule::OnUnload() +{ +} + +const char* VulkanModule::MetaData(void) +{ + return nullptr; +} diff --git a/engine/modules/render/vulkan/xmake.lua b/engine/modules/render/vulkan/xmake.lua new file mode 100644 index 0000000..b4f74f3 --- /dev/null +++ b/engine/modules/render/vulkan/xmake.lua @@ -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}) \ No newline at end of file diff --git a/engine/modules/xmake.lua b/engine/modules/xmake.lua new file mode 100644 index 0000000..789afc1 --- /dev/null +++ b/engine/modules/xmake.lua @@ -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") \ No newline at end of file diff --git a/engine/tools/make_plugin/src/main.cpp b/engine/tools/make_plugin/src/main.cpp new file mode 100644 index 0000000..f441c51 --- /dev/null +++ b/engine/tools/make_plugin/src/main.cpp @@ -0,0 +1,145 @@ +#include +#include +#include +#include +#include +#include +#include +#include +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 args; + MacroData() :args(&pool) {} + MacroData(const pmr::vector& args):args(args) {} +}; +pmr::vector parseArgs(std::string_view& str) { + pmr::vector args(&pool); + std::stack 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 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{}; +} +// 读取文件并返回每一行内容 +pmr::vector readFile(const char* file_path) { + pmr::vector 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& 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& 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; +} \ No newline at end of file diff --git a/engine/tools/make_plugin/xmake.lua b/engine/tools/make_plugin/xmake.lua new file mode 100644 index 0000000..01d815b --- /dev/null +++ b/engine/tools/make_plugin/xmake.lua @@ -0,0 +1,2 @@ +tool_target("make_plugin") + add_files("src/main.cpp") \ No newline at end of file diff --git a/engine/tools/xmake.lua b/engine/tools/xmake.lua new file mode 100644 index 0000000..45136d6 --- /dev/null +++ b/engine/tools/xmake.lua @@ -0,0 +1,6 @@ +function tool_target(name) + target(name) + set_kind("binary") + set_group("Tools") +end +includes("*/xmake.lua") \ No newline at end of file diff --git a/engine/xmake.lua b/engine/xmake.lua new file mode 100644 index 0000000..a747bef --- /dev/null +++ b/engine/xmake.lua @@ -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") \ No newline at end of file diff --git a/engine/xmake/modules/find_sdk.lua b/engine/xmake/modules/find_sdk.lua new file mode 100644 index 0000000..d944fe6 --- /dev/null +++ b/engine/xmake/modules/find_sdk.lua @@ -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 diff --git a/engine/xmake/rule_plugin/make_plugin.lua b/engine/xmake/rule_plugin/make_plugin.lua new file mode 100644 index 0000000..01a4518 --- /dev/null +++ b/engine/xmake/rule_plugin/make_plugin.lua @@ -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 \ No newline at end of file diff --git a/engine/xmake/rule_plugin/xmake.lua b/engine/xmake/rule_plugin/xmake.lua new file mode 100644 index 0000000..df2523d --- /dev/null +++ b/engine/xmake/rule_plugin/xmake.lua @@ -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) \ No newline at end of file diff --git a/engine/xmake/xmake.lua b/engine/xmake/xmake.lua new file mode 100644 index 0000000..86fa590 --- /dev/null +++ b/engine/xmake/xmake.lua @@ -0,0 +1,2 @@ +includes("*/xmake.lua") +add_moduledirs(path.join(os.projectdir(), "engine/xmake/modules")) \ No newline at end of file diff --git a/game/zworld/editor/main.cpp b/game/zworld/editor/main.cpp new file mode 100644 index 0000000..7f69d63 --- /dev/null +++ b/game/zworld/editor/main.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#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::StaticClass; + //auto str4 = concat(r1, str2); + auto t1 = refl::type_name(); + auto v1 = refl::type_name().View(); + auto v2 = t1.View(); + if (v1 == t1.View()) { + auto t2 = refl::type_name(); + auto t3 = refl::type_name(); + } + auto t2 = refl::type_name(); + auto t3 = refl::type_name(); + 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"; +} \ No newline at end of file diff --git a/game/zworld/src/zworld.cpp b/game/zworld/src/zworld.cpp new file mode 100644 index 0000000..dcc18b9 --- /dev/null +++ b/game/zworld/src/zworld.cpp @@ -0,0 +1,5 @@ +#include "zworld.h" + +void hello() { + +} \ No newline at end of file diff --git a/game/zworld/src/zworld.h b/game/zworld/src/zworld.h new file mode 100644 index 0000000..14e73eb --- /dev/null +++ b/game/zworld/src/zworld.h @@ -0,0 +1 @@ +void hello(); \ No newline at end of file diff --git a/game/zworld/xmake.lua b/game/zworld/xmake.lua new file mode 100644 index 0000000..8bc4a0e --- /dev/null +++ b/game/zworld/xmake.lua @@ -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") \ No newline at end of file diff --git a/xmake.lua b/xmake.lua new file mode 100644 index 0000000..bc9ae31 --- /dev/null +++ b/xmake.lua @@ -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" \ No newline at end of file