完整代码:https://github.com/DXT00/Hazel_study/tree/master/Layer
overlay must after the layer
rendering -->从layer到overlay
event 处理-->从overlay 到 layer
Layer.h
#pragma once
#include"Hazel/Event/Event.h"
namespace Hazel {
class HAZEL_API Layer
{
public:
Layer(const std::string& name = "Layer");
virtual ~Layer();
virtual void OnAttach() {}
virtual void OnDetach() {}
virtual void OnUpdate() {}
virtual void OnEvent(Event& e) {}
inline const std::string &GetString()const { return m_DegugName; }
protected:
std::string m_DegugName;
};
}
Layer.cpp
#include "hzpch.h"
#include "Layer.h"
namespace Hazel {
Layer::Layer(const std::string & name):m_DegugName(name)
{
}
Layer::~Layer()
{
}
}
LayerStack.cpp
#include "hzpch.h"
#include "LayerStack.h"
namespace Hazel {
LayerStack::LayerStack()
{
m_LayerInsert = m_Layers.begin();
}
LayerStack::~LayerStack()
{
for (Layer* layer : m_Layers) {
delete layer;
}
}
void LayerStack::PushLayer(Layer * layer)
{
m_Layers.emplace(m_Layers.begin()+ m_LayerInsertIndex, layer);
m_LayerInsertIndex++;
layer->OnAttach();
}
void LayerStack::PushOverLayer(Layer * overlay)
{
m_Layers.emplace_back( overlay);
overlay->OnAttach();
}
void LayerStack::PopLayer(Layer * layer)
{
auto it = find(m_Layers.begin(), m_Layers.begin() + m_LayerInsertIndex, layer);
if (it != m_Layers.end()) {
layer->OnDetach();
m_Layers.erase(it);
m_LayerInsertIndex--;
}
}
void LayerStack::PopOverLayer(Layer * overlay)
{
auto it = find(m_Layers.begin() + m_LayerInsertIndex, m_Layers.end(), overlay);
if (it != m_Layers.end()) {
overlay->OnDetach();
m_Layers.erase(it);
}
}
}
LayerStack.h
#pragma once
#include<vector>
#include "Hazel/Core.h"
#include "Layer.h"
namespace Hazel {
class HAZEL_API LayerStack
{
public:
LayerStack();
~LayerStack();
void PushLayer(Layer *layer);
void PushOverLayer(Layer *layer);
void PopLayer(Layer *layer);
void PopOverLayer(Layer *layer);
std::vector<Layer*>::iterator begin() { return m_Layers.begin(); }
std::vector<Layer*>::iterator end() { return m_Layers.end(); }
private:
std::vector<Layer*> m_Layers;
std::vector<Layer*>::iterator m_LayerInsert;
int m_LayerInsertIndex = 0;
};
}
Application.cpp
#include "hzpch.h"
#include "Application.h"
#include "GLFW/glfw3.h"
namespace Hazel {
#define BIND_EVENT_FN(x) std::bind(&Application::x, this, std::placeholders::_1)
Application::Application()
{
m_Window = std::unique_ptr<Window>(Window::Create());
m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent));
//std::placeholders::_1 占位符-->表示OnEvent(e)的第一个参数,也就是e
// m_Data.EventCallback = std::bind(&Application::OnEvent, this, std::placeholders::_1)
//data.EventCallback(event);
//相当于--》Application::OnEvent(event)
}
Application::~Application()
{
}
void Application::PushLayer(Layer* layer)
{
m_LayerStack.PushLayer(layer);
}
void Application::PushOverlay(Layer* overlay)
{
m_LayerStack.PushOverLayer(overlay);
}
void Application::OnEvent(Event& e)
{
EventDispatcher dispatcher(e);
dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(OnWindowClose));
HZ_CORE_INFO("{0}", e);
for (auto it = m_LayerStack.end(); it!= m_LayerStack.begin();)
{
(*--it)->OnEvent(e);
if (e.Handled)
break;
}
}
bool Application::OnWindowClose(WindowCloseEvent& e)
{
m_Running = false;
return true;
}
void Application:: Run() {
while (m_Running) {
glClearColor(1, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
for (Layer *layer:m_LayerStack)
{
layer->OnUpdate();
}
m_Window->OnUpdate();
}
}
}
可以看到,我们需要从最顶层遍历event,当某一层layer处理了这个event后就截止!不会传到下一层
void Application::OnEvent(Event& e)
{
EventDispatcher dispatcher(e);
dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(OnWindowClose));
HZ_CORE_INFO("{0}", e);
for (auto it = m_LayerStack.end(); it!= m_LayerStack.begin();)
{
(*--it)->OnEvent(e);
if (e.Handled)
break;
}
}
while()循环遍历每一层layer
void Application:: Run() {
while (m_Running) {
glClearColor(1, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
for (Layer *layer:m_LayerStack)
{
layer->OnUpdate();
}
m_Window->OnUpdate();
}
}
需要使用多线程调试DLL,所以要修改premake5.lua 改:staticruntime "Off" --linking the runtime library
转自:https://blog.csdn.net/vip_member888/article/details/73330539
https://blog.csdn.net/qq_33757398/article/details/82156956
一种语言的开发环境往往会附带有语言库,这些库就是对操作系统的API的包装,我们也称这些语言库为运行库
对于MSVC的运行库(CRT),按照静态/动态链接,可以分为静态版和动态版;按照调试/发布,可以分为调试版本和发布版本;按照单线程/多线程,可以分为单线程版本和多线程版本(但是目前VS中已不提供单线程版本了)
在调试模式(Debug)下,使用调试运行库:多线程调试(/MTd)、多线程调试DLL(/MDd)
在发布模式(Release)下,使用发布运行库:多线程(/MT)、多线程DLL(/MD)
调试模式下运行库带d,但发布模式不带。调试与发布的区别在于,发布模式省略了程序的调试信息,简单来说就是删除了调试模式下的用于调试的内容,所以一般情况下,发布模式下生成的可执行文件的大小比调试模式下生成的要小
静态链接:多线程(/MT)、多线程调试(/MTd)
动态链接:多线程DLL(/MD)、多线程调试DLL(/MDd)
动态链接为D,静态链接为T。两者的区别在于,静态链接将程序所依赖的运行库集成到了可执行文件中,可执行文件运行时不再需要运行库;动态链接没有把程序所依赖的运行库集成到可执行文件中,可执行文件运行时需要运行库。由于静态链接将程序所依赖的运行库集成到了可执行文件中,一般情况下,生成的可执行文件的大小大于动态链接生成的
filter "system:windows"
cppdialect "C++17"
staticruntime "Off" --linking the runtime library
systemversion "latest"
完整的premake5.lua
workspace "Hazel"
architecture "x64"
configurations{
"Debug",
"Release",
"Dist"
}
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}" --Debug-Windows-x64
-- include directory relative to root folder (solution directory)
IncludeDir = {}
IncludeDir["GLFW"] = "Hazel/vendor/GLFW/include"
include "Hazel/vendor/GLFW" --include Hazel/vendor/GLFW/premake5.lua
project "Hazel"
location "Hazel"
kind "SharedLib" --dll
language "C++"
targetdir("bin/" .. outputdir .. "/%{prj.name}")
objdir("bin-int/" .. outputdir .. "/%{prj.name}")
pchheader "hzpch.h"
pchsource "Hazel/src/hzpch.cpp"
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp",
}
includedirs
{
"%{prj.name}/vendor/spdlog/include",
"%{prj.name}/src",
"%{IncludeDir.GLFW}"
}
links{
"GLFW",
"opengl32.lib"
}
filter "system:windows"
cppdialect "C++17"
staticruntime "Off" --linking the runtime library
systemversion "latest"
defines
{
"HZ_BUILD_DLL",
"HZ_PLATFORM_WINDOWS",
}
--create a postbuild step to put the .dll where we want to be
postbuildcommands{
("{COPY} %{cfg.buildtarget.relpath} ../bin/" ..outputdir.. "/Sandbox")
}
filter "configurations:Debug" --only apply to Debug configurations
defines "HZ_DEGUG"
--buildoptions "/MDd"
symbols "On"
filter "configurations:Release" --only apply to Debug configurations
defines "HZ_RELEASE"
--buildoptions "/MD"
optimize "On"
filter "configurations:Dist" --only apply to Debug configurations
defines "HZ_DIST"
--buildoptions "/MD"
optimize "On"
project "Sandbox"
location "Sandbox"
kind "ConsoleApp" --.exe
language "C++"
targetdir("bin/" .. outputdir .. "/%{prj.name}")
objdir("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp",
}
includedirs
{
"Hazel/vendor/spdlog/include",
"Hazel/src"
}
links{
"Hazel"
}
filter "system:windows"
cppdialect "C++17"
staticruntime "Off" --linking the runtime library
systemversion "latest"
defines
{
"HZ_PLATFORM_WINDOWS",
}
filter "configurations:Debug" --only apply to Debug configurations
defines "HZ_DEGUG"
--buildoptions "/MDd"
symbols "On"
filter "configurations:Release" --only apply to Debug configurations
defines "HZ_RELEASE"
--buildoptions "/MD"
optimize "On"
filter "configurations:Dist" --only apply to Debug configurations
defines "HZ_DIST"
--buildoptions "/MD"
optimize "On"
重新生成项目:
注意这里的Layer是在客户端设定和调用的!
如layer里的
virtual void OnAttach() {}
virtual void OnDetach() {}
virtual void OnUpdate() {}
virtual void OnEvent(Event& e)
需要在客户端重写--》也即SandBoxApp.cpp
#include<Hazel.h>
class ExampleLayer :public Hazel::Layer{
public:
ExampleLayer()
:Layer("Example"){}
void OnUpdate() override {
HZ_INFO("ExampleLayer::Update");
}
void OnEvent(Hazel::Event& e) override {
HZ_TRACE("{0}",e);
}
}
class SandBox:public Hazel::Application
{
public:
SandBox() {
}
~SandBox() {
}
};
Hazel::Application * Hazel::CreateApplication() {
return new SandBox();
}
F5运行
可以看到Hazel和SandBox都可以处理event了