美文网首页
Dragon Engine:层

Dragon Engine:层

作者: Dragon_boy | 来源:发表于2020-07-18 23:38 被阅读0次

    本文同时发布在我的个人博客上: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

    相关文章

      网友评论

          本文标题:Dragon Engine:层

          本文链接:https://www.haomeiwen.com/subject/ispqkktx.html