support scene serialize
This commit is contained in:
parent
cb1c7ad1e5
commit
3d404294ab
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -4,6 +4,7 @@
|
|||||||
"bitmap.c": "cpp",
|
"bitmap.c": "cpp",
|
||||||
"heap.c": "cpp",
|
"heap.c": "cpp",
|
||||||
"init.c": "cpp",
|
"init.c": "cpp",
|
||||||
"random.c": "cpp"
|
"random.c": "cpp",
|
||||||
|
"type_traits": "cpp"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,13 +1,16 @@
|
|||||||
|

|
||||||
# 个人游戏引擎
|
# 个人游戏引擎
|
||||||
|
|
||||||
|
原始项目: http://175.24.226.114:3000/ouczbs/zengine.git
|
||||||
|
|
||||||
这是一个模块化的 C++ 游戏引擎,旨在帮助学习和实现基本的游戏引擎系统。它包括多个模块,如渲染、资源管理、UI 等,并使用 Vulkan 作为主要的渲染 API。该引擎的结构被拆分为多个静态库和动态链接库(DLL),通过 `xmake` 管理。
|
这是一个模块化的 C++ 游戏引擎,旨在帮助学习和实现基本的游戏引擎系统。它包括多个模块,如渲染、资源管理、UI 等,并使用 Vulkan 作为主要的渲染 API。该引擎的结构被拆分为多个静态库和动态链接库(DLL),通过 `xmake` 管理。
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
- **模块化架构**:将引擎拆分成多个独立模块,提高了可维护性和可扩展性。
|
- **模块化架构**:将引擎拆分成多个独立模块,提高了可维护性和可扩展性。
|
||||||
- **渲染**:使用 Vulkan 实现,且有抽象层支持未来扩展到 OpenGL、DirectX 和 Metal 等其他渲染 API。
|
- **渲染**:使用 Vulkan 实现,且有抽象层支持未来扩展到 OpenGL、DirectX 和 Metal 等其他渲染 API。
|
||||||
- **资源管理**:包括基础的资源管理、加载和序列化功能。
|
- **资源管理**:包括基础的资源管理、加载和序列化功能。
|
||||||
- **UI**:集成了 NoesisGUI 进行 XAML UI 元素的渲染。
|
- **UI**:初步集成了 NoesisGUI 和 ImGui 进行 XAML UI 元素的渲染。
|
||||||
- **全局变量管理**:通过 `engine.dll` 集中管理全局状态,避免模块间不一致。
|
- **接口导出**:通过 `engine.dll` 集中管理全局状态,避免模块间不一致。
|
||||||
- **高效内存管理**:通过 `pmr` 内存资源和模板元编程优化内存分配。
|
- **高效内存管理**:通过 `pmr` 内存资源和模板元编程优化内存分配。
|
||||||
- **编辑器支持**:为编辑器功能提供基本的集成,未来计划使用 ImGui 和 NoesisGUI 开发完整的编辑器工具。
|
- **编辑器支持**:为编辑器功能提供基本的集成,未来计划使用 ImGui 和 NoesisGUI 开发完整的编辑器工具。
|
||||||
|
|
||||||
|
|||||||
BIN
engine/assets/logo.png
Normal file
BIN
engine/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
12
engine/assets/scene/entry.scene
Normal file
12
engine/assets/scene/entry.scene
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
__parent__:
|
||||||
|
mName: entry
|
||||||
|
mLevelBlueprint:
|
||||||
|
__class__: api::LevelBlueprint
|
||||||
|
__data__: ~
|
||||||
|
mLevelInfos:
|
||||||
|
- mName: main
|
||||||
|
mPath: /scene/entry/main.level
|
||||||
|
mOffset:
|
||||||
|
x: 0
|
||||||
|
y: 255
|
||||||
|
z: 0
|
||||||
13
engine/assets/scene/entry/main.level
Normal file
13
engine/assets/scene/entry/main.level
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
__parent__:
|
||||||
|
mName: main
|
||||||
|
mPath: /scene/entry/main.level
|
||||||
|
mOffset:
|
||||||
|
x: 0
|
||||||
|
y: 255
|
||||||
|
z: 0
|
||||||
|
mObjects:
|
||||||
|
- __class__: api::GameObject
|
||||||
|
__data__:
|
||||||
|
mName: ""
|
||||||
|
mChildrens: ~
|
||||||
|
mComponents: ~
|
||||||
12
engine/include/engine/app.h
Normal file
12
engine/include/engine/app.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "data/global.h"
|
||||||
|
namespace api{
|
||||||
|
class ENGINE_API App {
|
||||||
|
public:
|
||||||
|
void* operator new(size_t size) {
|
||||||
|
return ::operator new(size, GlobalPool());
|
||||||
|
}
|
||||||
|
virtual bool Launch();
|
||||||
|
virtual void Update();
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,5 +1,8 @@
|
|||||||
#include "app.h"
|
|
||||||
#include "data/global.h"
|
#include "data/global.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
APP_API EngineConfig gEngineConfig{};
|
APP_API EngineConfig gEngineConfig{};
|
||||||
|
APP_API ProjectConfig gProjectConfig{};
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
APP_API EditorConfig gEditorConfig{};
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
163
engine/modules/engine/app/impl/scene_system_impl.inl
Normal file
163
engine/modules/engine/app/impl/scene_system_impl.inl
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#include "scene/scene_system.h"
|
||||||
|
#include "scene/scene.h"
|
||||||
|
namespace api {
|
||||||
|
class SceneSystemImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Scene* curScene = nullptr;
|
||||||
|
table<Name, Scene*> scenes;
|
||||||
|
table<Name, Name> pathTable;
|
||||||
|
public:
|
||||||
|
void LoadScene(PackagePath path, bool switchNow = true);
|
||||||
|
void SwitchScene(Name name);
|
||||||
|
void DeleteScene(Name name);
|
||||||
|
void DeleteAllScene();
|
||||||
|
void ReloadScene();
|
||||||
|
void Render();
|
||||||
|
void Update();
|
||||||
|
Scene* GetCurScene();
|
||||||
|
Scene* GetScene(Name name);
|
||||||
|
Scene* FindScene(PackagePath path);
|
||||||
|
};
|
||||||
|
Scene* SceneSystemImpl::GetScene(Name name)
|
||||||
|
{
|
||||||
|
auto iter = scenes.find(name);
|
||||||
|
if (iter != scenes.end())
|
||||||
|
return iter->second;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
Scene* SceneSystemImpl::FindScene(PackagePath path)
|
||||||
|
{
|
||||||
|
Name name = Name::Find(path.path);
|
||||||
|
auto it = pathTable.find(name);
|
||||||
|
if (it != pathTable.end()) {
|
||||||
|
return GetScene(it->second);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
void SceneSystemImpl::LoadScene(PackagePath path, bool switchNow)
|
||||||
|
{
|
||||||
|
Scene* pScene = FindScene(path);
|
||||||
|
if (pScene) {
|
||||||
|
curScene = pScene;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FileHandle handle(path);
|
||||||
|
if (!handle.Open(FILE_OP::READ)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pmr::string text = handle.ReadAll<pmr::string>();
|
||||||
|
pScene = new Scene();
|
||||||
|
if (!TextDeserialize<Scene>(text, pScene)) _UNLIKELY{
|
||||||
|
delete pScene;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
pScene->mPath = path();
|
||||||
|
pathTable.emplace(pScene->mPath, pScene->mName);
|
||||||
|
scenes.emplace(pScene->mName, pScene);
|
||||||
|
curScene = pScene;
|
||||||
|
curScene->OnLoad();
|
||||||
|
}
|
||||||
|
void SceneSystemImpl::SwitchScene(Name name)
|
||||||
|
{
|
||||||
|
auto scene = GetScene(name);
|
||||||
|
if (scene == nullptr) _UNLIKELY
|
||||||
|
{
|
||||||
|
zlog::error("Switch to invalid scene: {}", name.data());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
curScene = scene;
|
||||||
|
}
|
||||||
|
void SceneSystemImpl::DeleteScene(Name name)
|
||||||
|
{
|
||||||
|
auto iter = scenes.find(name);
|
||||||
|
if (iter == scenes.end()) _UNLIKELY
|
||||||
|
{
|
||||||
|
zlog::info("Attempt to delete a nonexistent scene: {}", name.ToStringView());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete iter->second;
|
||||||
|
scenes.erase(iter);
|
||||||
|
}
|
||||||
|
void SceneSystemImpl::DeleteAllScene()
|
||||||
|
{
|
||||||
|
for (auto& iter : scenes)
|
||||||
|
{
|
||||||
|
delete iter.second;
|
||||||
|
}
|
||||||
|
scenes.clear();
|
||||||
|
}
|
||||||
|
void SceneSystemImpl::ReloadScene()
|
||||||
|
{
|
||||||
|
if (!curScene)_UNLIKELY{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Name path = curScene->mPath;
|
||||||
|
DeleteScene(curScene->mName);
|
||||||
|
LoadScene(path, true);
|
||||||
|
}
|
||||||
|
void SceneSystemImpl::Render()
|
||||||
|
{
|
||||||
|
if(curScene) _LIKELY
|
||||||
|
curScene->Render();
|
||||||
|
}
|
||||||
|
void SceneSystemImpl::Update()
|
||||||
|
{
|
||||||
|
if(curScene) _LIKELY
|
||||||
|
curScene->Update();
|
||||||
|
}
|
||||||
|
Scene* SceneSystemImpl::GetCurScene()
|
||||||
|
{
|
||||||
|
return curScene;
|
||||||
|
}
|
||||||
|
SINGLETON_DEFINE(SceneSystem)
|
||||||
|
SceneSystem::SceneSystem()
|
||||||
|
{
|
||||||
|
SINGLETON_PTR();
|
||||||
|
impl = new (GlobalPool())SceneSystemImpl();
|
||||||
|
}
|
||||||
|
void SceneSystem::Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void SceneSystem::Finalize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void SceneSystem::LoadScene(PackagePath path, bool switchNow)
|
||||||
|
{
|
||||||
|
impl->LoadScene(path, switchNow);
|
||||||
|
}
|
||||||
|
void SceneSystem::SwitchScene(Name name)
|
||||||
|
{
|
||||||
|
impl->SwitchScene(name);
|
||||||
|
}
|
||||||
|
void SceneSystem::DeleteScene(Name name)
|
||||||
|
{
|
||||||
|
impl->DeleteScene(name);
|
||||||
|
}
|
||||||
|
void SceneSystem::DeleteAllScene()
|
||||||
|
{
|
||||||
|
impl->DeleteAllScene();
|
||||||
|
}
|
||||||
|
void SceneSystem::ReloadScene()
|
||||||
|
{
|
||||||
|
impl->ReloadScene();
|
||||||
|
}
|
||||||
|
void SceneSystem::Render()
|
||||||
|
{
|
||||||
|
impl->Render();
|
||||||
|
}
|
||||||
|
void SceneSystem::Update()
|
||||||
|
{
|
||||||
|
impl->Update();
|
||||||
|
}
|
||||||
|
Scene* SceneSystem::GetCurScene()
|
||||||
|
{
|
||||||
|
return impl->GetCurScene();
|
||||||
|
}
|
||||||
|
Scene* SceneSystem::GetScene(Name name)
|
||||||
|
{
|
||||||
|
return impl->GetScene(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,25 +0,0 @@
|
|||||||
namespace api {
|
|
||||||
template<typename T>
|
|
||||||
class AppImpl {
|
|
||||||
void Setup() {
|
|
||||||
static_cast<T*>(this)->Setup();
|
|
||||||
}
|
|
||||||
void CleanUp() {
|
|
||||||
static_cast<T*>(this)->CleanUp();
|
|
||||||
}
|
|
||||||
void ImGui() {
|
|
||||||
static_cast<T*>(this)->ImGui();
|
|
||||||
}
|
|
||||||
void PreRender() {
|
|
||||||
static_cast<T*>(this)->PreRender();
|
|
||||||
}
|
|
||||||
void PostRender() {
|
|
||||||
static_cast<T*>(this)->PostRender();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
template<typename T>
|
|
||||||
inline void App::Run(EngineConfig config, AppImpl<T>& impl)
|
|
||||||
{
|
|
||||||
impl.Setup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "module/module.h"
|
#include "module/module.h"
|
||||||
#include "data/engine_config.h"
|
|
||||||
namespace api{
|
namespace api{
|
||||||
class APP_API AppModule : public IStaticModule
|
class APP_API AppModule : public IStaticModule
|
||||||
{
|
{
|
||||||
@ -9,12 +8,4 @@ namespace api{
|
|||||||
void OnUnload() override;
|
void OnUnload() override;
|
||||||
void InitMetaData(void) override {};
|
void InitMetaData(void) override {};
|
||||||
};
|
};
|
||||||
template<typename T>
|
|
||||||
class AppImpl;
|
|
||||||
class App {
|
|
||||||
public:
|
|
||||||
template<typename T>
|
|
||||||
void Run(EngineConfig config, AppImpl<T>& impl);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
#include "app.inl"
|
|
||||||
9
engine/modules/engine/app/include/data/editor_config.h
Normal file
9
engine/modules/engine/app/include/data/editor_config.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "render/type.h"
|
||||||
|
namespace api{
|
||||||
|
struct EditorConfig {
|
||||||
|
bool IsRenderEditorSurface = false;
|
||||||
|
bool IsGameStart = false;
|
||||||
|
bool isGamePause = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -3,9 +3,5 @@
|
|||||||
namespace api{
|
namespace api{
|
||||||
struct EngineConfig {
|
struct EngineConfig {
|
||||||
GraphicsAPI API = GraphicsAPI::Vulkan;
|
GraphicsAPI API = GraphicsAPI::Vulkan;
|
||||||
#ifdef WITH_EDITOR
|
|
||||||
bool IsRenderEditorSurface = false;
|
|
||||||
#endif // WITH_EDITOR
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -8,4 +8,11 @@ namespace api {
|
|||||||
constexpr const char* CFileMountName = "/work/assets/file_mount.meta";
|
constexpr const char* CFileMountName = "/work/assets/file_mount.meta";
|
||||||
|
|
||||||
extern APP_API EngineConfig gEngineConfig;
|
extern APP_API EngineConfig gEngineConfig;
|
||||||
|
extern APP_API ProjectConfig gProjectConfig;
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
#include "editor_config.h"
|
||||||
|
namespace api{
|
||||||
|
extern APP_API EditorConfig gEditorConfig;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "pmr/name.h"
|
||||||
namespace api{
|
namespace api{
|
||||||
|
using pmr::Name;
|
||||||
struct ProjectConfig {
|
struct ProjectConfig {
|
||||||
|
Name EntryScene;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "object/game_object.h"
|
||||||
|
namespace api {
|
||||||
|
class Transform : public Component {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
31
engine/modules/engine/app/include/object/game_object.h
Normal file
31
engine/modules/engine/app/include/object/game_object.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "archive/reflect.h"
|
||||||
|
namespace api {
|
||||||
|
using pmr::Name;
|
||||||
|
using refl::TAny;
|
||||||
|
using std::vector;
|
||||||
|
class Component;
|
||||||
|
class GameObject {
|
||||||
|
private:
|
||||||
|
GENERATED_BODY()
|
||||||
|
UPROPERTY()
|
||||||
|
Name mName;
|
||||||
|
UPROPERTY()
|
||||||
|
vector<TAny<GameObject>> mChildrens;
|
||||||
|
UPROPERTY()
|
||||||
|
vector<TAny<Component>> mComponents;
|
||||||
|
public:
|
||||||
|
|
||||||
|
};
|
||||||
|
class Component {
|
||||||
|
private:
|
||||||
|
GENERATED_BODY()
|
||||||
|
UPROPERTY()
|
||||||
|
Name mName;
|
||||||
|
GameObject* mOwner;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#include ".app/game_object_gen.inl"
|
||||||
26
engine/modules/engine/app/include/scene/level.h
Normal file
26
engine/modules/engine/app/include/scene/level.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "object/game_object.h"
|
||||||
|
#include "math/vector3.h"
|
||||||
|
namespace api {
|
||||||
|
using refl::TAny;
|
||||||
|
struct LevelInfo {
|
||||||
|
UPROPERTY()
|
||||||
|
Name mName;
|
||||||
|
UPROPERTY()
|
||||||
|
Name mPath;
|
||||||
|
UPROPERTY()
|
||||||
|
Vector3 mOffset;
|
||||||
|
};
|
||||||
|
class Level : public LevelInfo{
|
||||||
|
protected:
|
||||||
|
GENERATED_BODY()
|
||||||
|
UPROPERTY()
|
||||||
|
vector<TAny<GameObject>> mObjects;
|
||||||
|
public:
|
||||||
|
Level(const LevelInfo& info) : LevelInfo(info) {};
|
||||||
|
Level();
|
||||||
|
~Level();
|
||||||
|
void AddObject(TAny<GameObject> object);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#include ".app/level_gen.inl"
|
||||||
11
engine/modules/engine/app/include/scene/level_blueprint.h
Normal file
11
engine/modules/engine/app/include/scene/level_blueprint.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "object/game_object.h"
|
||||||
|
namespace api {
|
||||||
|
class Scene;
|
||||||
|
class LevelBlueprint {
|
||||||
|
public:
|
||||||
|
LevelBlueprint();
|
||||||
|
~LevelBlueprint();
|
||||||
|
void LoadScene(Scene* scene);
|
||||||
|
};
|
||||||
|
}
|
||||||
31
engine/modules/engine/app/include/scene/scene.h
Normal file
31
engine/modules/engine/app/include/scene/scene.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "level.h"
|
||||||
|
namespace api {
|
||||||
|
class LevelBlueprint;
|
||||||
|
struct SceneInfo {
|
||||||
|
UPROPERTY()
|
||||||
|
Name mName;
|
||||||
|
Name mPath;
|
||||||
|
UPROPERTY()
|
||||||
|
TAny<LevelBlueprint> mLevelBlueprint;
|
||||||
|
UPROPERTY()
|
||||||
|
vector<LevelInfo> mLevelInfos;
|
||||||
|
};
|
||||||
|
class Scene : public SceneInfo{
|
||||||
|
protected:
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
vector<Level*> mLevels;
|
||||||
|
vector<GameObject*> mObjects;
|
||||||
|
public:
|
||||||
|
Scene(const SceneInfo& info) : SceneInfo(info) {};
|
||||||
|
Scene();
|
||||||
|
~Scene();
|
||||||
|
void OnLoad();
|
||||||
|
void Update();
|
||||||
|
void Render();
|
||||||
|
void AddLevel(Level* level);
|
||||||
|
void AddGameObject(GameObject* object);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#include ".app/scene_gen.inl"
|
||||||
25
engine/modules/engine/app/include/scene/scene_system.h
Normal file
25
engine/modules/engine/app/include/scene/scene_system.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "module/module.h"
|
||||||
|
namespace api {
|
||||||
|
class Scene;
|
||||||
|
class SceneSystemImpl;
|
||||||
|
class APP_API SceneSystem : public ISystem {
|
||||||
|
SINGLETON_IMPL(SceneSystem)
|
||||||
|
private:
|
||||||
|
SceneSystemImpl* impl;
|
||||||
|
public:
|
||||||
|
SceneSystem();
|
||||||
|
void Initialize() override;
|
||||||
|
void Finalize() override;
|
||||||
|
public:
|
||||||
|
void LoadScene(PackagePath path, bool switchNow = true);
|
||||||
|
void SwitchScene(Name name);
|
||||||
|
void DeleteScene(Name name);
|
||||||
|
void DeleteAllScene();
|
||||||
|
void ReloadScene();
|
||||||
|
void Render();
|
||||||
|
void Update();
|
||||||
|
Scene* GetCurScene();
|
||||||
|
Scene* GetScene(Name name);
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,10 +1,11 @@
|
|||||||
#include "data/engine_config.h"
|
|
||||||
#include "event/event_system.h"
|
#include "event/event_system.h"
|
||||||
#include "app.h"
|
#include "scene/scene_system.h"
|
||||||
|
#include "app_module.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
void AppModule::OnLoad(int argc, char** argv)
|
void AppModule::OnLoad(int argc, char** argv)
|
||||||
{
|
{
|
||||||
AddSystem<EventSystem>();
|
AddSystem<EventSystem>();
|
||||||
|
AddSystem<SceneSystem>();
|
||||||
}
|
}
|
||||||
void AppModule::OnUnload()
|
void AppModule::OnUnload()
|
||||||
{
|
{
|
||||||
16
engine/modules/engine/app/src/scene/level.cpp
Normal file
16
engine/modules/engine/app/src/scene/level.cpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include "scene/level.h"
|
||||||
|
|
||||||
|
namespace api {
|
||||||
|
Level::Level()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
Level::~Level()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void Level::AddObject(TAny<GameObject> object)
|
||||||
|
{
|
||||||
|
mObjects.push_back(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
28
engine/modules/engine/app/src/scene/level_blueprint.cpp
Normal file
28
engine/modules/engine/app/src/scene/level_blueprint.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "scene/level_blueprint.h"
|
||||||
|
#include "scene/scene.h"
|
||||||
|
#include "os/file_handle.h"
|
||||||
|
#include "archive/pch.h"
|
||||||
|
namespace api {
|
||||||
|
LevelBlueprint::LevelBlueprint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
LevelBlueprint::~LevelBlueprint()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void LevelBlueprint::LoadScene(Scene* scene)
|
||||||
|
{
|
||||||
|
for (auto& levelInfo : scene->mLevelInfos) {
|
||||||
|
FileHandle handle(levelInfo.mPath);
|
||||||
|
if (!handle.Open(FILE_OP::READ)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Level* pLevel = new Level(levelInfo);
|
||||||
|
pmr::string text = handle.ReadAll<pmr::string>();
|
||||||
|
if (!TextDeserialize<Level>(text, pLevel)) {
|
||||||
|
delete pLevel;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
scene->AddLevel(pLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
engine/modules/engine/app/src/scene/scene.cpp
Normal file
31
engine/modules/engine/app/src/scene/scene.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "scene/scene.h"
|
||||||
|
#include "scene/level_blueprint.h"
|
||||||
|
namespace api {
|
||||||
|
Scene::Scene()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
Scene::~Scene()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Scene::OnLoad()
|
||||||
|
{
|
||||||
|
if (mLevelBlueprint) {
|
||||||
|
mLevelBlueprint->LoadScene(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Scene::Update()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Scene::Render()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void Scene::AddLevel(Level* level)
|
||||||
|
{
|
||||||
|
mLevels.push_back(level);
|
||||||
|
}
|
||||||
|
void Scene::AddGameObject(GameObject* object)
|
||||||
|
{
|
||||||
|
mObjects.push_back(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,4 +1,7 @@
|
|||||||
static_component("app","engine")
|
static_component("app","engine")
|
||||||
add_headerfiles("include/**.h", "include/**.inl")
|
add_rules("c++.codegen",{
|
||||||
|
files = {"include/object/**.h", "include/scene/*.h"}
|
||||||
|
})
|
||||||
|
add_headerfiles("include/**.h")
|
||||||
add_files("src/**.cpp")
|
add_files("src/**.cpp")
|
||||||
add_deps("core", "asset", "zlib", "render")
|
add_deps("core", "asset", "zlib", "render")
|
||||||
@ -7,15 +7,15 @@
|
|||||||
#define JSON_WRITE_FLAGS YYJSON_WRITE_NOFLAG
|
#define JSON_WRITE_FLAGS YYJSON_WRITE_NOFLAG
|
||||||
#endif
|
#endif
|
||||||
namespace gen {
|
namespace gen {
|
||||||
template<>
|
template<is_any_v T>
|
||||||
inline bool JsonRead<refl::Any>(yyjson_val* node, const refl::Any& t) {
|
struct JsonSerde<T> {
|
||||||
if (!node) return false;
|
inline static bool Read(yyjson_val* val, const void* ptr) {
|
||||||
return api::JsonArchive::Deserialize(node, t);
|
return api::JsonArchive::Deserialize(val, refl::Any{ ptr, refl::meta_info<refl::Any>() });
|
||||||
}
|
}
|
||||||
template<>
|
inline static yyjson_mut_val* Write(yyjson_mut_doc* doc, const void* ptr) {
|
||||||
inline yyjson_mut_val* JsonWrite<refl::Any>(yyjson_mut_doc* doc, const refl::Any& t) {
|
return api::JsonArchive::Serialize(doc, refl::Any{ ptr, refl::meta_info<refl::Any>() });
|
||||||
return api::JsonArchive::Serialize(doc, t);
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
namespace api {
|
namespace api {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|||||||
@ -37,8 +37,8 @@ namespace gen {
|
|||||||
for (size_t i = 0; i < length; ++i) {
|
for (size_t i = 0; i < length; ++i) {
|
||||||
yyjson_val* obj_i = yyjson_arr_get(val, i);
|
yyjson_val* obj_i = yyjson_arr_get(val, i);
|
||||||
if constexpr (refl::is_map_v<T>) {
|
if constexpr (refl::is_map_v<T>) {
|
||||||
JsonRead(yyjson_obj_get(obj_i, "#k"), it.first);
|
JsonRead(yyjson_obj_get(obj_i, MAP_KEY_NAME), it.first);
|
||||||
JsonRead(yyjson_obj_get(obj_i, "#v"), it.second);
|
JsonRead(yyjson_obj_get(obj_i, MAP_VALUE_NAME), it.second);
|
||||||
docker[it.first] = it.second;
|
docker[it.first] = it.second;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -54,8 +54,8 @@ namespace gen {
|
|||||||
if constexpr (refl::is_map_v<T>) {
|
if constexpr (refl::is_map_v<T>) {
|
||||||
for (auto& it : docker) {
|
for (auto& it : docker) {
|
||||||
yyjson_mut_val* obj = yyjson_mut_obj(doc);
|
yyjson_mut_val* obj = yyjson_mut_obj(doc);
|
||||||
yyjson_mut_obj_add_val(doc, obj, "#k", JsonWrite(doc, it.first));
|
yyjson_mut_obj_add_val(doc, obj, MAP_KEY_NAME, JsonWrite(doc, it.first));
|
||||||
yyjson_mut_obj_add_val(doc, obj, "#v", JsonWrite(doc, it.second));
|
yyjson_mut_obj_add_val(doc, obj, MAP_VALUE_NAME, JsonWrite(doc, it.second));
|
||||||
yyjson_mut_arr_add_val(arr, obj);
|
yyjson_mut_arr_add_val(arr, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,7 +66,7 @@ namespace api {
|
|||||||
}
|
}
|
||||||
yyjson_mut_val* obj = yyjson_mut_obj(doc);
|
yyjson_mut_val* obj = yyjson_mut_obj(doc);
|
||||||
if (auto p = any.Parent()) {
|
if (auto p = any.Parent()) {
|
||||||
yyjson_mut_obj_add_val(doc, obj, "__parent__", Serialize(doc, p));
|
yyjson_mut_obj_add_val(doc, obj, PARENT_KEY_NAME, Serialize(doc, p));
|
||||||
}
|
}
|
||||||
auto fieldList = any.cls->GetFields(refl::FIND_ALL_MEMBER, pmr::Name(""));
|
auto fieldList = any.cls->GetFields(refl::FIND_ALL_MEMBER, pmr::Name(""));
|
||||||
for (auto& field : fieldList) {
|
for (auto& field : fieldList) {
|
||||||
|
|||||||
77
engine/modules/engine/core/include/archive/reflect.h
Normal file
77
engine/modules/engine/core/include/archive/reflect.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "refl/pch.h"
|
||||||
|
#include "math/vector2.h"
|
||||||
|
#include "math/vector3.h"
|
||||||
|
#include "math/vector4.h"
|
||||||
|
namespace refl {
|
||||||
|
template<> struct Meta<api::Vector2> {
|
||||||
|
using T = api::Vector2;
|
||||||
|
using Impl = gen::MetaImpl<T, string_hash("Meta")>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
namespace refl {
|
||||||
|
template<> struct Meta<api::Vector3> {
|
||||||
|
using T = api::Vector3;
|
||||||
|
using Impl = gen::MetaImpl<T, string_hash("Meta")>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
namespace refl {
|
||||||
|
template<> struct Meta<api::Vector4> {
|
||||||
|
using T = api::Vector4;
|
||||||
|
using Impl = gen::MetaImpl<T, string_hash("Meta")>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
namespace gen {
|
||||||
|
template<> struct MetaImpl<api::Vector2, string_hash("Meta")> : public refl::MetaHelp {
|
||||||
|
using T = api::Vector2;
|
||||||
|
consteval static int MemberCount() { return 2; };
|
||||||
|
consteval static int StaticMemberCount() { return 0; };
|
||||||
|
consteval static int CtorCount() { return 0; };
|
||||||
|
consteval static auto Fields() {
|
||||||
|
return std::make_tuple(FProperty(&T::x, "x"), FProperty(&T::y, "y"));
|
||||||
|
}
|
||||||
|
static auto MakeFields() {
|
||||||
|
return std::array{
|
||||||
|
MemberField(&T::x, "x", {}),
|
||||||
|
MemberField(&T::y, "y", {}),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
namespace gen {
|
||||||
|
template<> struct MetaImpl<api::Vector3, string_hash("Meta")> : public refl::MetaHelp {
|
||||||
|
using T = api::Vector3;
|
||||||
|
consteval static int MemberCount() { return 3; };
|
||||||
|
consteval static int StaticMemberCount() { return 0; };
|
||||||
|
consteval static int CtorCount() { return 0; };
|
||||||
|
consteval static auto Fields() {
|
||||||
|
return std::make_tuple(FProperty(&T::x, "x"), FProperty(&T::y, "y"), FProperty(&T::z, "z"));
|
||||||
|
}
|
||||||
|
static auto MakeFields() {
|
||||||
|
return std::array{
|
||||||
|
MemberField(&T::x, "x", {}),
|
||||||
|
MemberField(&T::y, "y", {}),
|
||||||
|
MemberField(&T::z, "z", {}),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
namespace gen {
|
||||||
|
template<> struct MetaImpl<api::Vector4, string_hash("Meta")> : public refl::MetaHelp {
|
||||||
|
using T = api::Vector4;
|
||||||
|
consteval static int MemberCount() { return 4; };
|
||||||
|
consteval static int StaticMemberCount() { return 0; };
|
||||||
|
consteval static int CtorCount() { return 0; };
|
||||||
|
consteval static auto Fields() {
|
||||||
|
return std::make_tuple(FProperty(&T::x, "x"), FProperty(&T::y, "y"), FProperty(&T::z, "z"), FProperty(&T::w, "w"));
|
||||||
|
}
|
||||||
|
static auto MakeFields() {
|
||||||
|
return std::array{
|
||||||
|
MemberField(&T::x, "x", {}),
|
||||||
|
MemberField(&T::y, "y", {}),
|
||||||
|
MemberField(&T::z, "z", {}),
|
||||||
|
MemberField(&T::w, "w", {}),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,6 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "meta/result.h"
|
#include "meta/result.h"
|
||||||
#include "refl/pch.h"
|
#include "refl/pch.h"
|
||||||
|
#define PARENT_KEY_NAME "__parent__"
|
||||||
|
#define CLASS_KEY_NAME "__class__"
|
||||||
|
#define DATA_KEY_NAME "__data__"
|
||||||
|
#define MAP_KEY_NAME "#k"
|
||||||
|
#define MAP_VALUE_NAME "#v"
|
||||||
|
|
||||||
namespace gen {
|
namespace gen {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Meta {};
|
struct Meta {};
|
||||||
@ -15,6 +21,9 @@ namespace gen {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
concept is_serde_v = std::is_same_v<T, bool> || std::is_integral_v<T> || std::is_floating_point_v<T> || is_string_v<T> || std::is_enum_v<T>
|
concept is_serde_v = std::is_same_v<T, bool> || std::is_integral_v<T> || std::is_floating_point_v<T> || is_string_v<T> || std::is_enum_v<T>
|
||||||
|| is_string_view_v<T>;
|
|| is_string_view_v<T>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
concept is_any_v = std::is_base_of_v<refl::Any, T>;
|
||||||
}
|
}
|
||||||
namespace api {
|
namespace api {
|
||||||
using meta::result;
|
using meta::result;
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
#include "yaml/serde.inl"
|
#include "yaml/serde.inl"
|
||||||
#include "yaml/serialize.inl"
|
#include "yaml/serialize.inl"
|
||||||
namespace gen {
|
namespace gen {
|
||||||
template<>
|
template<is_any_v T>
|
||||||
inline bool YamlRead<refl::Any>(const YAML::Node& node, const refl::Any& t) {
|
struct YamlSerde<T> {
|
||||||
if (!node) return false;
|
inline static bool Read(const YAML::Node& node, const void* ptr) {
|
||||||
return api::YamlArchive::Deserialize(node, refl::Any{ &t, refl::meta_info<refl::Any>() });
|
return api::YamlArchive::Deserialize(node, refl::Any{ ptr, refl::meta_info<refl::Any>() });
|
||||||
}
|
}
|
||||||
template<>
|
inline static YAML::Node Write(const void* ptr) {
|
||||||
inline YAML::Node YamlWrite<refl::Any>(const refl::Any& t) {
|
return api::YamlArchive::Serialize(refl::Any{ ptr, refl::meta_info<refl::Any>() });
|
||||||
return api::YamlArchive::Serialize(refl::Any{&t, refl::meta_info<refl::Any>()});
|
}
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
namespace YAML {
|
namespace YAML {
|
||||||
inline Node APILoad(std::string_view text) {
|
inline Node APILoad(std::string_view text) {
|
||||||
|
|||||||
@ -13,6 +13,10 @@ namespace gen {
|
|||||||
struct YamlSerde<T, std::enable_if_t<refl::is_meta_v<T>>> {
|
struct YamlSerde<T, std::enable_if_t<refl::is_meta_v<T>>> {
|
||||||
inline static bool Read(const YAML::Node& node, const void* ptr) {
|
inline static bool Read(const YAML::Node& node, const void* ptr) {
|
||||||
T& v = *(T*)ptr;
|
T& v = *(T*)ptr;
|
||||||
|
if constexpr (refl::has_parent_v<T>) {
|
||||||
|
using P = refl::parent_t<T>;
|
||||||
|
YamlRead<refl::parent_t<T>>(node[PARENT_KEY_NAME], *(P*)ptr);
|
||||||
|
}
|
||||||
for_each_field([&](std::string_view name, auto&& value) {
|
for_each_field([&](std::string_view name, auto&& value) {
|
||||||
YamlRead(node[name], value);
|
YamlRead(node[name], value);
|
||||||
}, v);
|
}, v);
|
||||||
@ -21,6 +25,10 @@ namespace gen {
|
|||||||
inline static YAML::Node Write(const void* ptr) {
|
inline static YAML::Node Write(const void* ptr) {
|
||||||
T& v = *(T*)ptr;
|
T& v = *(T*)ptr;
|
||||||
YAML::Node node;
|
YAML::Node node;
|
||||||
|
if constexpr (refl::has_parent_v<T>) {
|
||||||
|
using P = refl::parent_t<T>;
|
||||||
|
node[PARENT_KEY_NAME] = YamlWrite<P>(*(P*)ptr);
|
||||||
|
}
|
||||||
for_each_field([&](std::string_view name, auto&& value) {
|
for_each_field([&](std::string_view name, auto&& value) {
|
||||||
node[name] = YamlWrite(value);
|
node[name] = YamlWrite(value);
|
||||||
}, v);
|
}, v);
|
||||||
@ -35,8 +43,8 @@ namespace gen {
|
|||||||
value_type_t it;//构造失败怎么办?
|
value_type_t it;//构造失败怎么办?
|
||||||
for (auto node_i : node) {
|
for (auto node_i : node) {
|
||||||
if constexpr (refl::is_map_v<T>) {
|
if constexpr (refl::is_map_v<T>) {
|
||||||
YamlRead(node_i["#k"], it.first);
|
YamlRead(node_i[MAP_KEY_NAME], it.first);
|
||||||
YamlRead(node_i["#v"], it.second);
|
YamlRead(node_i[MAP_VALUE_NAME], it.second);
|
||||||
docker[it.first] = it.second;
|
docker[it.first] = it.second;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -52,8 +60,8 @@ namespace gen {
|
|||||||
if constexpr (refl::is_map_v<T>) {
|
if constexpr (refl::is_map_v<T>) {
|
||||||
for (auto& it : docker) {
|
for (auto& it : docker) {
|
||||||
YAML::Node node_i;
|
YAML::Node node_i;
|
||||||
node_i["#k"] = YamlWrite(it.first);
|
node_i[MAP_KEY_NAME] = YamlWrite(it.first);
|
||||||
node_i["#v"] = YamlWrite(it.second);
|
node_i[MAP_VALUE_NAME] = YamlWrite(it.second);
|
||||||
node.push_back(node_i);
|
node.push_back(node_i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,11 +36,11 @@ namespace api {
|
|||||||
return Serialize(any.Parent());
|
return Serialize(any.Parent());
|
||||||
}
|
}
|
||||||
YAML::Node result;
|
YAML::Node result;
|
||||||
if (any.cls == meta_info<Any>()) {
|
if (any.Check(meta_info<Any>())) {
|
||||||
Any obj = any.CastTo<Any>();
|
Any obj = any.CastTo<Any>();
|
||||||
if (obj) {
|
if (obj) {
|
||||||
result["__class__"] = obj.cls->name.ToStringView();
|
result[CLASS_KEY_NAME] = obj.cls->name.ToStringView();
|
||||||
result["__data__"] = Serialize(obj);
|
result[DATA_KEY_NAME] = Serialize(obj);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ namespace api {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (Any p = any.Parent()) {
|
if (Any p = any.Parent()) {
|
||||||
result["__parent__"] = Serialize(p);
|
result[PARENT_KEY_NAME] = Serialize(p);
|
||||||
}
|
}
|
||||||
auto fieldList = any.cls->GetFields(refl::FIND_ALL_MEMBER, Name(""));
|
auto fieldList = any.cls->GetFields(refl::FIND_ALL_MEMBER, Name(""));
|
||||||
for (auto& field : fieldList) {
|
for (auto& field : fieldList) {
|
||||||
@ -89,8 +89,8 @@ namespace api {
|
|||||||
if (any.IsEnum()) {
|
if (any.IsEnum()) {
|
||||||
return Deserialize(res, any.Parent());
|
return Deserialize(res, any.Parent());
|
||||||
}
|
}
|
||||||
if (any.cls == meta_info<Any>() && res) {
|
if (any.Check(meta_info<Any>()) && res) {
|
||||||
auto __class = res["__class__"];
|
auto __class = res[CLASS_KEY_NAME];
|
||||||
if (!__class) {
|
if (!__class) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -99,7 +99,7 @@ namespace api {
|
|||||||
if (cls) {
|
if (cls) {
|
||||||
Any obj = cls->New(FramePool());
|
Any obj = cls->New(FramePool());
|
||||||
*any.CastTo<Any*>() = obj;
|
*any.CastTo<Any*>() = obj;
|
||||||
return Deserialize(res["__data__"], obj);
|
return Deserialize(res[DATA_KEY_NAME], obj);
|
||||||
}
|
}
|
||||||
*any.CastTo<Any*>() = {};
|
*any.CastTo<Any*>() = {};
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -2,4 +2,5 @@
|
|||||||
namespace fs {
|
namespace fs {
|
||||||
std::string GetExecutablePath();
|
std::string GetExecutablePath();
|
||||||
std::string GetWorkPath();
|
std::string GetWorkPath();
|
||||||
|
void EnsurePathExists(std::string_view path);
|
||||||
}
|
}
|
||||||
@ -1,10 +1,14 @@
|
|||||||
#include "module/module_manager.h"
|
#include "module/module_manager.h"
|
||||||
#include "os/file_manager.h"
|
#include "os/file_manager.h"
|
||||||
#include "archive/pch.h"
|
#include "archive/pch.h"
|
||||||
|
#include "archive/reflect.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
void CoreModule::OnLoad(int argc, char** argv)
|
void CoreModule::OnLoad(int argc, char** argv)
|
||||||
{
|
{
|
||||||
TextArchive::InitSerde();
|
TextArchive::InitSerde();
|
||||||
|
TextArchive::Register<Vector2>();
|
||||||
|
TextArchive::Register<Vector3>();
|
||||||
|
TextArchive::Register<Vector4>();
|
||||||
}
|
}
|
||||||
void CoreModule::OnUnload()
|
void CoreModule::OnUnload()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include "os/file_handle.h"
|
#include "os/file_handle.h"
|
||||||
|
#include "os/file_system.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#define READ_DATA_SIZE 100
|
#define READ_DATA_SIZE 100
|
||||||
#define TOKEN_SIZE 100
|
#define TOKEN_SIZE 100
|
||||||
@ -24,6 +25,7 @@ namespace api {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case api::FILE_OP::WRITE:
|
case api::FILE_OP::WRITE:
|
||||||
|
fs::EnsurePathExists(file_path);
|
||||||
vfile = std::ofstream(file_path.c_str(), is_binarry ? std::ios::binary : 0);
|
vfile = std::ofstream(file_path.c_str(), is_binarry ? std::ios::binary : 0);
|
||||||
break;
|
break;
|
||||||
case api::FILE_OP::APPEND:
|
case api::FILE_OP::APPEND:
|
||||||
|
|||||||
@ -44,4 +44,15 @@ namespace fs {
|
|||||||
return path.string();
|
return path.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EnsurePathExists(std::string_view path)
|
||||||
|
{
|
||||||
|
size_t pos = path.find_last_of("\\/");
|
||||||
|
if (std::string::npos != pos){
|
||||||
|
std::string_view dir = path.substr(0, pos);
|
||||||
|
if (!std::filesystem::exists(dir)) {
|
||||||
|
std::filesystem::create_directories(dir); // 如果目录不存在,则创建它
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -209,6 +209,7 @@ namespace pmr {
|
|||||||
const StringEntry* stringEntry = UNIQUER_VAL(stringEntryMemoryManager).GetStringEntry(StringEntryHandle(flag3_memory29));
|
const StringEntry* stringEntry = UNIQUER_VAL(stringEntryMemoryManager).GetStringEntry(StringEntryHandle(flag3_memory29));
|
||||||
return std::string(stringEntry->GetData(), stringEntry->GetSize());
|
return std::string(stringEntry->GetData(), stringEntry->GetSize());
|
||||||
}
|
}
|
||||||
|
static Name Find(std::string_view view);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Tag {
|
class Tag {
|
||||||
|
|||||||
@ -152,4 +152,23 @@ namespace pmr {
|
|||||||
}
|
}
|
||||||
return slotValue;
|
return slotValue;
|
||||||
}
|
}
|
||||||
|
inline Name Name::Find(std::string_view view) {
|
||||||
|
Name result{};
|
||||||
|
if (!view.empty()) {
|
||||||
|
HashInfo hashInfo(view);
|
||||||
|
auto& stringEntryMemoryManager = UNIQUER_VAL(stringEntryMemoryManager);
|
||||||
|
auto& slotPool = stringEntryMemoryManager.slotPoolArray[hashInfo.GetSlotPoolIndex()];
|
||||||
|
uint32_t slotValue = 0u;
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(slotPool.mutex);
|
||||||
|
Name::Slot& slot = slotPool.FindUnusedOrTargetSlot(hashInfo);
|
||||||
|
if (slot.IsUsed())
|
||||||
|
{
|
||||||
|
result.flag3_memory29 = slot.GetSlotValue();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@ namespace refl {
|
|||||||
constexpr Any() noexcept: ptr(nullptr), cls(nullptr) {}
|
constexpr Any() noexcept: ptr(nullptr), cls(nullptr) {}
|
||||||
constexpr Any(const void* ptr, const UClass* cls) noexcept : ptr(ptr), cls(cls) {}
|
constexpr Any(const void* ptr, const UClass* cls) noexcept : ptr(ptr), cls(cls) {}
|
||||||
template<is_not_any_v T>
|
template<is_not_any_v T>
|
||||||
constexpr Any(T&& v) noexcept : ptr(&v), cls(meta_info<T>()) {}
|
constexpr Any(T&& v) noexcept : ptr(&v), cls(meta_info<std::remove_reference_t<T>>()) {}
|
||||||
template<is_not_any_v T>
|
template<is_not_any_v T>
|
||||||
constexpr Any(T* v) noexcept : ptr(v), cls(meta_info<T>()) {}
|
constexpr Any(T* v) noexcept : ptr(v), cls(meta_info<T>()) {}
|
||||||
template<typename T>//参数 T* => T*
|
template<typename T>//参数 T* => T*
|
||||||
@ -63,4 +63,16 @@ namespace refl {
|
|||||||
Destruct();
|
Destruct();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
template<typename T>
|
||||||
|
class TAny : public Any{
|
||||||
|
public:
|
||||||
|
TAny() : Any(){}
|
||||||
|
TAny(T* t) : Any(t){}
|
||||||
|
T* operator->() {
|
||||||
|
return (T*)ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename T> struct Meta<TAny<T>> {
|
||||||
|
using Parent = Any;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@ namespace refl {
|
|||||||
Any malloc(pmr::memory_resource* alloc)const {
|
Any malloc(pmr::memory_resource* alloc)const {
|
||||||
void* it = alloc->allocate(cls->parent->size);
|
void* it = alloc->allocate(cls->parent->size);
|
||||||
cls->Construct(it);
|
cls->Construct(it);
|
||||||
return Any{ it, cls };
|
return Any{ it, cls->parent };
|
||||||
}
|
}
|
||||||
span<const FieldPtr> GetFields() {
|
span<const FieldPtr> GetFields() {
|
||||||
return cls->parent->GetFields(EFieldFind::FIND_ALL_MEMBER, Name(""));
|
return cls->parent->GetFields(EFieldFind::FIND_ALL_MEMBER, Name(""));
|
||||||
|
|||||||
@ -26,6 +26,10 @@ namespace refl {
|
|||||||
flag = CLASS_ENUM_FLAG;
|
flag = CLASS_ENUM_FLAG;
|
||||||
parent = meta_info<std::underlying_type_t<T>>();
|
parent = meta_info<std::underlying_type_t<T>>();
|
||||||
}
|
}
|
||||||
|
else if constexpr (has_parent_v<T>) {
|
||||||
|
flag |= CLASS_PARENT_FLAG;
|
||||||
|
parent = meta_info<parent_t<T>>();
|
||||||
|
}
|
||||||
vtable.AddConstruct(&UClass::Construct<T>);
|
vtable.AddConstruct(&UClass::Construct<T>);
|
||||||
vtable.AddDestruct(&UClass::Destruct<T>);
|
vtable.AddDestruct(&UClass::Destruct<T>);
|
||||||
}
|
}
|
||||||
@ -170,6 +174,7 @@ namespace refl {
|
|||||||
FieldsType Fields{ MetaImpl::MakeFields() };
|
FieldsType Fields{ MetaImpl::MakeFields() };
|
||||||
UClass_Meta() : UClass(meta_name<T>(), sizeof(T)) {
|
UClass_Meta() : UClass(meta_name<T>(), sizeof(T)) {
|
||||||
if constexpr (has_parent_v<T>) {
|
if constexpr (has_parent_v<T>) {
|
||||||
|
flag |= CLASS_PARENT_FLAG;
|
||||||
parent = meta_info<parent_t<T>>();
|
parent = meta_info<parent_t<T>>();
|
||||||
}
|
}
|
||||||
vtable.AddGetFields(&UClass_Meta::GetFields);
|
vtable.AddGetFields(&UClass_Meta::GetFields);
|
||||||
|
|||||||
@ -16,8 +16,8 @@ namespace vkn {
|
|||||||
void vkn::VulkanUISystem::OnBeginRenderFrame(FrameGraph& graph, uint32_t frame)
|
void vkn::VulkanUISystem::OnBeginRenderFrame(FrameGraph& graph, uint32_t frame)
|
||||||
{
|
{
|
||||||
#ifdef WITH_EDITOR
|
#ifdef WITH_EDITOR
|
||||||
graph.mIsRenderEditorSurface = gEngineConfig.IsRenderEditorSurface;
|
graph.mIsRenderEditorSurface = gEditorConfig.IsRenderEditorSurface;
|
||||||
if (gEngineConfig.IsRenderEditorSurface) {
|
if (gEditorConfig.IsRenderEditorSurface) {
|
||||||
graph.mEditorSurfaceID = graph.mSurfaceID;
|
graph.mEditorSurfaceID = graph.mSurfaceID;
|
||||||
graph.mSurfaceID = graph.GetTextureID(FrameGraph::NameEditorSurface, frame);
|
graph.mSurfaceID = graph.GetTextureID(FrameGraph::NameEditorSurface, frame);
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ namespace vkn {
|
|||||||
.Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output)
|
.Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output)
|
||||||
.Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT)
|
.Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT)
|
||||||
.Write(stencil, ResourceState::DEPTH_ATTACHMENT);
|
.Write(stencil, ResourceState::DEPTH_ATTACHMENT);
|
||||||
if (gEngineConfig.IsRenderEditorSurface) {
|
if (gEditorConfig.IsRenderEditorSurface) {
|
||||||
builder.Read(graph.GetSurface(), ResourceState::READ_ONLY);
|
builder.Read(graph.GetSurface(), ResourceState::READ_ONLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ namespace api {
|
|||||||
ImGui::Begin("MainWindow", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
ImGui::Begin("MainWindow", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||||
ImGui::Text("This is some useful text.");
|
ImGui::Text("This is some useful text.");
|
||||||
ImGui::SliderFloat("float", &my_float, 0.0f, 1.0f);
|
ImGui::SliderFloat("float", &my_float, 0.0f, 1.0f);
|
||||||
if (gEngineConfig.IsRenderEditorSurface) {
|
if (gEditorConfig.IsRenderEditorSurface) {
|
||||||
TextureDesc surface = graph.GetSurface();
|
TextureDesc surface = graph.GetSurface();
|
||||||
if (!TextureIDList[ctx.frame]) {
|
if (!TextureIDList[ctx.frame]) {
|
||||||
TextureIDList[ctx.frame] = ctx->AddTexture(graph, surface, sampler);
|
TextureIDList[ctx.frame] = ctx->AddTexture(graph, surface, sampler);
|
||||||
@ -84,7 +84,7 @@ namespace api {
|
|||||||
ImGui::Image(TextureIDList[ctx.frame], ImVec2(surface.width, surface.height));
|
ImGui::Image(TextureIDList[ctx.frame], ImVec2(surface.width, surface.height));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gEngineConfig.IsRenderEditorSurface = true;
|
gEditorConfig.IsRenderEditorSurface = true;
|
||||||
InitRenderSurface(graph, ctx.frameCount);
|
InitRenderSurface(graph, ctx.frameCount);
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|||||||
54
engine/src/engine/app.cpp
Normal file
54
engine/src/engine/app.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "engine/app.h"
|
||||||
|
#include "scene/scene_system.h"
|
||||||
|
#include "os/file_manager.h"
|
||||||
|
|
||||||
|
#include "scene/scene.h"
|
||||||
|
#include "scene/level_blueprint.h"
|
||||||
|
#include "object/component/transform.h"
|
||||||
|
#include "os/file_handle.h"
|
||||||
|
#include "archive/pch.h"
|
||||||
|
namespace api{
|
||||||
|
void CreateDemoScene() {
|
||||||
|
LevelInfo levelInfo{ "main", "/scene/entry/main.level", Vector3(0, 255, 0) };
|
||||||
|
SceneInfo sceneInfo{};
|
||||||
|
sceneInfo.mName = "entry";
|
||||||
|
sceneInfo.mPath = "/scene/entry.scene";
|
||||||
|
sceneInfo.mLevelBlueprint = TAny<LevelBlueprint>(new LevelBlueprint());
|
||||||
|
sceneInfo.mLevelInfos.push_back(levelInfo);
|
||||||
|
|
||||||
|
Level level{ levelInfo };
|
||||||
|
GameObject* obj1 = new GameObject();
|
||||||
|
level.AddObject(obj1);
|
||||||
|
{
|
||||||
|
FileHandle handle(levelInfo.mPath);
|
||||||
|
handle.Open(FILE_OP::WRITE);
|
||||||
|
handle.Write(TextSerialize(level));
|
||||||
|
}
|
||||||
|
Scene scene{ sceneInfo };
|
||||||
|
scene.AddLevel(&level);
|
||||||
|
{
|
||||||
|
FileHandle handle(sceneInfo.mPath);
|
||||||
|
handle.Open(FILE_OP::WRITE);
|
||||||
|
handle.Write(TextSerialize(scene));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool App::Launch()
|
||||||
|
{
|
||||||
|
PackagePath scenePath{ "/engine/assets/scene" };
|
||||||
|
FileManager::Ptr()->Mount("scene", scenePath.RealPath().c_str());
|
||||||
|
CreateDemoScene();
|
||||||
|
gProjectConfig.EntryScene = "/scene/entry.scene";
|
||||||
|
SceneSystem::Ptr()->LoadScene(gProjectConfig.EntryScene);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void App::Update()
|
||||||
|
{
|
||||||
|
#ifdef WITH_EDITOR
|
||||||
|
gEditorConfig.IsGameStart = true;
|
||||||
|
if(gEditorConfig.IsGameStart && !gEditorConfig.isGamePause)
|
||||||
|
SceneSystem::Ptr()->Update();
|
||||||
|
#else
|
||||||
|
SceneSystem::Ptr()->Update();
|
||||||
|
#endif // WITH_EDITOR
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,8 +29,10 @@ IMPLEMENT_STATIC_MODULE(RENDER_API, api::RenderModule, render);
|
|||||||
|
|
||||||
#ifndef APP_API_VAL
|
#ifndef APP_API_VAL
|
||||||
#define APP_API_VAL 1
|
#define APP_API_VAL 1
|
||||||
|
#include "app_module.h"
|
||||||
#include "app_impl.inl"
|
#include "app_impl.inl"
|
||||||
#include "event_system_impl.inl"
|
#include "event_system_impl.inl"
|
||||||
|
#include "scene_system_impl.inl"
|
||||||
IMPLEMENT_STATIC_MODULE(APP_API, api::AppModule, app)
|
IMPLEMENT_STATIC_MODULE(APP_API, api::AppModule, app)
|
||||||
#endif // !APP_API_VAL
|
#endif // !APP_API_VAL
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,9 @@ function main(target)
|
|||||||
local link = pkg:get("links")
|
local link = pkg:get("links")
|
||||||
local targetdir = target:targetdir()
|
local targetdir = target:targetdir()
|
||||||
link = link[1] or link
|
link = link[1] or link
|
||||||
|
if is_mode("debug") and not os.isdir(targetdir) then
|
||||||
|
os.mkdir(targetdir)
|
||||||
|
end
|
||||||
if link and os.isdir(targetdir) and not os.isfile(path.join(targetdir, link .. ".lib")) then
|
if link and os.isdir(targetdir) and not os.isfile(path.join(targetdir, link .. ".lib")) then
|
||||||
local linkdirs = pkg:get("linkdirs")
|
local linkdirs = pkg:get("linkdirs")
|
||||||
os.trycp(linkdirs.."/*", targetdir)
|
os.trycp(linkdirs.."/*", targetdir)
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
#include "zworld.h"
|
#include "zworld.h"
|
||||||
#include "data/global.h"
|
|
||||||
#include "event/event_system.h"
|
#include "event/event_system.h"
|
||||||
#include "vkn/vulkan_window.h"
|
#include "vkn/vulkan_window.h"
|
||||||
#include "vkn/vulkan_api.h"
|
#include "vkn/vulkan_api.h"
|
||||||
#include "render/pass/demo_pass.h"
|
#include "render/pass/demo_pass.h"
|
||||||
|
#include "engine/app.h"
|
||||||
#ifdef WITH_EDITOR
|
#ifdef WITH_EDITOR
|
||||||
#include "imgui/imgui_impl_sdl2.h"
|
#include "imgui/imgui_impl_sdl2.h"
|
||||||
#endif
|
#endif
|
||||||
@ -48,8 +48,9 @@ void ZWorldModule::OnUnload()
|
|||||||
|
|
||||||
void ZWorldModule::MainLoop()
|
void ZWorldModule::MainLoop()
|
||||||
{
|
{
|
||||||
bool running = true;
|
|
||||||
SDL_Event event_;
|
SDL_Event event_;
|
||||||
|
App app;
|
||||||
|
bool running = app.Launch();
|
||||||
while (running) {
|
while (running) {
|
||||||
// 处理事件
|
// 处理事件
|
||||||
while (SDL_PollEvent(&event_)) {
|
while (SDL_PollEvent(&event_)) {
|
||||||
@ -60,6 +61,7 @@ void ZWorldModule::MainLoop()
|
|||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
app.Update();
|
||||||
API->BeginFrame();
|
API->BeginFrame();
|
||||||
API->Render();
|
API->Render();
|
||||||
API->EndFrame();
|
API->EndFrame();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user