add event system
This commit is contained in:
parent
0166774b26
commit
38cbff3c55
@ -1,4 +1,6 @@
|
|||||||
|
#include "app.h"
|
||||||
#include "data/global.h"
|
#include "data/global.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
APP_API EngineConfig gEngineConfig{};
|
APP_API EngineConfig gEngineConfig{};
|
||||||
|
IMPLEMENT_STATIC_MODULE(APP_API, AppModule, app)
|
||||||
}
|
}
|
||||||
17
engine/modules/engine/app/impl/event_system_impl.inl
Normal file
17
engine/modules/engine/app/impl/event_system_impl.inl
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include "event/event_system.h"
|
||||||
|
namespace api {
|
||||||
|
SINGLETON_DEFINE(EventSystem)
|
||||||
|
|
||||||
|
inline EventSystem::EventSystem()
|
||||||
|
{
|
||||||
|
SINGLETON_PTR();
|
||||||
|
}
|
||||||
|
inline void EventSystem::Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
inline void EventSystem::Finalize()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "module/module.h"
|
||||||
#include "data/engine_config.h"
|
#include "data/engine_config.h"
|
||||||
namespace api{
|
namespace api{
|
||||||
|
class APP_API AppModule : public IStaticModule
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void OnLoad(int argc, char** argv) override;
|
||||||
|
void OnUnload() override;
|
||||||
|
void InitMetaData(void) override {};
|
||||||
|
};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class AppImpl;
|
class AppImpl;
|
||||||
class App {
|
class App {
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
#include "engine_config.h"
|
#include "engine_config.h"
|
||||||
#include "project_config.h"
|
#include "project_config.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
|
|||||||
187
engine/modules/engine/app/include/event/event.h
Normal file
187
engine/modules/engine/app/include/event/event.h
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "pmr/name.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <unordered_map>
|
||||||
|
namespace api{
|
||||||
|
using pmr::Name;
|
||||||
|
//* Utility functions to create std::functions without std::placeholder
|
||||||
|
template <class>
|
||||||
|
class Event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Event that can call all of its subscribers
|
||||||
|
*
|
||||||
|
* @tparam R Return type
|
||||||
|
* @tparam Args Function arguments
|
||||||
|
*/
|
||||||
|
template <class R, class... Args>
|
||||||
|
class Event<R(Args...)> {
|
||||||
|
private:
|
||||||
|
using Delegate = std::function<R(Args...)>;
|
||||||
|
using FuncMap = std::unordered_map<Name, Delegate>;
|
||||||
|
std::unordered_map<void*, FuncMap> listeners;
|
||||||
|
//std::unordered_map<const void*, FuncMap> constListeners;
|
||||||
|
template<typename Type>
|
||||||
|
static consteval auto add_const(R(Type::* ptr)(Args...)) {
|
||||||
|
using MethodType = R(Type::*)(Args...)const;
|
||||||
|
return (MethodType)ptr;
|
||||||
|
}
|
||||||
|
template<class Type>
|
||||||
|
static std::function<R(Args...)> EasyBind(R(Type::* func)(Args... args) const, const Type* invoker) {
|
||||||
|
return [=](auto&&... args) {
|
||||||
|
return (invoker->*func)(std::forward<decltype(args)>(args)...);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Event() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Subscribes a member function to the event.
|
||||||
|
*
|
||||||
|
* @tparam Invoker The instance type to call the member function
|
||||||
|
* @tparam Type The type containing the member function
|
||||||
|
* @param id Unique identifier of the subscribing function
|
||||||
|
* @param func The function to call when the event is raised
|
||||||
|
* @param invoker The instance owning the member function
|
||||||
|
*/
|
||||||
|
template <class Invoker, class Type>
|
||||||
|
void Subscribe(const Name& id, R(Type::*func)(Args... args),const Invoker* invoker) {
|
||||||
|
Subscribe<Invoker, Type>(id, add_const(func), invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Subscribes a const member function to the event.
|
||||||
|
*
|
||||||
|
* @tparam Invoker The instance type to call the member function
|
||||||
|
* @tparam Type The type containing the member function
|
||||||
|
* @param id Unique identifier of the subscribing function
|
||||||
|
* @param func The const function to call when the event is raised
|
||||||
|
* @param invoker The instance owning the member function
|
||||||
|
*/
|
||||||
|
template <class Invoker, class Type>
|
||||||
|
void Subscribe(const Name& id, R (Type::*func)(Args... args) const, const Invoker* invoker) {
|
||||||
|
Delegate deleg{ std::move(EasyBind(func, invoker)) };
|
||||||
|
auto found{ listeners.find(invoker) };
|
||||||
|
if (found != listeners.end()) {
|
||||||
|
auto iter{ found->second.find(id) };
|
||||||
|
if (iter != found->second.end()) {
|
||||||
|
iter->second = std::move(deleg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
found->second.emplace(id, std::move(deleg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
listeners.emplace(invoker, FuncMap{ {id, {std::move(deleg)}} });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Subscribes a free function or a std::function reference to the event
|
||||||
|
*
|
||||||
|
* @param id Unique identifier of the subscribing function
|
||||||
|
* @param func The function to call when the event is raised
|
||||||
|
*/
|
||||||
|
void Subscribe(const Name& id,const std::function<R(Args...)>& func) {
|
||||||
|
auto found{listeners.find(nullptr)};
|
||||||
|
|
||||||
|
if (found != listeners.end()) {
|
||||||
|
auto iter{found->second.find(id)};
|
||||||
|
if (iter != found->second.end()) {
|
||||||
|
iter->second = func;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
found->second.emplace(id, func);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
listeners.emplace(nullptr, FuncMap{{id, {func}}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unsubscribes a member function from an event
|
||||||
|
*
|
||||||
|
* @tparam Invoker
|
||||||
|
* @param id Unique identifier of the subscribed function
|
||||||
|
* @param invoker The instance owning the member function
|
||||||
|
*/
|
||||||
|
template <class Invoker>
|
||||||
|
void Unsubscribe(const Name& id,const Invoker* invoker) {
|
||||||
|
auto found {listeners.find(invoker)};
|
||||||
|
|
||||||
|
if (found != listeners.end()) {
|
||||||
|
auto iter {found->second.find(id)};
|
||||||
|
if (iter != found->second.end()) {
|
||||||
|
found->second.erase(iter);
|
||||||
|
}
|
||||||
|
if (found->second.empty()) {
|
||||||
|
listeners.erase(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Unsubscribes a free function/lambda from an event
|
||||||
|
*
|
||||||
|
* @param id Unique identifier of the subscribed function/lambda
|
||||||
|
*/
|
||||||
|
void Unsubscribe(const Name& id) {
|
||||||
|
auto found{listeners.find(nullptr)};
|
||||||
|
|
||||||
|
if (found != listeners.end()) {
|
||||||
|
auto iter{found->second.find(id)};
|
||||||
|
if (iter != found->second.end()) {
|
||||||
|
found->second.erase(iter);
|
||||||
|
}
|
||||||
|
if (found->second.empty()) {
|
||||||
|
listeners.erase(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unsubscribes all functions owned by the invoker const instance from this event
|
||||||
|
*
|
||||||
|
* @param invoker Const instance subscribed to this event
|
||||||
|
*/
|
||||||
|
template <class Invoker>
|
||||||
|
void RemoveListener(const Invoker* invoker) {
|
||||||
|
auto found{ listeners.find(invoker)};
|
||||||
|
if (found != listeners.end()) {
|
||||||
|
listeners.erase(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unsubscribes all free functions/lambdas from this event
|
||||||
|
*/
|
||||||
|
void RemoveFreeFunctions() {
|
||||||
|
auto found{listeners.find(nullptr)};
|
||||||
|
if (found != listeners.end()) {
|
||||||
|
listeners.erase(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check if args should be lvalues or not.
|
||||||
|
/**
|
||||||
|
* @brief Calls all subscribed functions
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
void Invoke(Args... args) {
|
||||||
|
for (auto& listener : listeners) {
|
||||||
|
for (auto& func : listener.second) {
|
||||||
|
func.second(std::forward<decltype(args)>(args)...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calls all subscribed functions (this is equivalent to Invoke())
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
void operator()(Args... args) {
|
||||||
|
Invoke(std::forward<decltype(args)>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
13
engine/modules/engine/app/include/event/event_system.h
Normal file
13
engine/modules/engine/app/include/event/event_system.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "event.h"
|
||||||
|
#include "module/module.h"
|
||||||
|
namespace api {
|
||||||
|
class APP_API EventSystem : public ISystem{
|
||||||
|
SINGLETON_IMPL(EventSystem)
|
||||||
|
public:
|
||||||
|
EventSystem();
|
||||||
|
void Initialize() override;
|
||||||
|
void Finalize() override;
|
||||||
|
Event<void()> BeginRenderFrame;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,4 +1,13 @@
|
|||||||
#include "data/engine_config.h"
|
#include "data/engine_config.h"
|
||||||
|
#include "event/event_system.h"
|
||||||
|
#include "app.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
|
void AppModule::OnLoad(int argc, char** argv)
|
||||||
|
{
|
||||||
|
AddSystem<EventSystem>();
|
||||||
|
}
|
||||||
|
void AppModule::OnUnload()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
#include "package_path.h"
|
#include "package_path.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|||||||
@ -6,10 +6,12 @@
|
|||||||
#include "vkn/thread/command_worker.h"
|
#include "vkn/thread/command_worker.h"
|
||||||
#include "vkn/loader/vulkan_glsl_loader.h"
|
#include "vkn/loader/vulkan_glsl_loader.h"
|
||||||
#include "render/asset/mesh.h"
|
#include "render/asset/mesh.h"
|
||||||
|
#include "event/event_system.h"
|
||||||
#include "meta/enum.h"
|
#include "meta/enum.h"
|
||||||
#include "tinyimageformat/tinyimageformat_apis.h"
|
#include "tinyimageformat/tinyimageformat_apis.h"
|
||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
namespace vkn {
|
namespace vkn {
|
||||||
|
using api::EventSystem;
|
||||||
inline bool operator==(const FramebufferKey& k1, const FramebufferKey& k2) {
|
inline bool operator==(const FramebufferKey& k1, const FramebufferKey& k2) {
|
||||||
if (k1.pass != k2.pass) return false;
|
if (k1.pass != k2.pass) return false;
|
||||||
if (k1.attachmentCount != k2.attachmentCount) return false;
|
if (k1.attachmentCount != k2.attachmentCount) return false;
|
||||||
@ -344,6 +346,7 @@ namespace vkn {
|
|||||||
window.Aquire(ctx);
|
window.Aquire(ctx);
|
||||||
ctx.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
ctx.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
graph.mSurface = ctx.surface;
|
graph.mSurface = ctx.surface;
|
||||||
|
EventSystem::Ptr()->BeginRenderFrame.Invoke();
|
||||||
}
|
}
|
||||||
void VulkanAPI::EndFrame()
|
void VulkanAPI::EndFrame()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
#include "engine/api.h"
|
#include "engine/api.h"
|
||||||
#include "app_impl.inl"
|
|
||||||
#include "os/file_manager.h"
|
#include "os/file_manager.h"
|
||||||
#include "xmalloc_new_delete.h"
|
#include "xmalloc_new_delete.h"
|
||||||
class ENGINE_API EngineModule : public api::IDynamicModule
|
class ENGINE_API EngineModule : public api::IDynamicModule
|
||||||
@ -14,6 +13,7 @@ public:
|
|||||||
};
|
};
|
||||||
void InitMetaData(void) override {
|
void InitMetaData(void) override {
|
||||||
mInfo.dependencies = {
|
mInfo.dependencies = {
|
||||||
|
{"app","1.0.1", "static"},
|
||||||
{"core", "1.0.1", "static" },
|
{"core", "1.0.1", "static" },
|
||||||
{"asset", "1.0.1", "static" },
|
{"asset", "1.0.1", "static" },
|
||||||
{"render", "1.0.1", "static" },
|
{"render", "1.0.1", "static" },
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
#ifndef ASSET_API_VAL
|
|
||||||
#define ASSET_API_VAL 1
|
|
||||||
#include "resource_system_impl.inl"
|
|
||||||
#include "asset_visit_impl.inl"
|
|
||||||
#endif // !ASSET_API_VAL
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
#ifndef CORE_API_VAL
|
|
||||||
#define CORE_API_VAL 1
|
|
||||||
#include "zlog.h"
|
|
||||||
#include "module_manager_impl.inl"
|
|
||||||
#include "file_manager_impl.inl"
|
|
||||||
#endif // !CORE_API_VAL
|
|
||||||
30
engine/src/engine/plugin.cpp
Normal file
30
engine/src/engine/plugin.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef ZLIB_API_VAL
|
||||||
|
#define ZLIB_API_VAL 1
|
||||||
|
#include "pmr/name.h"
|
||||||
|
#include "pmr/frame_allocator.h"
|
||||||
|
#endif // !ZLIB_API_VAL
|
||||||
|
|
||||||
|
#ifndef CORE_API_VAL
|
||||||
|
#define CORE_API_VAL 1
|
||||||
|
#include "zlog.h"
|
||||||
|
#include "module_manager_impl.inl"
|
||||||
|
#include "file_manager_impl.inl"
|
||||||
|
#endif // !CORE_API_VAL
|
||||||
|
|
||||||
|
#ifndef ASSET_API_VAL
|
||||||
|
#define ASSET_API_VAL 1
|
||||||
|
#include "resource_system_impl.inl"
|
||||||
|
#include "asset_visit_impl.inl"
|
||||||
|
#endif // !ASSET_API_VAL
|
||||||
|
|
||||||
|
#ifndef RENDER_API_VAL
|
||||||
|
#define RENDER_API_VAL 1
|
||||||
|
#include "renderapi_impl.inl"
|
||||||
|
#include "window_impl.inl"
|
||||||
|
#endif // !RENDER_API_VAL
|
||||||
|
|
||||||
|
#ifndef APP_API_VAL
|
||||||
|
#define APP_API_VAL 1
|
||||||
|
#include "app_impl.inl"
|
||||||
|
#include "event_system_impl.inl"
|
||||||
|
#endif // !APP_API_VAL
|
||||||
@ -1,5 +0,0 @@
|
|||||||
#ifndef RENDER_API_VAL
|
|
||||||
#define RENDER_API_VAL 1
|
|
||||||
#include "renderapi_impl.inl"
|
|
||||||
#include "window_impl.inl"
|
|
||||||
#endif // !RENDER_API_VAL
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
#ifndef ZLIB_API_VAL
|
|
||||||
#define ZLIB_API_VAL 1
|
|
||||||
#include "pmr/name.h"
|
|
||||||
#include "pmr/frame_allocator.h"
|
|
||||||
#include "refl/detail/uclass.inl"
|
|
||||||
#endif // !ZLIB_API_VAL
|
|
||||||
@ -1,6 +1,7 @@
|
|||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
#include "zworld.h"
|
#include "zworld.h"
|
||||||
#include "data/global.h"
|
#include "data/global.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"
|
||||||
#ifdef WITH_EDITOR
|
#ifdef WITH_EDITOR
|
||||||
@ -26,6 +27,9 @@ void ZWorldModule::OnLoad(int argc, char** argv)
|
|||||||
#ifdef WITH_EDITOR //绑定窗口交互
|
#ifdef WITH_EDITOR //绑定窗口交互
|
||||||
ImGui_ImplSDL2_InitForVulkan(window->GetPtr());
|
ImGui_ImplSDL2_InitForVulkan(window->GetPtr());
|
||||||
#endif
|
#endif
|
||||||
|
EventSystem::Ptr()->BeginRenderFrame.Subscribe("zworld", []() {
|
||||||
|
API->graph.AddRenderPass<DemoPass>();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
void ZWorldModule::Initialize()
|
void ZWorldModule::Initialize()
|
||||||
{
|
{
|
||||||
@ -46,7 +50,6 @@ void ZWorldModule::MainLoop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
API->BeginFrame();
|
API->BeginFrame();
|
||||||
API->graph.AddRenderPass<DemoPass>();
|
|
||||||
API->Render();
|
API->Render();
|
||||||
API->EndFrame();
|
API->EndFrame();
|
||||||
FramePool()->reset();
|
FramePool()->reset();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user