add event system
This commit is contained in:
parent
0166774b26
commit
38cbff3c55
@ -1,4 +1,6 @@
|
||||
#include "app.h"
|
||||
#include "data/global.h"
|
||||
namespace api {
|
||||
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
|
||||
#include "module/module.h"
|
||||
#include "data/engine_config.h"
|
||||
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>
|
||||
class AppImpl;
|
||||
class App {
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#include "engine_config.h"
|
||||
#include "project_config.h"
|
||||
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 "event/event_system.h"
|
||||
#include "app.h"
|
||||
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 <vector>
|
||||
#include <fstream>
|
||||
|
||||
@ -6,10 +6,12 @@
|
||||
#include "vkn/thread/command_worker.h"
|
||||
#include "vkn/loader/vulkan_glsl_loader.h"
|
||||
#include "render/asset/mesh.h"
|
||||
#include "event/event_system.h"
|
||||
#include "meta/enum.h"
|
||||
#include "tinyimageformat/tinyimageformat_apis.h"
|
||||
#include "zlog.h"
|
||||
namespace vkn {
|
||||
using api::EventSystem;
|
||||
inline bool operator==(const FramebufferKey& k1, const FramebufferKey& k2) {
|
||||
if (k1.pass != k2.pass) return false;
|
||||
if (k1.attachmentCount != k2.attachmentCount) return false;
|
||||
@ -344,6 +346,7 @@ namespace vkn {
|
||||
window.Aquire(ctx);
|
||||
ctx.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
graph.mSurface = ctx.surface;
|
||||
EventSystem::Ptr()->BeginRenderFrame.Invoke();
|
||||
}
|
||||
void VulkanAPI::EndFrame()
|
||||
{
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
#include "engine/api.h"
|
||||
#include "app_impl.inl"
|
||||
#include "os/file_manager.h"
|
||||
#include "xmalloc_new_delete.h"
|
||||
class ENGINE_API EngineModule : public api::IDynamicModule
|
||||
@ -14,6 +13,7 @@ public:
|
||||
};
|
||||
void InitMetaData(void) override {
|
||||
mInfo.dependencies = {
|
||||
{"app","1.0.1", "static"},
|
||||
{"core", "1.0.1", "static" },
|
||||
{"asset", "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 "zworld.h"
|
||||
#include "data/global.h"
|
||||
#include "event/event_system.h"
|
||||
#include "vkn/vulkan_window.h"
|
||||
#include "vkn/vulkan_api.h"
|
||||
#ifdef WITH_EDITOR
|
||||
@ -26,6 +27,9 @@ void ZWorldModule::OnLoad(int argc, char** argv)
|
||||
#ifdef WITH_EDITOR //绑定窗口交互
|
||||
ImGui_ImplSDL2_InitForVulkan(window->GetPtr());
|
||||
#endif
|
||||
EventSystem::Ptr()->BeginRenderFrame.Subscribe("zworld", []() {
|
||||
API->graph.AddRenderPass<DemoPass>();
|
||||
});
|
||||
}
|
||||
void ZWorldModule::Initialize()
|
||||
{
|
||||
@ -46,7 +50,6 @@ void ZWorldModule::MainLoop()
|
||||
}
|
||||
}
|
||||
API->BeginFrame();
|
||||
API->graph.AddRenderPass<DemoPass>();
|
||||
API->Render();
|
||||
API->EndFrame();
|
||||
FramePool()->reset();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user