Dragon Engine:层

2020-07-18  本文已影响0人  Dragon_boy

本文同时发布在我的个人博客上:https://dragon_boy.gitee.io/

层的概念在许多软件中都存在,这里以PS中的为例。在PS中的层代表一个可显示的对象,对层可以执行许多不同的操作,窗口中的图像显示的层之间进行混合的结果。

这里我们借鉴这个概念定义层类:
Layer.h

#include "Dragon/Core/Core.h"
#include "Dragon/Core/Timestep.h"
#include "Dragon/Events/Event.h"

namespace Dragon
{
    class Layer
    {
    public:
        Layer(const std::string& name = "Layer");
        virtual ~Layer() = default;

        virtual void OnAttach() {}
        virtual void OnDetach() {}
        virtual void OnUpdate(Timestep ts) {}
        virtual void OnImGuiRender() {}
        virtual void OnEvent(Event& event){}

        inline const std::string& GetName() const { return m_DebugName; }
    private:
        std::string m_DebugName;
    };
}

该层类上有几个成员方法:绑定和解绑,用于是否显示该层。更新函数用于刷新该层的图像。OnImGuiRender()是该层上可以显示的GUI。接着是事件响应函数。最后是获得该层名的函数。

接着我们定义管理不同层的类,这里使用容器:
LayerStack.h

#include "Dragon/Core/Core.h"
#include "Layer.h"

#include <vector>

namespace Dragon
{
    class LayerStack
    {
    public:
        LayerStack();
        ~LayerStack();

        void PushLayer(Layer* layer);
        void PushOverlay(Layer* overlay);
        void PopLayer(Layer* layer);
        void PopOverlay(Layer* overlay);

        std::vector<Layer*>::iterator begin() { return m_Layers.begin(); }
        std::vector<Layer*>::iterator end() { return m_Layers.end(); }
    private:
        std::vector<Layer*> m_Layers;
        unsigned int m_LayerInsertIndex = 0;
    };
}

这里使用vector容器来存储层,并定义两个头尾迭代器方法。PushLayer和PopLayer方法是传统的入栈出栈方法:

    void LayerStack::PushLayer(Layer* layer)
    {
        m_Layers.emplace(m_Layers.begin() + m_LayerInsertIndex, layer);
        m_LayerInsertIndex++;
        layer->OnAttach();
    }
    void LayerStack::PopLayer(Layer* layer)
    {
        auto it = std::find(m_Layers.begin(), m_Layers.begin() + m_LayerInsertIndex, layer);
        if (it != m_Layers.end() + m_LayerInsertIndex)
        {
            layer->OnDetach();
            m_Layers.erase(it);
            m_LayerInsertIndex--;
        }
    }

PushLayer将层放到头+索引值的指定位置,然后绑定该层。PopLayer通过find()方法找到要弹出的层,然后解绑,擦除层。

PushOverlay和PopOverlay

    void LayerStack::PushOverlay(Layer* overlay)
    {
        m_Layers.emplace_back(overlay);
        overlay->OnAttach();
    }
    void LayerStack::PopOverlay(Layer* overlay)
    {
        auto it = std::find(m_Layers.begin() + m_LayerInsertIndex, m_Layers.end(), overlay);
        if (it != m_Layers.end())
        {
            overlay->OnDetach();
            m_Layers.erase(it);
        }
    }

PushOverlay方法在容器末尾添加一个层,PopOverLay方法在当前层索引和容器末尾间删除一个指定层。

简单来说上面的方法区别是正反加减层。

之后要使用层的时候,就是创建层之后插入LayerStack对象中,然后迭代就行。

下一节介绍窗口实现。

项目github地址(未完成):https://github.com/Dragon-Baby/Dragon

上一篇下一篇

猜你喜欢

热点阅读