Haxel Engine learning 8 -- Layer

完整代码: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了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值